Skip to content

Lookup Editors How to Create Lookup Editor for code description tables

Victor Tomaili edited this page May 3, 2021 · 1 revision

Inspired by issue https://github.com/volkanceylan/Serenity/issues/1398 of awesomegithubusername and edson I create this wiki page that describe how create a lookup editor that show data from a code and description field.

In most case tables has a code and a description. In these cases you would like to show at user both data.

First of all create a TypeScript class editor that extend Serenity.LookupEditorBase. The options for this editor are a codeFieldName and descrFieldName. These are needed to specify the fields that contains code value and description value.

    export interface LKCodeDescOptions extends Serenity.LookupEditorOptions {
        codeFieldName: string;
        descrFieldName: string;
    }

In the constructor of the editor I set two data attribute int the container object, with the parameters.

namespace MyNameSpace {
  @Serenity.Decorators.registerEditor()
     export class LKCodeDescr extends Serenity.LookupEditorBase<LKCodeDescOptions, any> {

     constructor(container: JQuery, opt?: LKCodeDescOptions)
     {
         super(container, opt);

         container.data("codeName", opt.codeFieldName);
         container.data("descrName", opt.descrFieldName);
     }

Then get Select2 options from base class and set the two delegate formatResult formatSelection to our function

    public getSelect2Options() {
        var selec2Options = super.getSelect2Options();

        selec2Options.formatResult = this.myFormatResult;
        selec2Options.formatSelection = this.myFormatSelection;

        return selec2Options;
    }

In formatSelection, that return the string shown to the user on select2 after user selection, I get the data parameters from control and use the to accesse the data in item. Then I format the result.

    protected myFormatSelection(item: Serenity.Select2Item): string {
        if (item === undefined)
            return null;

        var code = item.source[this.element.data("codeName")];
        var descr = item.source[this.element.data("descrName")];

        var title = "Code: " + code;
        title += " - " + descr;

        return "<div title='" + title + "'><b>" + code + "</b>&nbsp;-&nbsp;" + descr + "</div>";
    }

In formatResult that populates the select2 item per item, I get the data parameters from control and form the single item in select2. At the end I set item.text to make the search possible in both code and description values.

protected myFormatResult(item: Serenity.Select2Item) {
        var code = item.source[this.element.data("codeName")];
        var descr = item.source[this.element.data("descrName")];

        var title = "Code: " + code;
        title += " - " + descr;

        var markup = '<div class="row">' +
                '<div class="col-xs-2" style="white-space: nowrap"><b>' + code + "</b>" + "</div>" +
                '<div class="col-xs-10"><small>' + descr + '</small></div>' +
                '</div>';

        // This for search on code and description
        item.text = code + " " + descr;

        return markup;
    }

After that, you have to transform T4 and get the LKCodeDescrAttribute.

To facilitate your use I than extended attribute (that is a partial class) with LKCodeDescrAttribute in a separated file

    public partial class LKCodeDescrAttribute : LookupEditorBaseAttribute
    {
        public LKCodeDescrAttribute(Type lookupType, String codeFieldName, String descriptionFieldName)
            : base(Key)
        {
            if (lookupType == null)
                throw new ArgumentNullException("lookupType");

            var attr = lookupType.GetCustomAttribute<LookupScriptAttribute>(false);
            if (attr == null)
            {
                throw new ArgumentException(String.Format(
                    "'{0}' type doesn't have a [LookupScript] attribute, so it can't " +
                    "be used with a LookupEditor!",
                    lookupType.FullName), "lookupType");
            }

            SetOption("lookupKey", attr.Key);

            base.CodeFieldName = codeFieldName;
            base.DescrFieldName = descriptionFieldName;
        }
    }

Then use in Row or Form

    [LKCodeDescr(typeof(Modules.YourLookup), "MyCodeField", "MyDescrField")]

Result

Full code of LKCodeDescr.ts :

namespace MyNameSpace {
    @Serenity.Decorators.registerEditor()
    export class LKCodeDescr extends Serenity.LookupEditorBase<LKCodeDescOptions, any> {

        constructor(container: JQuery, opt?: LKCodeDescOptions)
        {
            super(container, opt);

            container.data("codeName", opt.codeName);
            container.data("descrName", opt.descrName);
        }

        public getSelect2Options() {
            var selec2Options = super.getSelect2Options();

            selec2Options.formatResult = this.myFormatResult;
            selec2Options.formatSelection = this.myFormatSelection;

            return selec2Options;
        }

        protected myFormatSelection(item: Serenity.Select2Item): string {
            if (item === undefined)
                return null;

            var code = item.source[this.element.data("codeName")];
            var descr = item.source[this.element.data("descrName")];

            var title = "Code: " + code;
            title += " - " + descr;

            return "<div title='" + title + "'><b>" + code + "</b>&nbsp;-&nbsp;" + descr + "</div>";
        }

        protected myFormatResult(item: Serenity.Select2Item) {
            var code = item.source[this.element.data("codeName")];
            var descr = item.source[this.element.data("descrName")];

            var title = "Code: " + code;
            title += " - " + descr;

            var markup = '<div class="row">' +
                '<div class="col-xs-2" style="white-space: nowrap"><b>' + code + "</b>" + "</div>" +
                '<div class="col-xs-10"><small>' + descr + '</small></div>' +
                '</div>';

            // This for search on code and description
            item.text = code + " " + descr;

            return markup;
        }
    }

    export interface LKCodeDescOptions extends Serenity.LookupEditorOptions {
        codeName: string;
        descrName: string;
    }
}
Clone this wiki locally