Announcement

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

    Sorting a TreeGrid after adding nodes

    I am using SmartClient_v111p_2017-09-16_LGPL with IE11.

    I have a TreeGrid with a hidden column (DisplayOrder). I can insert a node into the Tree and set the value of the attribute, DisplayOrder. I am then making the call to sort the TreeGrig:
    TreeGrid.sort('DisplayOrder', 'ascending');

    I tried placing markForRedraw() before and after the sort, but the sort is not reflected.
    Any ideas on what is going wrong with the sort?

    I think I read that the sort of a tree would sort sibling nodes and keep the overall schema of the tree. Is this true?


    #2
    You can see sorting of TreeGrids working fine in numerous samples. Both folders and modes are sorted. First step is elementary troubleshooting: is there a warning in the Developer Console? Is your sort field misspelled or simply missing from the data?

    Comment


      #3
      I am still having a problem getting the sort to work. In the attachment, the column beginning Internal contains the values for the sort operation.
      TIA
      Paul

      Click image for larger version

Name:	ReOrder.PNG
Views:	286
Size:	45.6 KB
ID:	251964


      Code:
      isc.DataSource.create({
       ID: "_isoDsProject", fields: [  { name: "ProjectTree"       , type: "text"  , length:  50 }, 
               { name: "ID"                , type: "text"  , length:  40, primaryKey: true },
               { name: "TaskID"            , type: "text"  , length:  40 },
               { name: "RefDesLevel"       , type: "integer"   },
               { name: "Active"            , type: "boolean"   }, 
               { name: "StartDatePlanned"  , type: "date"      },
               { name: "EndDatePlanned"    , type: "date"      },
               { name: "StartDateActual"   , type: "date"      },
               { name: "EndDateActual"     , type: "date"      },
               { name: "StartActualSaved"  , type: "boolean"   },
               { name: "EndActualSaved"    , type: "boolean"   },
               { name: "OnSite"            , type: "integer"   },
               { name: "Churn"             , type: "integer"   },
               { name: "Status"            , type: "text"  , length:  50 },
               { name: "EstimatedHours"    , type: "integer"   },
               { name: "CompletedHours"    , type: "integer"   },
               { name: "RemainingHours"    , type: "integer"   },
               { name: "PercentComplete"   , type: "integer"   },
               { name: "Notes"             , type: "text"  , length: 500 },
               { name: "Travel"            , type: "integer"   },
               { name: "Editable"          , type: "boolean"   },
               { name: "IDSortOrder"       , type: "integer"   }   ]
      });
      
      isc.TreeGrid.create({
       ID: "_isoProjectTree",
       top: 0,
       left: 1,
       htmlElement: "divProjectProgress",
       width: 700,
       height: 526,
       alternateRecordStyles: true,
       DataSource: _isoDsProject,
       autoFetchData: false,
       canSort: false,
       sortFieldNum: 2,
       sortDirection: "ascending",
       showHeaderContextMenu: false,
       canEdit: true,
       editByCell: true,
       selectOnEdit: true,
       selectionType: "single", //  "simple", //"multiple", //  "single",
       showOpenIcons: false,
       showDropIcons: false,
       showNodeIcons: false,
       showFolderIcons: false,
       folderIcon: null,
       nodeIcon: null,
       showFullConnectors: true,
       showRowNumbers: true,
       closedIconSuffix: "+",
       fields: [
         {  name: "TaskID", title: "Subsystem Tree", width: 260, canEdit: true, changed: "ProjectTree_Changed(this)",
          treeField: true, frozen: true, editorType: "select", optionDataSource: "_dsTaskList", displayField: "Task", valueField: "ID",
          editorProperties: {
           optionDataSource: "_dsTaskList",
           getPickListFilterCriteria: function () {
            var disRec = _isoProjectTree.getEditedRecord(_isoProjectTree.getEventRow());
            var level = disRec.RefDesLevel;
      
            var taskData = _dsTaskList.cacheData;
            var options = taskData.filter(function (x) { return x.Level == this }, level);
      
            var sibling = RecordByIdTree(_isoProjectTree, disRec, 'ID', 'RefDesLevel');
            sibling = FirstSiblingTree(_isoProjectTree, sibling);
            var cachSibling;
            while (sibling) {
             cachSibling = _isoProjectTree.getEditedRecord(RecordIndexTree(_isoProjectTree, sibling));
             if (cachSibling)
              for (var idx = 0; idx < options.length; idx++)
               if (cachSibling.TaskID == options[idx].ID)
                options.splice(idx, 1);
      
             sibling = NextSiblingTree(_isoProjectTree, sibling);
            }
      
            var optItems = [];
            options.forEach(function (x) { optItems.push(x.ID) })
      
            var obj = {
             _constructor: "AdvancedCriteria",
             operator: "and",
             criteria: [ { fieldName: "ID"   , operator: "inSet" , value: optItems } ]
            }
      
            return obj;
            //return { Level: _isoProjectTree.getEditedRecord(_isoProjectTree.getEventRow()).RefDesLevel };
           },
           sortField: "SortOrder"
         },
         autoFetchData: false, canFilter: true, filterLocally: true                   },
        { name: "IDSortOrder"    , title: "Internal Order" , width:  30, canEdit: false, hidden: false , cellAlign: "right" },
        { name: "ID"              , title: "ID"             , width:  30, canEdit: false, hidden: true , cellAlign: "right"                                                             },
        { name: "StartDatePlanned", title: "Start Date"     , width: 100, canEdit: true ,                cellAlign: "center", align: "center",
         type: "date", changed: "CalcProjectOnSite(this)" }, //, formatCellValue: function (value, record, rowNum, colNum) { return DateFormatter(value, record, rowNum, colNum, this); }  },
        { name: "EndDatePlanned"  , title: "End Date"       , width: 100, canEdit: true                , cellAlign: "center", align: "center",
         type: "date", changed: "CalcProjectOnSite(this)" , formatCellValue: function (value, record, rowNum, colNum) { return DateFormatter(value, record, rowNum, colNum, this); }  }, //emptyCellValue: function () { return TestEmpty('_isoProjectTree', 'EndDate'  ); } },
        { name: "OnSite"          , title: "On-Site Days"   , width: 100, canEdit: false               , cellAlign: "right" , align: "center",
         changed: "ProjectRollUp(this, 'Duration'     )"                                                                                                                             },
        { name: "EstimatedHours"  , title: "Est. Hours"     , width:  90, canEdit: true                , cellAlign: "right" , align: "center",
         changed: "ProjectRollUp(this, 'EstmatedHours')"                                                                                                                             },
        { name: "RemainingHours"  , title: "Remaining Hours", width:  30, canEdit: false, hidden: true                                                                                  },
        { name: "Editable"        , title: "Allow Edit"     , width:  30, canEdit: false, hidden: false, type: "boolean", canToggle: false                                              },
        { name: "Travel"          , title: "Travel"         , width:  30, canEdit: false, hidden: true },
        { name: "RefDesLevel"     , title: "Tree Level"     , width:  30, canEdit: false, hidden: true }
       ],
       cellContextClick: "return ShowTaskCM(rowNum,colNum)",
       contextMenu: _TaskContextNoSelectionMenu,
       getCellCSSText: "CellStyleTree (this, record, rowNum, colNum)",
       canEditCell: function (rowNum, colNum) { return ProjectCellCanEdit(rowNum, colNum, this); }
      });
      
      
      //  Sets the Sort Order for the user's selection
      function ProjectTree_Changed(cell) {
       var rowNum   = cell.rowNum;
       var record   = _isoProjectTree.getEditedRecord(rowNum);     //_isoConfigTree configTreeData    _isoDsConfig
       var level    = record.RefDesLevel;
       var taskId   = record.TaskID
       var taskData = _dsTaskList.cacheData;
       var task;
      
       record = RecordByIdTree(_isoProjectTree, record, 'ID');
       for (var i = 0; i < taskData.length; i++) {
        task = taskData[i];
        if (task.Level == level && task.ID == taskId) {
         record.IDSortOrder = task.SortOrder;
        }
       }
      
       _isoProjectTree.markForRedraw();
       _isoProjectTree.sort('IDSortOrder', 'ascending');
       _isoProjectTree.markForRedraw();
      }

      Comment


        #4
        For obvious reasons, we can't run this code. There is nothing obvious wrong with the simple call to sort(), although the markForRedraw() calls are unnecessary.

        We would again recommend checking the Developer Console for errors, and applying similar code to samples, where you should see that it works fine.

        Comment


          #5
          I have found that my problem occurs with added nodes. If the nodes are existing at initial loading, the sort works. If the nodes are added after the initial loading, they are not sorted. I am specifying a DataSource (isc.DataSource.create), a Tree (isc.Tree.create), and the TreeGrid (isc.TreeGrid.create).
          When I perform the node insert, I am inserting it into the TreeGrid.getData() specifying the parent. The node appears under the correct parent, but the sort has no effect. Where am I going wrong?

          Comment


            #6
            The set of steps here isn't really clear. If you are having the TreeGrid use a DataSource to fetch the initial set of nodes (via eg fetchData() or autoFetchData:true) then trying to directly modify the tree via add() calls, that's invalid: the TreeGrid creates a ResultTree, and the correct way to add new nodes to a ResultTree is to use DataSource.updateCaches(). If you are simply building your own Tree from data from DataSource.fetchData(), then modifying it via add() calls, this should work fine, and if it doesn't appear to be, we'd need a test case showing the issue.

            Comment


              #7
              I have narrowed my problem down to the editing of existing data. For some reason, the first edit is working, but subsequent edits do not work. I’ve attached a sample to illustrate the behavior I am seeing. Can you point me in the correct direction as to why only my first edit is working?
              Perform the following steps:
              1. Double click “Unit 4” (row 6) and select “Unit 1”. The “Internal Order” (IDSortOrder) is changed to 1 and the tree is correctly sorted.
              2. Double click “General Work” (row 4) and select “Unit 3”. The “Internal Order” (IDSortOrder) is unchanged subsequently no change in the sorting.
              TreeSort.html

              Thanks,
              Paul

              Comment


                #8
                This file is nowhere near a minimal test case and also isn't runnable, so we've just scanned it looking for obvious problems, and we notice that in ProjectTree_Changed, you directly update record data (not OK; use DataSource.updateCaches()) and also update the underlying record regardless of whether the TreeGrid is tracking (not OK - need to check whether there are editValues and update them if so) and finally, it's not clear if you might be modifying the result of getEditedRecord(), which is a copy, and hence wouldn't affect the tree data at all.

                Comment


                  #9
                  I started my test case with the application and forgot I was referencing an external utilities file. I’ve corrected that situation, so it is event longer. The problem is in the ProjectTree_Changed function. I am getting the edited record and using the IDs to get the Tree record. I am setting a field value, SortOrder. I added a call to DataSource.updateCaches(). I can quick reference (VS) DataSource, but get an error on the DataSource.updateCaches(). Is there an example on how this type of functionality is correctly performed? All references I found to DataSource.updateCaches() were for the GWT and I am using the LGPL version.


                  Code:
                  function ProjectTree_Changed(cell) {
                      var rowNum = cell.rowNum;
                      var recordSel = _isoProjectTree.getEditedRecord(rowNum);
                      var level = recordSel.RefDesLevel;
                      var taskId = recordSel.TaskID
                      var taskData = _dsTaskList.cacheData;
                      var task;
                      // Get the Tree record by using edited record's IDs
                      var record = RecordByIdTree(_isoProjectTree, _isoProjectTree.getData().root, recordSel, 'ID', 'RefDesLevel');
                      // Find the SortOrder value for the user's selection
                      for (var i = 0; i < taskData.length; i++) {
                          task = taskData[i];
                          if (task.Level == level && task.ID == taskId) {
                              // Set the desired SortOrder
                              record.IDSortOrder = task.SortOrder;
                              // I can quickwatch the DataSource, but I'm getting an error on the updateCaches(). ???
                              DataSource.updateCaches();
                              break;
                          }
                      }
                      _isoProjectTree.sort('IDSortOrder', 'ascending');
                  }
                  Thanks,
                  Paul

                  Comment


                    #10
                    See the docs for DataSource.updateCaches() - it has a required parameter, so what you're doing obviously won't work.

                    Again, we'd be happy to take a look if you can produce a minimal, ready-to-run test case seemingly showing the framework misbehaving, which should be easy by starting from a sample, if there's a framework issue here. So far all we've seen is incomplete code, and nowhere near minimal.

                    Comment


                      #11
                      I think I have followed the document you referenced. There are no error being generated, but it still is not working. The application is using three controls:
                      1. TreeGrid - isc.TreeGrid.create (ID: "_isoProjectTree")
                      2. Tree - isc.Tree.create (ID: "_projectTreeData")
                      3. DataSource - isc.DataSource.create (ID: "_isoDsProject")

                      The function ProjectTree_Changed is called by a fields changed event: changed: "ProjectTree_Changed(this)"


                      Code:
                      function ProjectTree_Changed(cell) {
                          var rowNum = cell.rowNum;
                          var recordSel = _isoProjectTree.getEditedRecord(rowNum);
                          var record = _isoProjectTree.DataSource.copyRecord(recordSel);
                          var level = record.RefDesLevel;
                          var taskId = record.TaskID;
                          var taskData = _dsTaskList.cacheData;
                          var task;
                          // Find the SortOrder value for the user's selection
                          for (var i = 0; i < taskData.length; i++) {
                              task = taskData[i];
                              if (task.Level == level && task.ID == taskId) {
                                  // Set the desired SortOrder
                                  record.IDSortOrder = task.SortOrder;
                                  break;
                              }
                          }
                          var dsResponse = {
                              data: [record],
                              operationType: "update"
                          };
                          _isoProjectTree.DataSource.updateCaches(dsResponse);
                          _isoProjectTree.sort('IDSortOrder', 'ascending');
                      }

                      Comment


                        #12
                        This part of the code, in isolation, is no longer obviously wrong, but we still have no way of investigating the problem further.

                        Comment


                          #13
                          This is the test I have been using. It’s a bit long (16K), but is taken from the application with live data.

                          TreeSort.html

                          Thanks,
                          Paul

                          Comment


                            #14
                            This may not be the real code, or if it is, there are some issues: it shows setting a "DataSource" property, whereas you would need to set the "dataSource" property instead for it to actually work.

                            Even aside from this typo, since you are directly populating your TreeGrid with a hand-created Tree data model (not a ResultTree), DataSource.updateCaches() doesn't apply.

                            So ultimately your problem is pretty simple: you are calling sort() when, as far as the TreeGrid knows, the data is already sorted - and because you aren't using a DataSource or ResultTree, updateCaches() doesn't work as a notification of data change. So the TreeGrid believes the sort is already applied and does nothing. To force a re-sort in this situation where you've manually updated the data and the TreeGrid doesn't know about it, just call resort().

                            Comment

                            Working...
                            X