Extending dgrid formatters

Vote:
 

I'm looking for ways to improve experience for editors by adding some more information into the block search reusults or the tooltip:

I've explored a lot of files, and I think what I have to do is to add or override default formatter to \epi_modules\CMS\11.24.1\ClientResources\epi-cms\dgrid\formatters. Haven't found much resources.

What I tried so far:

  1. Copied ClientResources\epi-cms\dgrid\formatters.js.uncompressed.js to \ClientResources\Scripts\AlloyFormatters.js
  2. Created Initializer.js file:
    define([
        "dojo",
        'dojo/_base/declare',
        // Parent class
        'epi/_Module',
        // Commands
        'alloy/AlloyFormatters'
    ], function (
        // Dojo
        dojo,
        declare,
        // Parent class
        _Module,
        AlloyFormatters
    ) {
     
        return declare([_Module], {
     
            initialize: function () {
                this.inherited(arguments);
            }
        });
    });​
  3. Updated module config to initialize my module after Shell and CMS:
    <?xml version="1.0" encoding="utf-8"?>
    <module>
        <assemblies>
    	    <!-- This adds the Alloy template assembly to the "default module" -->
            <add assembly="AlloyDemo" />
        </assemblies>
        <clientResources>
            <add name="epi-cms.widgets.base" path="Styles/Styles.css" resourceType="Style"/>
        </clientResources>
      <clientModule initializer="alloy.Initializer">
        <moduleDependencies>
          <add dependency="Shell" type="RunAfter" />
          <add dependency="CMS" type="RunAfter" />
        </moduleDependencies>
      </clientModule>
        <dojo>
            <!-- Add a mapping from alloy to ~/ClientResources/Scripts to the dojo loader configuration -->
            <paths>
                <add name="alloy" path="Scripts" />
            </paths>
        </dojo>
    </module>​

What I observe in when I debug the code is following:

  1. Default formatters register, by calling Formatter.addFormatter() method:
  2. My module is initialized, and calls method Formatter.addFormatter("contentItem", module.contentItemFactory, true); effectively overriding default implementation provided by default modules:

  3. However, when I type something in the block search field, and break in the JS, the formatter that is being picked is always the default one:

As you can see, it's the default implementation of contentItem formatter resolved, and not mine from AlloyFormatters.

As I'm no dojo-expert, I feel like I'm missing something very simple.

#223789
Edited, Jun 04, 2020 15:21
Vote:
 

I figured it out. The actual place to look into is/was epi-cms/widget/ReadOnlyContentList  - this component has a protected method, called _getBaseSettings() which returns configuration item, with direct reference to formatters.contentItemFactory() method.

So what I did, in module initializer I have put together following code:

define([
    "dojo",
    'dojo/_base/declare',
    // Parent class
    'epi/_Module',
    // Commands
    'alloy/AlloyFormatters',
    "epi-cms/widget/ReadOnlyContentList",
    // epi
    "epi/shell/dgrid/Formatter",

    "epi-cms/core/ContentReference",
    "epi-cms/dgrid/formatters"
], function (
    // Dojo
    dojo,
    declare,
    // Parent class
    _Module,
    AlloyFormatters,
    ReadOnlyContentList,
    Formatter,
    ContentReference,
    formatters
) {

    return declare([_Module], {

        initialize: function () {
            this.inherited(arguments);

            /*
             * Overriding default implementation of _getBaseSettings() method
             */
            ReadOnlyContentList.prototype._getBaseSettings = function (contextMenu) {
                
                /*
                 * This part is copy/pasted from original implementation
                 */
                var titleSelector = function (item) {
                    var reference = new ContentReference(item.contentLink);

                    return formatters.title(item.name, reference.id, item.contentTypeName);
                };

                var thumbnailSelector = function (item) {
                    return item.thumbnailUrl;
                };
                
                /*
                 * Here I build reference to my implementation of contentItemFactory() implementation
                 */
                var alloyFormatter = AlloyFormatters.contentItemFactory("name",
                    titleSelector,
                    null,
                    contextMenu,
                    thumbnailSelector,
                    undefined,
                    undefined,
                    true);

                /*
                 * Returning object  - only `formatters` option is overriden, rest is as in default implementation
                 */
                return {
                    store: this.store,
                    queryOptions: this.queryOptions,
                    formatters: [alloyFormatter],
                    deselectOnRefresh: true,
                    sort: this.queryOptions && this.queryOptions.sort
                };
            }
        }
    });
});

now my code runs :)

#223862
Edited, Jun 05, 2020 12:08
* 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.