Skip to content

Additional Feature Using a LookupEditor in direct entry in a Grid

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

Hello, I wanted to use a LookupEditor drop-down list to make direct entry in a grid. In the demo, on the product screen, there are examples of drop-down lists, but they are just fixed lists of type Select2Editor.

Volkan had already answered this question in another post saying that this is not possible in the current version of Serenity. After much research, I confirm that it is impossible.

However, I absolutely wanted to use a LookupEditor and founded how to do it. Attention, to get there, I had to modify basic classes of Serenity. This post is for sharing this find for those who are interested in this use.

To get there, modify the following files ...

Modify the file /Scripts/SlickGrid/slick.grid.js (remember to save this file before making any changes and it will be overwritten if you update the Serenity version)

function render() {
   ...
   // generation of the onRender event with each rendering and production of the html code
   trigger(self.onRender, { grid: self });
}
$.extend(this, {
   "slickGridVersion": "2.1",

   // Events
   ...
   "onRender": new Slick.Event(),

Modify the file /Scripts/typings/serenity/Serenity.CoreLib.d.ts (remember to save this file before making any changes and it will be overwritten if you update the Serenity version)

interface Grid {
   ...
   onRender?: Slick.Event;
}

These changes will add a new event to each render in the grid.

Example of adding a LookupEditor in direct entry in a grid (in xxxEditor.ts for an entry in a master-detail grid)

...
constructor(container: JQuery) {
   ...
   // interception of the onRender event
   this.slickGrid.onRender.subscribe(() => {
      // call of the function that will bind the editors with the fields (<input>) of the html page
      this.liaisonEditeurs();
   }
}

private liaisonEditeurs() {
   // course of all the lines present in the grid
   var laLignes = this.view.getItems();
   for (let lnCpt in laLignes) {
      this.liaisonEditeur(lnCpt, laLignes);
   }
}

private liaisonEditeur(pnIndex: string, paLignes: trs_CtcTelRow[]) {
   // Link the editor to the html field only if it has not been linked yet.
   // The editor adds the class select2-offscreen in the class tag of the field.
   // it is possible if you wish to add your own class. Replace select2-offscreen with "MyClass" and add in the If block :
   // $("#CtcTelIdf" + pnIndex).addClass("MyClass");

   if (!$("#CtcTelIdf" + pnIndex).hasClass("select2-offscreen")) {
      // Editor creation and field binding
      var loEditeur = new Tables.TabIdfListeEditor($("#CtcTelIdf" + pnIndex));

      // initialization of the value by the one in the line
      loEditeur.value = Q.toId(paLignes[pnIndex].CtctelIdfFk);

      // interception of the selection change event in the LookupEditor
      loEditeur.changeSelect2(e => {
         // assigning the new value selected in the line
         paLignes[pnIndex].CtctelIdfFk = Q.toId(loEditeur.value);
      });
   }
}

protected getColumns() {
   var laColonnes = super.getColumns();

   // adding the field when producing the html code that will be later replaced when creating the editor (xxx.format)
   var loCtcTelIdf = Q.first(laColonnes, x => x.field === fld.CtctelIdfFkIdf);
   loCtcTelIdf.referenceFields = [fld.CtctelIdfFk];
   loCtcTelIdf.format = ctx => { return '<input type="hidden" id="CtcTelIdf' + ctx.row + '" title="Indicatif" />'; };

   return laColonnes;
}

It works very well for me, I hope it will help you. Perhaps this could be a suggestion for adding it to a future version of Serenity. For information, my actual version of Serenity is 3.6.0.

Here an example of LookupEditor class, file TabIdfListeEditor.ts :

namespace MyProject.MyModule {
    @Serenity.Decorators.registerEditor()
    export class TabIdfListeEditor extends Serenity.LookupEditorBase {
        constructor(container: JQuery, options?: Serenity.LookupEditorOptions) {
            super(container, options);
        }

        protected getLookupKey(): string {
            var lcValeur = super.getLookupKey();
            lcValeur = Tables.tab_IdfRow.lookupKey;
            return lcValeur;
        }
        
        protected getItemText(item: tab_IdfRow, lookup: Q.Lookup) {
            return "+" + item.IdfIdf + " (" + item.IdfPaysFkPaysNom + ")";
        }

        protected getSelect2Options(): Select2Options {
            var liOptions = super.getSelect2Options();

            liOptions.dropdownAutoWidth = true;

            return liOptions;
        }
    }
}

I think on the same way you can use a DateEditor or DateTimeEditor...

Here is an example of the final result in a grid :

Example of grid in direct entry with LookupEditor

This Wiki page was created from issue #3508

Clone this wiki locally