Coming soon: Your brand new Help Center & Community! Get a sneak-peek here

Add/remove fields in company preview

Is it possible to customize what fields are displayed in the company preview? A customer would like to add a UDEF field to easier and quicker get wanted information when a customer contacts them.

RE: Add/remove fields in company preview

It is plugin based.
You will need to write a Preview Plugin.
I suspect Tony has some examples..



Af: Conrad Weyns 4. okt 2018

RE: Add/remove fields in company preview

Thanks for the info! I will have a look at plugins then.

Af: Patrik Larsson 5. okt 2018

RE: Add/remove fields in company preview

HI Patrik

EDIT: As Henning points out below, you can not replace the default fields.

Here is a copy of our default Contact (Company) preview plugin. It has a default priority of int.MaxValue / 2, so if you implement one and give it a lower number, it will append your fields to the top of the preview. If you add higher number (lower priority), it will app the new fields to the lower part of the preview.


String resource strings are what are shown as labels and are documented. These are the labels you see in the code below that appears surrounded by square brackets.

using SuperOffice.CRM.ArchiveLists;
using SuperOffice.CRM.Cache;
using SuperOffice.CRM.Data;
using SuperOffice.CRM.Globalization;
using SuperOffice.CRM.Rows;
using SuperOffice.Data;
using SuperOffice.Data.SQL;

namespace SuperOffice.CRM.Previews
    [PreviewPlugin("SuperOffice:ContactPreview", ContactHint)]
    public class ContactPreviewPlugin : PreviewPluginBase
        public const string ContactHint = "contact_id";

        private static ContactTableInfo _contactTableInfo;
        private static PhoneTableInfo _phoneTableInfo;
        private static AddressTableInfo _addressTableInfo;
        private static AddressTableInfo _postalAddressTableInfo;
        private static URLTableInfo _URLTable;

        #region IPreviewProviderPlugin Members

        protected override PreviewData InnerGetPreview(PreviewData previewData)
            int contactId;
            if (TryGetIntHint(ContactHint, out contactId))
                Select query = S.NewSelect();


                query.JoinRestriction.LeftOuterJoin(_contactTableInfo.ContactId.Equal(_URLTable.ContactId), _URLTable.Rank.Equal(S.Parameter(1)));
                query.JoinRestriction.LeftOuterJoin(_contactTableInfo.ContactId.Equal(_phoneTableInfo.OwnerId), _phoneTableInfo.PtypeIdx.Equal(S.Parameter(PhoneType.ContactPhone)).And(_phoneTableInfo.Rank.Equal(S.Parameter(1))));

                query.Restriction = _contactTableInfo.ContactId.Equal(S.Parameter(contactId));

                using (SoConnection conn = ConnectionFactory.GetConnection())
                    SoCommand cmd = conn.CreateCommand();
                    cmd.SqlCommand = query;
                    using (SoDataReader reader = cmd.ExecuteReader())
                        if (reader.Read())
                            ContactRow contactRow = ContactRow.GetFromReader(reader, _contactTableInfo);
                            PhoneRow phoneRow = PhoneRow.GetFromReader(reader, _phoneTableInfo);
                            AddressRow addressRow = AddressRow.GetFromReader(reader, _addressTableInfo);
                            AddressRow postalAddressRow = AddressRow.GetFromReader(reader, _postalAddressTableInfo);
                            URLRow urlRow = URLRow.GetFromReader(reader, _URLTable);
                            return FormatLargePreview(previewData,contactRow, phoneRow, addressRow,postalAddressRow,urlRow);

            return previewData;


        public static PreviewData FormatLargePreview(PreviewData pd, ContactRow contactRow, PhoneRow phoneRow, AddressRow addressRow, AddressRow postalAddressRow, URLRow urlRow)
            pd.heading = contactRow.Name; //ContactNameFormatter.GetFullName(contactRow,);
            pd.previewImageUrl = "[IMG:flagid=" + contactRow.CountryId + "]";
            pd.subheading = "";

            pd.AddField("[SR_ARCHIVE_DEPARTEMENT]", contactRow.Department);
            if (contactRow.AssociateId != 0)
                pd.AddField("[SR_CC_OUR_CONTACT]", AssociateCache.GetCurrent().GetAssociateFullName(contactRow.AssociateId));

            pd.AddField("[SR_LABEL_NUMBER]", contactRow.Number2);
            string category = CategoryCache.GetCurrent().GetNameFromId(contactRow.CategoryIdx);
            //if (category != null && category.Trim() != string.Empty)
                pd.AddField("[SR_LABEL_CATEGORY]", category);

            ListItemLookupHelper lih = ListItemLookupHelper.GetCurrent();
            pd.AddField("[SR_LIST_BUSINESS]", lih.LookupItem("Business", contactRow.BusinessIdx).Name);
            pd.AddField("", "");

            AddressRow dummyRow = AddressRow.CreateNew();
            pd.AddField("[SR_AL_STREET_LABEL]", AddressFormatter.FormatContact(contactRow, addressRow, dummyRow).ToString() );
            pd.AddField("[SR_AL_POSTAL_LABEL]", AddressFormatter.FormatContact(contactRow, postalAddressRow, dummyRow).ToString());
            pd.AddField("[SR_CC_PHONE]", PhoneFormatter.GetShortDisplayNumber(SoContext.CurrentPrincipal.HomeCountryId, contactRow.CountryId, phoneRow.Phone, true) );
            pd.AddField("[SR_COMMON_URL]", urlRow.UrlAddress);

            return pd;

        static ContactPreviewPlugin()
            _contactTableInfo = TablesInfo.GetContactTableInfo();
            _phoneTableInfo = TablesInfo.GetPhoneTableInfo();
            _addressTableInfo = TablesInfo.GetAddressTableInfo();
            _postalAddressTableInfo = TablesInfo.GetAddressTableInfo();
            _URLTable = TablesInfo.GetURLTableInfo();

