Announcement

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

    Losing grouping information

    * Isomorphic SmartClient
    * Version v9.0p_2013-08-19 (2013-08-19)
    * All browsers.


    Problem: ListGrid's grouping state is lost when it gets updated by calling setTestData() on the DataSource and invalidateCache() on the grid. Example: collapse group1 and expand group2, grid refreshes, all groups come back open.

    What I've tried
    (1) Using ListGrid.getGroupState() and then calling ListGrid.setGroupState()

    (2) Digging the tree information from the group record and then collapsing/expanding groups based on a state previously saved. Bad idea: the grid blinks before the groups are fixed and causes an annoying experience to the user.

    (3) Taking out groupStartOpen, but no effect.

    Any suggestions? I'll be sharing some snippets too.

    ListGrid
    Code:
            isc.ListGrid.create({
                ID: "queueStatusList",
                width: "100%",
                height: "100%",
                headerHeight: 30,
                cellHeight: 25,
                dataSource: getQueueStatusPanelDataSource(),
                groupByField: "directionType",
                // groupStartOpen: "all",
                sortField: "longest",
                sortDirection: "ascending",
                recordEnabledProperty: "enabled",
                quickDrawAheadRatio: 4.0,
                wrapCells: true,
                fixedRecordHeights: false,
                autoFetchData: true,
                canResizeFields: false,
                canAutoFitFields: false,
                canReorderFields: false,
                alternateRecordStyles: true,
                virtualScrolling: false,
                showHeaderContextMenu: false,
                groupByAsyncThreshold: 100
            });
    DataSource
    Code:
    isc.DataSource.create({
            ID: "queueStatusPanelDataSource",
            clientOnly: true,
            testData: getQueueData("all_queues"),
            fields:[{
                name: "statusFlag",
                headerTitle: "",
                width: 15,
                align: "center",
                type: "image",
                imageURLPrefix: CONFIG.AGUI_IMG_PATH,
                imageURLSuffix: ".png",
                imageSize: 10,
                prompt: CONFIG.PROMPT.memberOf,
                icon: CONFIG.AGUI_IMG_PATH + "agent_info_member_of.png",
                iconSize: 10,
                canEdit: false,
                canFilter: false
            }, {
                name: "enabled",
                showIf: "false"
            }, {
                name: "supervisorOf",
                showIf: "false"
            }, {
                name: "name",
                title: "Queue",
                type: "text",
                width: nameWidth
            }, {
                name: "busy",
                headerTitle: "",
                type: "text",
                align: "center",
                showIf: busyShowIf,
                prompt: CONFIG.PROMPT.busyInteractions,
                icon: CONFIG.AGUI_IMG_PATH + "agent_info_busy_agent.png",
                iconSize: 16,
                width: 26
            }, {
                name: "wait",
                headerTitle: "",
                type: "text",
                align: "center",
                showIf: waitShowIf,
                prompt: CONFIG.PROMPT.inQueueInteractions,
                icon: CONFIG.AGUI_IMG_PATH + "agent_info_waiting.png",
                iconSize: 16,
                width: 26,
                formatCellValue: formatQueueStatusCellValue
            }, {
                name: "longest",
                headerTitle: "",
                type: "text",
                align: "center",
                icon: CONFIG.AGUI_IMG_PATH + "agent_info_duration.png",
                iconHeight: 16,
                iconWidth: 16,
                prompt: CONFIG.PROMPT.longestWaiting,
                canSort: true,
                width: 52
            }, {
                name: "lastInteraction",
                title: CONFIG.LAST + "<br>" + CONFIG.CONTACTED,
                type: "datetime",
                showIf: lastInteractionShowIf,
                align: "right",
                datetimeFormatter: "toLocaleString",
                width: 68
            },{
                name: "directionType",
                type: "text",
                showIf: "false",
                valueMap: directionTypeValueMap
            },{
                name: "favIconField",
                headerTitle: "",
                align: "center",
                type: "image",
                width: 25,
                emptyCellValue: "",
                icon: CONFIG.AGUI_IMG_PATH + "agent_info_fav_on.png",
                iconSize: 16,
                prompt: CONFIG.PROMPT.favorites,
                imageURLPrefix: CONFIG.AGUI_IMG_PATH,
                imageURLSuffix: ".png",
                imageSize: 16,
                formatCellValue: formatQueuesFavIconField
            }]
        });

    #2
    Just to be clear - you're talking about the open state of the group (which groups are open, and which are closed).

    On a complete data change (due to setData(), for example), this state is not retained as the underlying set of data may be completely different, rendering the old open/closed state inapplicable to the new nodes.
    Instead the specified groupStartOpen attribute is consulted and applied.

    To avoid this behavior, you can explicitly manipulate the group tree yourself to open/close the nodes you want to have opened or closed when you the data changes.

    If you'd like additional handling for this sort of thing built into the framework, it's something that might be eligible for Feature Sponsorship. Let us know if you'd wan't to pursue that and we can iron out the specifics of the behavior you'd expect and how much work would be involved in achieving this

    Regards
    Isomorphic Software

    Comment


      #3
      After some testing with observing various methods I decided that observing the groupTree changeDataVisibility was my most reliable option. I was confused as to why I could not get the grid to observe that method, until I looked at the source and saw that the grid already observes changeDataVisibility and calls _folderToggleObservation.

      So my solution was to re-open the previously opened groups was to override _folderToggleObservation on the ListGrid

      Code:
        $34u:function() {
          this.openGroupValues = this.groupTree.getOpenFolders().getProperty("groupValue");
      
          this.Super("$34u", arguments);
        // end $isc_ListGrid__folderToggleObservation
        },
      I also overrode dataArrived to re-open those folders:

      Code:
        dataArrived:function(startRow, endRow) {
          if (this.openGroupValues) {
            try {
              this.openGroupValues.each(function(groupValue) {
                if (!groupValue) return;
      
                var folder = this.groupTree.find("groupValue", groupValue);
                if (!folder) return;
      
                this.groupTree.openFolder(folder);
              // end each
              }.bind(this));
            } catch(err) {
              // This will catch the case where grid is no longer grouped (groupTree doesn't exist)
              // and should catch anything else I've not thought of
              delete this.openGroupValues;
            }
          }
      
          this.Super("dataArrived", arguments);
        // end dataArrived
        },
      I doubt it's the most elegant and I don't like that it's brittle around the obfuscated _folderToggleObservation method. However, it does work even when then canvas is destroyed and redrawn.

      Can you suggest anything cleaner?

      Thanks!

      Comment

      Working...
      X