Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
Clear All
new posts

    ListGrid.selectionUpdated called even when the selection was not updated

    After upgrading from SmartClient 9.1 to 12.0 we are now running into the bug below.

    After calling setSelectedState on a ListGrid, method ListGrid.selectionUpdated is called by SmartClient code even when the output of method setSelectedState is the same as it was at the time method setSelectedState was called.

    VERSION: This was working properly in 9.1, and stopped working starting in 10.0. It is still not working in latest 12.0 as we can reproduce it in latest Showcase example (see below).
    We are currently running v12.0p_2019-02-28/Pro Development Only.

    BROWSER: This behavior has been observed on all browsers/platforms i.e. Chrome,Firefox,IE11,Safari/Linux,Windows 7 Enterprise,Mac Mojave

    SCENARIO:
    ListGrid containing some rows. No row selected.
    Call method setSelectedState on the listgrid with content equivalent to the current selection (in particular, for the "empty" concept this may be either null, "[]", undefined etc and the current value may not be identical to the passed in value i.e. the current state returned by getSelectedState() may be "[]" and the value passed in to method setSelectedState may be null)
    Expectation: nothing happens
    Issue: method selectionUpdated is called
    Repeat when a row is already selected (by calling setSelectedState with the same selection content)
    Issue: method selectionUpdated is called

    This issue is particularly problematic because in our case, our implementation of method selectionUpdated is triggering a resource-consuming fetch which should only be called when the selection is truly changed.


    STEPS TO REPRODUCE:
    Navigate to the following Showcase example:https://www.smartclient.com/smartcli...sizeIncrease=2

    Replace the entire contents of fetch.js with the following:

    Code:
    var lListGrid_o = isc.ListGrid.create({
        ID:"dsListGrid",
        top: 100,
        width: "100%",
        height: "100%",
        autoFetchData: true,
        dataSource: "supplyItem",
        selectionUpdated: function(record, recordList) {
            alert("selectionUpdated was called");
        },
        //Call setSelectedState only if aInSelectedState_s corresponds to a different selectedState
        updateSelectedState: function(aInSelectedState_s) {
            var lSelectedState_s = this.getSelectedState(),
                lIsSameSelectedState_b =
                    ((lSelectedState_s === aInSelectedState_s) ||
                     (this._isEmptySelectedState(lSelectedState_s) && this._isEmptySelectedState(aInSelectedState_s)));
            if (!lIsSameSelectedState_b) {
                this.setSelectedState(aInSelectedState_s);
            }
        },
        // aInSelectedState_s is expected to always come from the output of calling getSelectedState here
        _isEmptySelectedState: function(aInSelectedState_s) {
            var lSelectedState_o;
            if (!isc.isA.String(aInSelectedState_s)) {
                return true;
            }
            try {
                lSelectedState_o = isc.eval(aInSelectedState_s);
            } catch (e) {
                return true;
            }
            return !lSelectedState_o || lSelectedState_o.length === 0;
        },
    });
    isc.IButton.create({
        top: 0, width: 200, title: "Set selection",
        click: function () {
            var lSelectedState = lListGrid_o.getSelectedState();
            console.log(lSelectedState);
            // Note: clearly no one would be silly enough to call setSelectedState with the direct output of getSelectedState, but just doing this here as the simplest way to demonstrate the bug
            lListGrid_o.setSelectedState(lSelectedState);
        }
    });
    isc.IButton.create({
        left: 300, width: 200, title: "Update selection",
        click: function () {
            var lSelectedState = lListGrid_o.getSelectedState();
            console.log(lSelectedState);
            lListGrid_o.updateSelectedState(lSelectedState);
        }
    });

    Click on the "Try it" button to run the code
    To reproduce with empty selection:
    Click on the "Set selection" button (observe the bug: method selectionUpdated is called i.e. shows the popup)
    Click on the "Update selection" button corresponding to my tentative workaround (observe that method selectionUpdated is NOT called when passing in the same value which is the expected/desired behavior)
    To reproduce with non-empty selection:
    Select a row (observe: the selectionUpdated popup appears as expected because the selection was truly changed)
    Click on the "Set selection" button (observe the bug: method selectionUpdated is called i.e. shows the popup)
    Click on the "Update selection" button corresponding to my tentative workaround (observe that method selectionUpdated is NOT called when passing in the same value which is the expected/desired behavior)



    Question: is it safe for us to call our workaround method updateSelectedState(), or do you see potential issues with it under some circumstances?

    #2
    Thanks for the very clear report.
    We've made a change to avoid firing the selectionUpdated() notification in the development branch (12.1d). This will be present in nightly builds going forward (dated June 3 and above)
    Your workaround is safe to use in 12.0

    Regards
    Isomorphic Software

    Comment


      #3
      On reflection we've decided to go ahead and port the fix back to the 12.0 and 11.1 branches. As of the next nightly build (dated June 5 or above), your workaround should no longer be necessary

      Regards
      Isomorphic Software

      Comment


        #4
        Perfect, even better. Appreciate your quick turnaround on this one. Thanks

        Comment

        Working...
        X