Announcement

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

    ListGrid.hasChanges() returns true when grid has no updated fields

    Hi

    I use following code to update ListGrid row via form:

    Code:
    grid.addRecordClickHandler(new RecordClickHandler() {  
       public void onRecordClick(RecordClickEvent event) {
          editRowNumber = event.getRecordNum();
          editForm.editRecord(grid.getEditedRecord(editRowNumber));
       }  
    });  
    
    ....
        
    saveButton.addClickHandler(new ClickHandler(){
       @Override
       public void onClick(ClickEvent event) {
          grid.setEditValues(editRowNumber, editForm.getValues());
          grid.endEditing();
       }
    });
    I change old value to new one, save record to grid. Updated cell becomes highlighted with blue font color.
    Then I update the same field from new value to old one and save record to grid again.
    The updated cell in grid is not marked as updated any more.

    However grid.hasChanges() still returns true. And when I call grid.saveAllEdits() I get update request on server where <data> and <oldValues> are equal.

    Is it correct?

    #2
    That sounds wrong, but we need a way to reproduce the problem (minimal, ready-to-run code) as well as the other information the forums prompts you for.

    Comment


      #3
      Hi Isomorphic

      I use:
      SmartClient Version: SNAPSHOT_v8.3d_2012-06-12/LGPL Development Only (built 2012-06-12)
      Browsers: IE8, Firefox 10.0.2

      I created test example based on this showcase
      http://www.smartclient.com/smartgwt/showcase/#grid_editing_mass_update
      and found even more strange behavior of hasChanges() method that I can’t understand. Could you please check it?

      Code:
      public class TestGridHasChanges implements EntryPoint {
      
      	int editRowNumber = -1;
      
      	public void onModuleLoad() {
      
      		Canvas canvas = new Canvas();
      
      		final DynamicForm form = new DynamicForm();
      		TextItem countryNameItem = new TextItem("countryName");
      		form.setItems(countryNameItem);
      		form.setHeight(30);
      		form.setWidth(500);
      
      		final ListGrid countryGrid = new ListGrid();
      		countryGrid.setWidth(500);
      		countryGrid.setHeight(224);
      		countryGrid.setCellHeight(22);
      		countryGrid.setTop(50);
      		countryGrid.setDataSource(CountryXmlDS.getInstance());
      
      		ListGridField nameField = new ListGridField("countryName", "Country");
      		ListGridField continentField = new ListGridField("continent",
      				"Continent");
      		ListGridField memberG8Field = new ListGridField("member_g8",
      				"Member G8");
      		ListGridField populationField = new ListGridField("population",
      				"Population");
      		populationField.setType(ListGridFieldType.INTEGER);
      		populationField.setCellFormatter(new CellFormatter() {
      			public String format(Object value, ListGridRecord record,
      					int rowNum, int colNum) {
      				if (value == null) {
      					return null;
      				}
      				NumberFormat nf = NumberFormat.getFormat("0,000");
      				try {
      					return nf.format(((Number) value).longValue());
      				} catch (Exception e) {
      					return value.toString();
      				}
      			}
      		});
      		ListGridField independenceField = new ListGridField("independence",
      				"Independence");
      //		independenceField.setHidden(true);
      		
      		countryGrid.setFields(nameField, continentField, memberG8Field,
      				populationField, independenceField);
      
      		countryGrid.setAutoFetchData(true);
      		countryGrid.setCanEdit(false);
      		countryGrid.setAutoSaveEdits(false);
      
              final Label label = new Label();  
              label.setHeight(30);  
              label.setContents("hasChanges = " + countryGrid.hasChanges());  
              label.setTop(350);
              label.setLeft(110);
      
      		countryGrid.addRecordClickHandler(new RecordClickHandler() {
      			public void onRecordClick(RecordClickEvent event) {
      				editRowNumber = event.getRecordNum();
      				form.editRecord(countryGrid.getEditedRecord(editRowNumber));
      		        label.setContents("hasChanges = " + countryGrid.hasChanges());  
      			}
      		});
      
      		IButton saveButton = new IButton("Save to Grid");
      		saveButton.setTop(300);
      		saveButton.setLeft(110);
      		saveButton.addClickHandler(new ClickHandler() {
      			public void onClick(ClickEvent event) {
      				countryGrid.setEditValues(editRowNumber, form.getValues());
      				countryGrid.endEditing();
      		        label.setContents("hasChanges = " + countryGrid.hasChanges());  
      			}
      		});
      
      
      		canvas.addChild(form);
      		canvas.addChild(countryGrid);
      		canvas.addChild(saveButton);
      		canvas.addChild(label);
      
      		canvas.draw();
      
      	}
      }
      Test case 1:
      1. Select any record in grid.
      2. Update “Country” item with new value.
      3. Press “Save to Grid” button:
      ---> “Country” field in current row is updated BUT font is not highlighted !!! with blue color
      ---> hasChanges = true
      4. Change “Country” item value to old one.
      5. Press “Save to Grid” button:
      ---> “Country” field in current row is updated with old value
      ---> hasChanges = false
      6. Select other records in the Grid.
      ---> hasChanges = true !!! everywhere except the row that was updated.

      Test case 2
      1. The same like in Test case 1, but update any 2 rows with new values first and then return old values back. You will find that hasChanges = true !!! always.

      I can’t continue tests while it’s not fixed. However it seems that hasChanges() always returns true after Grid was updated at least once and any of fields in Grid has setHidden(true) (or absent in grid.setFields(…)).

      Comment


        #4
        There are 2 issues here:
        1) The failure of the blue "pending" text to show up when a cell has an edit value.
        This is due to the fact that the grid is marked as canEdit:false. The edit-pending hilighting is not applied to a non-editable grid.
        You can resolve this by setting canEdit to true on the grid, and (to suppress edit on click or double-click) set EditEvent to NONE

        2) "hasChanges" returning unpredictable values.
        You can resolve this issue by modifying your code to only apply the fields that are actually present in the form as form items to the grid as edit values for the row (so in this case just the "countryName" field value).

        Background on why this makes a difference:
        The behavior you're encountering is due to the fact that when you call getEditedRecord() you're getting values for every field in the grid, and also a selection marker attribute that is attached to the record while it is selected.
        When you then allow the user to make edits and apply them back to the grid as edit values, its picking up all of these attributes (including the selection marker attribute) and storing them as edit values for the grid.
        Then 'hasChanges' is performing a comparison of the edit values against the underlying record values and returning true if it finds a difference -- so while the record is selected you have an exact match, whereas while the record is not selected the selection marker is seen as a different, unsaved edit value.
        Long term we will review this behavior and see if there's a way to make things less confusing, but regardless the correct resolution is to selectively apply the edit values you care about only.

        Regards
        Isomorphic Software

        Comment


          #5
          Hi Isomorphic
          Thank you for this detailed answer. Workarounds you propose are clear however for issue 2 it’s quite time consuming on big number of forms. I very much hope “Long term” that you mention will not be really long.

          Comment

          Working...
          X