Skip to content

Conditionally disable the EditLinks in a Detail Editor that is part of MasterDialog with a Parent Child Relationship

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

HOW TO:

Conditionally Disable Edit Links:

In an XyzDetailEditor that is the related part of a Master Dialog.


There might be a situation where you need to disable the edit links in your xyzEditorDialog - for example when an order is placed it is locked and can not be changed.

When I approached this issue the first thing was to disable the grid and all would be well. [Serenity makes things easy :-) .. except this time (-: .

When I created my columns of course I took the Serenity route - easy peazy and placed that [EditLink] on the field. EditLinks in the XYZcolumn are wonderful - they automagically create the links for you.

When I disabled the grid everything on the grid was disabled and to my dismay and surprise - everything EXCEPT hyperlinks in the grid!

No problem I will hunt for the solution and find it after all Serenity has all kinds of built ins somewhere and work around's in the issues list- and yet after two weeks of searching and effort and design ideas - stuck!

There was no server side code for the declaration that I could use to set a conditional field - oh I so wanted it - and not anything straight forward I could implement.

There was nothing on the client side that was implemented either , so I came up with this solution.


This was a very difficult task to achieve especially in SlickGrid. A Downside or an Upside depending on how you look at it - is that SlickGrid does not have a render complete method.


Required: Modify the SlickGrid to have the renderComplete event. Add the event to the Serenity.CoreLib.js and build the min and map files.
Add a css style to site.mydb.less Add the code to the dialog that contains your editor (if you need to) and your code to the editor.


SLICK GRID CODE CHANGES.


**In Slick.Grid.js **

function render() {
    ...
    renderRows(rendered);
    trigger(self.onRenderCompleted, {}); // fire when rendering is done
    ...
}

Add a new event handler to the 'public API': somewhere around line 5040ish

"onRenderCompleted":            new Slick.Event(),

Bind to the new event in your code:


grid.onRenderCompleted.subscribe(function() {
    alert('onRenderCompleted');
    console.log('onRenderCompleted');
});

In Serenity.CoreLib.Js


at:[Line 15179 ish]

RemoteView(options) {

...

            var onRenderCompleted = new Slick.Event();
            var intf;
...
  
at:[Line 16145 ish]
 intf = { 
...
                "onDataLoading": onDataLoading,
                "onRenderCompleted": onRenderCompleted
...
}

You will need {Closure Compiler} to minify the Serenity.CoreLib and create a map file. Use this in the Command Prompt

java -jar D:\Development\ClosureCompiler\closure-compiler.jar --js D:\Projects\Projects.Web\Scripts\serenity\Serenity.CoreLib.js `
     `--create_source_map D:\Projects\Projects.Web\Scripts\serenity\new\Serenity.CoreLib.min.js.map `
     `--source_map_format=V3`
     `--js_output_file D:\Projects\rojects.Web\Scripts\serenity\new\Serenity.CoreLib.min.js


##In your XyzEditor ##


       constructor(container: JQuery) {
            super(container);

            this.slickGrid.onRenderCompleted.subscribe((e) => {
                var test = this.orderSubmitted;
                if (this.orderSubmitted) {

                    var eLinks = this.element.find('.s-MyDB-VendorOrderDetailEditorLink');

                    this.removeEditLinks(true);

                }
            });

      }


        public removeEditLinks(remove: boolean) {

            var eLinks = this.element.find('.s-MyDB-VendorOrderDetailEditorLink');

            for (var i = 0; i < eLinks.length; i++) {

                if (remove) {
                    this.disableLink(eLinks[i]);
                }
                else {
                    this.enableLink(eLinks[i]);
                }

            }

        }


        protected enableLink(eLink: Element) {

            var attrRef = eLink.getAttribute('data-href'); 
            if (!attrRef) {               
                return;
            }

            if (eLink.classList.contains('isDisabled')) {

               eLink.className.replace('isDisabled', 's-EditLink');

               eLink.className.replace('Disabled', 's-MyDB-VendorOrderDetailEditorLink');

               eLink.removeAttribute('aria-disabled');

               eLink.setAttribute('href', attrRef);
 
            }

        }

        protected disableLink(eLink: Element) {
            eLink.setAttribute('data-href', eLink.attributes.getNamedItem('href').value);
            eLink.className = eLink.className.replace(/\bs-EditLink\b/g, 'isDisabled');
            eLink.className = eLink.className.replace(/\bs-MyDB-VendorOrderDetailEditorLink\b/g, 'Disabled');
            eLink.setAttribute('aria-disabled', 'true');
        }

Last of all the CSS to be placed in your site.mydb.less

.isDisabled {
    cursor: not-allowed;
    opacity: 0.5;
}

.isDisabled > a {
    color: currentColor;
    display: inline-block; /* For IE11/ MS Edge bug */
    pointer-events: none;
    text-decoration: none;
}
Clone this wiki locally