Announcement

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

    Removing local record from listGrid without committing

    I am trying to pull up a listGrid and make changes to it and then commit all of the changes at the end. Right now I am just working on the display side and am using hard coded JS data. It appears that I can add a record and update a record without going back to the server but I can't find a delete function. The removeSelectedData() function goes directly to the server.

    On the same topic, am I going to have a problem committing changes from added and updated records? Will the saveAllEdits() function do this?

    Code:
    this.addMembers([
    			
    			isc.ListGrid.create({
    			    ID: "TPAList",
    			    width:400, height:224, alternateRecordStyles:true, showAllRecords:true,
    			    fields:[
    			        {name:"TPA", title:"TPA"}
    			    ],
    			    data: TPAData,
    			    canEdit: true,
    			    editEvent: "doubleClick"
    			}),
    			isc.HLayout.create({
    			    members:[
    					isc.IButton.create({
    					    top:250,
    					    title:"Add New",
    					    click:"TPAList.startEditingNew()"
    					})
    					,isc.IButton.create({
    					    top:250,
    					    title:"Edit",
    					    click:"TPAList.startEditing(TPAList.getRecordIndex(TPAList.getSelectedRecord()),0)"
    					})
    					,isc.IButton.create({
    					    top:250,
    					    title:"Delete",
    					    click:"TPAList.removeSelectedData()"
    					})
    			    ],
    			    autoDraw:false,
    			    width:"100%",
    			    height:"50px"
    			}),
    			
    			isc.IButton.create({
    					    top:250,
    					    title:"Commit Changes",
    					    click:"TPAList.saveAllEdits()",
    					    autoFit:"true"
    			})
            ]);
    Last edited by Wakebrad; 30 May 2007, 13:14.

    #2
    Hi Wakebrad,
    The way this is written, you don't have a dataSource specified for the ListGrid, just client-side data -- this means that as you are making edits they are being saved directly into that client-side data set (rather than attempting to hit the server at all).
    By contrast - removeSelectedData() is intended to be used with databound ListGrids only, and will delete the selected record from the DataSource (it's not influenced by the 'autoSaveEdits' property on the grid).
    If you want to remove local data, you will need to interact directly with the listGrids' data array using the Array APIs.

    saveAllEdits() is a slightly different thing:
    By default ListGrids will update their underlying data as the user naviagates around the listGrid making edits. For databound grids this means they will hit the server and perform save operations. For grids with client-only data they will simply integrate the changes into the data array.
    (This means that if you specify a dataSource in your listGird, you will find the records get saved to the server automatically when the would previously have been saved to the local data set).

    You can suppress this behavior by setting autoSaveEdits to false - in this case edits are stored as "pending edit values" on the grid rather than being integrated directly into the ListGrids underlying data. You can then call 'saveAllEdits()' [or just 'saveEdits(...)' to commit the changes the user has made to the underlying data.

    Setting autoSaveEdits to false does not alter the behavior of the removeSelectedData() method - this will still call the Datasource method to directly remove the record from the server.
    One thing worth noting is that with autoSaveEdits set to false, for newly added records that have never been saved (rather than edits to existing records), clearing the edit values for the record will completely drop the (unsaved) record [as it was never a part of the data-set for the grid].

    Hope this helps

    Thanks
    Isomorphic Software

    Comment


      #3
      Thanks, that makes sense.

      Are there any examples of working with the dataset directly using the Array APIs? I am looking at the SmartClient Reference 5.6 but don't see any examples.

      Comment


        #4
        Hi Wakebrad,
        If you want to manipulate the data in the local data array directly, having autoSaveEdits set to true means the data will automatically pick up edits the user performs via inline editing of the grid.
        The only Array APIs you'll need to call directly on the data would probably be to remove data - take a look at the docs for the extensions that are added by SmartClient to native JS Arrays.
        remove(), removeAt() and removeList() will probably give you the behavior you need.

        Also note one gotcha, if you have a databound list, the data for that list will be a ResultSet object rather than an Array. ResultSets automatically synchronize their content with their dataSource, so modifications to the dataSource data set (on the server) will automatically be reflected in the databound listGrid's resultset.
        You should not attempt to apply Array modification methods (such as removeAt()) directly to a ResultSet. Instead you should always call the appropriate APIs on the DataSource to directly manipulate the underlying data-set.

        Hope this makes sense
        Isomorphic Software

        Comment


          #5
          So if I understand you correctly once I hook this up to a datasource it will not be possible for me to delete on the local dataset without automatically updating the datasource because the local dataset will refresh with the datasource.

          Comment


            #6
            Yes, this is basically true. You can't remove records from the local data (ResultSet) of a databound listGrid directly, as this will break how it synchs up with the underlying data set of the dataSource.

            For most use cases we have found this is appropriate (in fact, in terms of UI a local 'delete' is often somewhat ambiguous).
            However if your application requires the ability to have UI to locally 'remove' records, without actually committing the changes (and then committing them later in response to a 'saveAllEdits()' call, for example), there are a couple of ways to achieve this.

            Let us know if this is what you need and we can show you how to do it.

            Thanks
            Isomorphic Software

            Comment


              #7
              Could you show us an example on how to that?

              -----
              However if your application requires the ability to have UI to locally 'remove' records, without actually committing the changes (and then committing them later in response to a 'saveAllEdits()' call, for example), there are a couple of ways to achieve this.

              Comment


                #8
                Sure.
                The basic approach we'd recommend is to have client side "delete" work by simply adding a property to the record to be removed (such as "record.markedForDelete").
                We'd also recommend applying this property as an edit value rather than a value directly on the record object.

                Obviously your choice of UI would vary but to mark a record (in this case the first row) as deleted you could therefore call:
                Code:
                myGrid.setEditValue(0, "markedForDelete", true);
                You'll probably want to have records that have been marked for deletion be visibly different from other records in the grid. Various options for this - the simplest is just to include a boolean 'markedForDelete' column in the grid which will then show checkboxes against deleted fields.
                Another option would be to display a custom style (for example strike-through text) by overriding getCellStyle() on the grid. Note that in this case you might have to refresh the styling of the row after setting the 'markedForDelete' edit value.

                The other part of the puzzle is actually committing the deletes to the server. The best thing to do here is probably to have a custom method which would iterate through all the edited rows, and just call 'dataSource.removeData()' on those records marked for deletion.

                Something like this:

                Code:
                isc.ListGrid.create({
                   ... // various props
                   
                   commitDeletes : function () {
                       var editRows= this.getAllEditRows(),
                            recordsToDelete = [];
                       for (var i = 0; i < editRows.length; i++) {
                           var record = this.getEditedRecord(editRows[i]);
                           if (record.markedForDelete) {
                               recordsToDelete.add(record);
                           }
                       }
                       // actually delete in a second loop - this avoids the
                       // rowNums getting out of date as rows are removed
                       var ds = isc.DataSource.getDataSource(this.dataSource);
                       for (var i = 0; i < recordsToDelete.length; i++) {
                           var record = recordsToDelete[i];
                           // drop edits before deleting the record from the DS
                           var rowNum = this.data.indexOf(record);
                           this.discardEdits(rowNum);
                           
                           ds.removeData(record);
                       }
                   }
                });
                Hope this all makes sense

                Thanks
                Isomorphic Software

                Comment


                  #9
                  Hi,

                  I have a requirement where I have a listgrid,associated with a datasource,
                  I should be able to do multiple seelcts from this list and should be able to delete it locally from the list. But when i call removeData , it hits the server, but I just want to remove it from the listgrid, and not from my database(server).

                  I tried using removeAt,remove() ,removeList() APi's of List , but its a databound listgrid, so am not sure if it works for it.

                  I also tried using removeData, but was not able to remove the data from local listgrid.

                  Please see gthe code I tried below.

                  DATASOURCE ::

                  isc.ListGrid.create({
                  ID:"grid2",
                  autoDraw: false,
                  dataSource: dimensionValuesDS,

                  canEdit:true,
                  editByCell: true,
                  modalEditing: true,
                  fields:
                  [
                  {name: "valueName" },
                  {name: "levelName"}
                  ],

                  selectionChanged: "deSelect1.enable()"
                  })




                  isc.IButton.create({
                  ID: "deSelect1",
                  autoDraw:"true",
                  width:"100",
                  title: "<",
                  disabled:"true",
                  click : function(){


                  for ( var x=0;x<grid2.getSelection().getLength();x++)
                  {
                  var sel= grid2.getSelection().get(x);

                  grid2.removeData(sel); //this hits the server, but I dont want t odo anything on the server side.

                  }


                  }
                  });



                  I tried using List.removeList as below.

                  isc.IButton.create({
                  ID: "deSelect1",
                  autoDraw:"true",
                  width:"100",
                  title: "<",
                  disabled:"true",
                  click : function(){


                  grid2.data.removeList(grid2.getSelection());

                  // it showed a java script error , for this line saying object doesnt support this method.

                  }
                  )};

                  Could you please help me in this case.

                  Comment


                    #10
                    Hi Kirti,

                    See the docs for DataSource.fetchData(). You can fetch data from a DataSource and supply it to a ListGrid as an ordinary JavaScript Array. At that point you can modify it directly via methods like removeList().

                    Comment


                      #11
                      local update to databound listgrid

                      Similar to how remove data could be done locally (or atleast give an illusion like local remove), is it possible to hold the edits and adds of new records to a listgrid locally?

                      The scenario is:
                      1. I have an application list grid, user list grid and role list grid all in the same page each with an add and a remove operation for each, which is supposed to do only local adds and edits.
                      2. The grids are filter search enabled.
                      3. When I complete all my edits in the page, I click on the common Save button of the page which will Save the cumulative changes made to the page.
                      4. The grids are internally linked meaning, user list will have a application column indicating to which application the user belongs to. Here when I edit or add a new user in this list, I would want the new locally added/edited application data from the application list grid....

                      I would like some guidance to do the above steps.

                      As of now I disabled autoSaveEdit by setting it to false.
                      When I add a new record and then try adding another new record or try a new filter for data, I keep getting pop-up message like "This action will discard all unsaved edited values for this list", with a OK, Save and Cancel button.

                      I do not want this pop-up, I do not want to Save the data to the persitent storage yet (until I click on the common Save button).

                      Thanks in advance.

                      Thanks
                      Shiv

                      Comment


                        #12
                        @shiv Similar to the strategy suggested for Kirti, use a clientOnly:true DataSource and set DataSource.testData to the data fetched from your actual DataSource. Once you've done a series of operations on this dataset via the grid, DataSource.testData contains the modified records (including removals and additions).

                        Comment

                        Working...
                        X