Hope this helps!

Af: Tony Yates 8. okt 2018

RE: Add/remove fields in company preview

I have tried to create a plugin as you describe Tony but it will not override but extend.

If I use Integer.MaxValue higher than Integer.MaxValue / 2 it will add my fields to the top of the existing standard. If I use Integer.MaxValue lower than Integer.MaxValue / 2 it will add my fields to the end of the existing fields.

The problem is that I want to modify the existing standard view. It seems that I'm not able to replace or override the standard fields.

In the code below, I expect to only view the stop field, but it also shows the standard.


Public Shared Function FormatLargePreview(ByVal pd As PreviewData, ByVal contactRow As ContactRow, ByVal phoneRow As PhoneRow, ByVal addressRow As AddressRow, ByVal postalAddressRow As AddressRow, ByVal urlRow As URLRow) As PreviewData
        If contactRow.Xstop = 1 Then
        	pd.AddField("Stop using customer", "Yes")
        	pd.AddField("Stop using customer", "No")
	End If
	Return pd
End Function


Af: Henning Dahl 7. nov 2018

RE: Add/remove fields in company preview

HI Henning,

You are correct. New preview provider fields are added to the default preview and can not impact the default fields. 

My apologies for any confusion on this plugin. 

Best regards!

Af: Tony Yates 8. nov 2018

RE: Add/remove fields in company preview

Hi guys, I'm working on a case where we want to add some fields, particularly userdefined fields, to the preview.

Here is a simple example which works:

using SuperOffice.CRM.Rows;
using SuperOffice.CRM.Previews;

namespace ModifyPreviewPlugin
    [PreviewPlugin("MyCompanyPreview", (int.MaxValue / 2) + 1, ContactHint)]
    public class MyCompanyPreview : ContactPreviewPlugin
        protected override PreviewData InnerGetPreview(PreviewData previewData)
            if (TryGetIntHint(ContactHint, out int contactId))
                ContactRow contactRow = ContactRow.GetFromIdxContactId(contactId);

                //Horizontal space
                previewData.AddField("", ""); 

                //Code field
                previewData.AddField("[SR_SEARCH_NUMBER1]", contactRow.Number1);

                //A userdefied field
                UDContactSmallRow udef = UDContactSmallRow.GetFromIdxUdcontactSmallId(contactRow.UserdefId);
                previewData.AddField("My udef field", udef.String05);

            return previewData;

The code above results in this:

I've got a couple of questions when it comes to getting the userdefined fields.

- How can I get the label of the userdefined field dynamically? Are there resource strings for useredfined field labels?

- Does NetServer have a helper which will let me get the value of the userdefined field using a progId string, instead of hardcoding the .String05 field in the code above?

Af: Frode Lillerud 26. mar 2019

RE: Add/remove fields in company preview

Hi Frode,

Look into:  SuperOffice.CRM.Entities.EntityUdefHelper

Say you have some contact:
Entities.Contact contact = ....
Object obj = contact.UdefHelper.GetValue( string progId )

This is how I did it in the BulkUpdate system.
progid is the key that comes from:

UDefFieldRows udefRows = UDefFieldCache.GetCurrent().GetFromType( i_UdefType );

foreach ( UDefFieldRow udefRow in udefRows )





And no, there are no resources for the labels of udef fields.
You get the label from udefRow.FieldLabel which can be encoded with the inlined multi-language encoding hack.
Use the localization methods to localize.

Af: Conrad Weyns 29. mar 2019

RE: Add/remove fields in company preview

Thanks Conrad! That was really helpful!

I can now show a userdefined field using this.

var progId = System.Configuration.ConfigurationSettings.AppSettings["CompanyPreviewProgId"];
var udefField = UDefFieldCache.GetCurrent().GetFromProgId(progId, UDefType.Contact);
var uiCulture = SuperOffice.DCF.Web.ApplicationUtility.GetUserUICulture();
var label = SuperOffice.CRM.Globalization.CultureDataFormatter.ParseMultiLanguageString(udefField.FieldLabel, uiCulture);
var value = contact.UdefHelper.GetValue(udefField.ProgId).ToString();
previewData.AddField(label, value);
Af: Frode Lillerud 29. mar 2019