Changing fields on "Select Objects" / "Objects Search" UI in Commerce Manager

Vote:
 

I'm wondering how to change the fields on the Objects Search (or Select Objects) pop up that you get if you're doing something like, for example, changing the parent org of a contact. From digging into the Commerce Manager code it is looking up a ListViewProfile from the database - in these object search UI's it is using the "EntitySelect" from the ListViewProfile table for the respective class ("Organization" in my case).

I'm trying to figure out how to change the columns/fields included on this table view. I couldn't see anything in Commerce Manager for changing a ListView, and from googling this is the closest answer I've found:

https://world.episerver.com/forum/developer-forum/Episerver-Commerce/Thread-Container/2016/6/change-parent-organization-for-contact/

This looks promising, but I'm wondering if anyone can confirm if this is the preferred approach?

We're using Commerce v11.8.5

#196413
Aug 30, 2018 7:20
Vote:
 

A few screenshots would be very helpful here, I'm not sure which part you are talking about 

#196415
Aug 30, 2018 8:12
Vote:
 

Hmm, I would but can't figure out how to attach a screenshot - the insert image UI asks for a "source" but no idea how to simply upload an image for it..?

#196418
Aug 30, 2018 9:02
Vote:
 

Okay, how about this :) Edit contact:

https://snag.gy/VbEk1a.jpg

And then choose to select another parent org:

https://snag.gy/zjvrNo.jpg

#196419
Aug 30, 2018 9:05
Vote:
 

Hello Matthew!

Just to ensure that I understood this correctly, are you trying to (for example) add your own custom fields to those forms and/or remove existing ones?

#196424
Aug 30, 2018 11:39
Vote:
 

Can you give an example of what type of change you want to make to that table? Is it adding a custom field to be presented on each organisation for example?

#196425
Aug 30, 2018 11:42
Vote:
 

I’m trying to add another field (which happens to be a custom one I added, but don’t think that matters) to be presented. Also, from reading the Commerce Manager logic, I think that also will allow that field to be included in the search.

#196427
Aug 30, 2018 11:45
Vote:
 

So after researching this a bit I'd have to say that yes, that'd be the best approach. One simple reason being that you don't have to modify any Commerce Manager-specific code or views, you want to generally avoid doing that because those types of changes get reset whenever you upgrade.

Anyway, I looked at the code that you linked to and it worked if you needed to add fields, but not remove (for example if you don't want description). Also it didn't allow you to change the order of the columns.

Here's my modified version, running as an InitializationModule:

using System.Collections.Generic;
using Castle.Core.Internal;
using EPiServer.Framework;
using EPiServer.Framework.Initialization;
using EPiServer.Security;
using Mediachase.BusinessFoundation.Core;
using Mediachase.BusinessFoundation.Data;
using Mediachase.Commerce.Customers;
using Mediachase.Commerce.Security;
using InitializationModule = EPiServer.Commerce.Initialization.InitializationModule;

namespace <your namespace path>
{
    [ModuleDependency(typeof(InitializationModule))]
    public class OrganizationSelectionInitialization : IInitializableModule
    {
        // In case you want to reset the fields displayed to default.
        private readonly List<UiField> _defaults = new List<UiField>
        {
            new UiField("Name", 200),
            new UiField("Description", 200)
        };

        // Add all the fields you want displayed here, and their widths. This also controls in which order they will be displayed.
        private List<UiField> _fieldsList = new List<UiField>
        {
            new UiField("OrganizationId", 50),
            new UiField("Name", 200),
            new UiField("Description", 200),
            new UiField("Modified", 200),
            new UiField("CreatorId", 200)
        };

        public void Initialize(InitializationEngine context)
        {
            var listViewProfile = ListViewProfile.Load("Organization", "", "EntitySelect");
            if (listViewProfile == null)
            {
                return;
            }

            if (_fieldsList.IsNullOrEmpty())
                _fieldsList = _defaults;

            // If necessary, add check here to ensure that we don't run the rest of this code unnecessarily, for example checking that listViewProfile.FieldSet is not an exact match to _uiFields list already.
            
            CleanFieldsList();

            AddMetaFieldsToEntitySelectListViewProfile(listViewProfile);
        }

        public void Uninitialize(InitializationEngine context)
        {
            // Do nothing
        }

        private void AddMetaFieldsToEntitySelectListViewProfile(ListViewProfile listViewProfile)
        {
            // To reduce risk of fields showing up twice and to ensure sort order, we need to clear the UI list.
            // So we need to make sure that every field we want to be shown is in our _uiFields list, including the default ones.
            listViewProfile.ColumnsUI.Clear();
            listViewProfile.FieldSet.Clear();

            foreach (var uiField in _fieldsList)
            {
                listViewProfile.FieldSet.Add(uiField.FieldName);
                listViewProfile.ColumnsUI.Add(new ColumnProperties(uiField.FieldName, uiField.ColumnWidth+"px", string.Empty));
            }
            
            ListViewProfile.SaveSystemProfile("Organization", "EntitySelect", PrincipalInfo.CurrentPrincipal.GetContactId(), listViewProfile);
        }

        /// <summary>
        /// Removes fields from the FieldSet that do not exist on the BusinessFoundation model. This makes sure that the search functionality isn't broken if someone decides to remove a field at some point.
        /// </summary>
        private void CleanFieldsList()
        {
            var organizationEntity = DataContext.Current.GetMetaClass(OrganizationEntity.ClassName);

            var unavailableFields = new List<UiField>();
            foreach (var uiField in _fieldsList)
            {
                if (!organizationEntity.Fields.Contains(uiField.FieldName))
                {
                    unavailableFields.Add(uiField);
                }
            }
            unavailableFields.ForEach(x => _fieldsList.Remove(x));
        }

        private class UiField
        {
            public UiField(string fieldName, int columnWidth)
            {
                FieldName = fieldName;
                ColumnWidth = columnWidth;
            }

            public string FieldName { get; }
            public int ColumnWidth { get; }
        }
    }
}

Hope this helps!

#196441
Edited, Aug 30, 2018 19:13
Vote:
 

Another thing, the search only works for some types of fields. What I could discern is that it works for non-reference types.

For example, DateTime, Text, LongText and Guid types worked with the search

But something like OrganizationType (which references another Business Foundation object) is not searchable.

#196442
Aug 30, 2018 19:18
Vote:
 

Hi Jafet

This is awesome thanks! Our field is an Integer and have put in code based on your example and all works perfectly, including search :)

Thanks again!

#196446
Aug 31, 2018 1:33
This topic was created over six months ago and has been resolved. If you have a similar question, please create a new topic and refer to this one.
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.