Announcement

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

    ListGrid does not re-sort on updated records

    I am using a ListGrid with a data source and I am updating records in the list based on events from the server. When I update fields that are used to sort the ListGrid, the values displayed in the ListGrid change, but the rows do not move to their new sort positions.

    Is there something I have to do to make the grid re-sort when records are changed?

    Here's my update code:

    Code:
    public static void updateListGridRecord(ListGrid grid, String primaryKeyField, Map<String, Object> properties) {
    	Record oldRecord = findOldListGridRecord(grid, properties.get(primaryKeyField), primaryKeyField);
    	if( oldRecord == null ) {
    		return; // no old record; no need to update
    	}
    		
    	updateListGridRecord(grid, oldRecord, properties);
    }
    
    protected static Record findOldListGridRecord(ListGrid grid, Object recordId, String primaryKeyField) {
    	ResultSet resultSet = (grid.isGrouped() ? grid.getOriginalResultSet() : grid.getResultSet());
    	Record record = null;
    	if( resultSet != null ) {
    		record = resultSet.find(primaryKeyField, recordId.toString());
    	}
    	return record;
    }
    
    private static void updateListGridRecord(ListGrid grid, Record oldRecord, Map<String, Object> properties) {
    	Record record = new ListGridRecord(oldRecord.getJsObj());
    	for( String key: properties.keySet() ) {
    		record.setAttribute(key, properties.get(key));
    	}
    
    	updateCache(grid, record, DSOperationType.UPDATE);
    }
    
    protected static void updateCache(ListGrid grid, Record record, DSOperationType opType) {
    	DataSource dataSource = grid.getDataSource();
    		
    	DSRequest request = new DSRequest();
    	request.setOperationType(opType);
    	request.setDataSource(dataSource.getID());
    
    	DSResponse carrier = new DSResponse();
    	carrier.setData(new Record[]{record});
    	dataSource.updateCaches(carrier, request);
    }

    #2
    Calling sort() will do it.

    Comment


      #3
      Calling sort() on the grid causes it to sort by the first sortable column, which isn't what I want. I want the grid to re-sort based on the current sorting criteria.

      I don't know if it matters, but I'm using a multi-column sort (by calling setSort(SortSpecifier[])) and I have setCanSort(false) to prevent the user from changing the sort order.

      Comment


        #4
        Sorry, to clarify, you want to call the signature of sort() that takes specifiers, re-iterating your current specifiers.

        Comment


          #5
          I'm using a multi-column sort, and there doesn't appear to be a version of sort() that can specify a multi-column sort. These are the versions of sort that I see:

          Code:
              /**
               * Sort the the data  by the first sortable column.
               * <P>&#010 Updates the sortFieldNum and sortDirection to reflect the new sort order of the grid.&#010&#010
               *
               * @return sorting worked
               */
              public native Boolean sort() /*-{
                  var self = this.@com.smartgwt.client.widgets.BaseWidget::getOrCreateJsObj()();
                  var retVal =self.sort();
                  if(retVal == null || retVal === undefined) {
                      return null;
                  } else {
                      return @com.smartgwt.client.util.JSOHelper::toBoolean(Z)(retVal);
                  }
              }-*/;
          
              /**
               * Sorts a listGrid explicitly by the column given by sortFieldNum, if provided, in &#010 ascending or descending order if specified by sortDirection. If sortFieldNum is not&#010 provided and listGrid.sortFieldNum is undefined, the data will be sorted by the first&#010 sortable column according to {@link com.smartgwt.client.widgets.grid.ListGridField#getSortDirection sortDirection} if specified, or&#010 {@link com.smartgwt.client.widgets.grid.ListGrid#getSortDirection sortDirection}.&#010 <P>&#010 Updates the sortFieldNum and sortDirection to reflect the new sort order of the grid.&#010&#010
               *
               * @param sortField     the field name to sort by
               * @param sortDirection the direction to sort in
               * @return sorting worked
               */
              public native Boolean sort(String sortField, SortDirection sortDirection) /*-{
                  var self = this.@com.smartgwt.client.widgets.BaseWidget::getOrCreateJsObj()();
                  var retVal =self.sort(sortField, sortDirection.@com.smartgwt.client.types.SortDirection::getValue()());
                  if(retVal == null || retVal === undefined) {
                      return null;
                  } else {
                      return @com.smartgwt.client.util.JSOHelper::toBoolean(Z)(retVal);
                  }
              }-*/;
          
              /**
               * Sorts a listGrid explicitly by the column given by sortFieldNum, if provided, in &#010 ascending or descending order if specified by sortDirection. If sortFieldNum is not&#010 provided and listGrid.sortFieldNum is undefined, the data will be sorted by the first&#010 sortable column according to {@link com.smartgwt.client.widgets.grid.ListGridField#getSortDirection sortDirection} if specified, or&#010 {@link com.smartgwt.client.widgets.grid.ListGrid#getSortDirection sortDirection}.&#010 <P>&#010 Updates the sortFieldNum and sortDirection to reflect the new sort order of the grid.&#010&#010
               *
               * @param sortCol the column number to sort by
               * @param sortDirection the direction to sort in
               * @return sorting worked
               */
              public native Boolean sort(int sortCol, SortDirection sortDirection) /*-{
                  var self = this.@com.smartgwt.client.widgets.BaseWidget::getOrCreateJsObj()();
                  var retVal =self.sort(sortCol, sortDirection.@com.smartgwt.client.types.SortDirection::getValue()());
                  if(retVal == null || retVal === undefined) {
                      return null;
                  } else {
                      return @com.smartgwt.client.util.JSOHelper::toBoolean(Z)(retVal);
                  }
              }-*/;
          Is it possible to get the grid to re-sort by multiple columns?

          Comment


            #6
            http://www.smartclient.com/smartgwt/...ecifier&#91;])?

            Comment


              #7
              I don't know if I'm missing something totally obvious, but I'm not getting it to work. Calling grid.setSort() was actually what I was trying before I started this thread. Here's what I'm now doing on an update:


              Code:
              public static void updateListGridRecord(ListGrid grid, String primaryKeyField, Map<String, Object> properties) {
              	Record oldRecord = GridUtils.findOldListGridRecord(grid, properties.get(primaryKeyField), primaryKeyField);
              	if( oldRecord == null ) {
              		return; // no old record; no need to update
              	}
              		
              	updateListGridRecord(grid, oldRecord, properties);
              		
              	SortSpecifier[] sorts = grid.getSort();
              	grid.setSort(sorts);
              }
              But the grid still does not sort. I can see the (sorted) fields changing in the grid, but they stay in the same order.

              I have tried changing the sort specification slightly (changing the precedence of the columns in the sort) and I get mixed results. Sometimes it sorts. Sometimes it doesn't. Sometimes the item moves in the list, but to the wrong position.

              When I just call grid.setSort(grid.setSort()) nothing happens.

              I also tried adding a button to the application so I can call grid.setSort(grid.getSort()) at any time, just to see if it might be a timing issue, but this appears to have no effect.

              Is there something else I'm missing?

              Comment


                #8
                Okay...I've been playing with this a little more, and it looks as though it may not be an issue with re-sorting, but rather an issue with how I'm updating data when I get an event.

                I'm sorting on a numeric (Long) column, and I have three rows. The values in the rows are:

                Code:
                1326400909715
                1326402709715
                1326403109715
                Then, I get an event, and I change the value in the last row from 4031 to 3991. This should cause it to move to the top of the list, but it does not. It just changes to 3991 in place, and my list looks like this:

                Code:
                1326400909715
                1326402709715
                1326399109715
                This is clearly out of order. If I click on the column header and switch to sorting DESCENDING, it changes to this:

                Code:
                1326399109715
                1326402709715
                1326400909715
                If I click again to switch back to ASCENDING, it looks like this again:

                Code:
                1326400909715
                1326402709715
                1326399109715
                It appears that I have updated the data that appears in the grid but the old value is still in some layer behind the UI and the old value is being used for sorting.

                If I re-load the data from the server (through the data source) the values sort correctly.

                Is my update code incorrect? Is there another layer that I also need to update? Is there a problem with using Long values with DataSourceIntegerField?

                Comment


                  #9
                  Okay, I think there are two issues here.

                  First, the behavior I mentioned in my last post, where the sorting seems to be using the previous value, only happens if I put the value from the server in an Integer field. If I put it in a String field, the sorting works correctly and it uses the updated values for sorting.

                  Second, the grid does not sort if I call grid.setSort(grid.getSort()). It only appears to sort if I actually change the sort criteria to something new. This code DOES cause the grid to re-sort correctly:

                  Code:
                  SortSpecifier[] sorts = grid.getSort();
                  grid.setSort(new SortSpecifier[0]);
                  grid.setSort(sorts);
                  So I have two questions:

                  1. Is the code above correct? Should I have to clear the sort and set it again to get the grid to re-sort?

                  2. Is there a way to handle Long values as numeric in ListGrid?

                  Comment


                    #10
                    1. yes that's correct code to force a re-sort if you've directly modified data so that no automatic detection is possible. We're adding an official resort() API to simplify this.

                    2. there's no general problem with sorting numeric values (as can be seen in countless Showcase samples). Your results suggest a problem with how you're delivering the data. We noticed elsewhere you're using GWT-RPC and it's likely that something in your GWT-RPC implementation is causing this issue - have you seen the FAQ about what a bad idea GWT-RPC is?

                    Comment


                      #11
                      You mention that automated detection is not possible because I have modified the data directly.

                      Is there a different way that I should be performing the updates so the automatic detection works properly?

                      Comment


                        #12
                        ListGrid.updateData() is one way to make a change which will be detected and will cause automatic consequences such as refreshing the display. However as far as sorting, bear in the mind that the ListGrid has an automatic behavior of not sorting right after an update, and this is by design: it prevents records from popping mysteriously out of the viewport when they are modified.

                        Comment

                        Working...
                        X