Announcement

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

    Only submitting values exposed for editing in ListGrid or Datasource updateData?

    Hi,

    Is there a way to only submit to the server the values that are currently exposed for editing in a ListGrid or DynamicForm via ListGrid or Datasource updateData()?

    I have an Object that has a lot of child object that I dont' want to submit to the server every time I do an updateData.

    #2
    Probably the simplest approach is to trim off any values you don't want to transmit in datasource.transformRequest()

    Comment


      #3
      Ok, that sounds like a possibility. So, is there anyway to programmatically pass to transformRequest the fields that were open for editing in the ListGrid or DynamicForm so I wouldn't need to hard-code a list of fields that are acceptable vs unacceptable for submitting?

      Comment


        #4
        Presumably the list of acceptable and unacceptable fields could be detected from the DataSource fields, eg, fields whose type is Object or another DataSource get dropped?

        Comment


          #5
          Hi, this seems to be working fine for a DynamicForm. However, it is not working quite right for a ListGrid.

          When I call Datasource.updateData(), I am able to check all of the fields on the current record and remove those I don't want to submit in transformRequest as you suggested. However, when I call ListGrid.saveEdits(), then transformRequest is only able to inspect the fields that were edited in the ListGrid. If there are 4 fields open for editing and I only edit one of them, then dsRequest.data inside of transformRequest (and record inside of Datasource.updateData for that matter) only contains the fields that were edited. As a result, I"m not able to remove these other objects that I don't want to submit to the server. Since I can't remove them, I end up with a too much recursion error like you see below in Firefox (I wasn't able to get any useful output for this in IE.


          For now, I'm using a custom function to strip out all the child objects I don't want to submit before the ListGrid loads. But, I'd really like to be able to do this via updateData() or transformRequest() like I now can with DynamicForm. Any idea why the difference between the DynamicForm and ListGrid?

          Code:
          too much recursion
          http://localhost:8080/dev/isoversion/6.0.2/isomorphic/system/modules/ISC_Core.js?isc_version=6.0.js
          Line 291
          Here is the bottom portion of the trace in Firefox:
          Code:
          //top of this trace removed for brevity
          xmlSerialize("elem", Object analysisConfidenceID=100 analystID=8, null, Object objRefs=Object, [], [])ISC_DataBinding.j... (line 50)
          36s("activeFundAssetList", [Object analysisConfidenceID=100 analystID=8, Object analysisConfidenceID=50 analystID=9, Object analysisConfidenceID=100 analystID=8, 1 more...], ".operations[0].oldValues.fundSectorListJSON[0].activeFundAssetList[1].fundJSON.fundSectorList[0].act...", Object obj=[3523] path=[3522], null, false)ISC_DataBinding.j... (line 50)
          xmlSerialize("activeFundAssetList", [Object analysisConfidenceID=100 analystID=8, Object analysisConfidenceID=50 analystID=9, Object analysisConfidenceID=100 analystID=8, 1 more...], null, Object objRefs=Object, undefined, undefined)ISC_DataBinding.j... (line 50)
          36w("elem", Object createdUserName=Smith, Dean fundMinLongInv=1, ".operations[0].oldValues.fundSectorListJSON[0].activeFundAssetList[1].fundJSON.fundSectorList[0]", Object obj=[3523] path=[3522], null, false)ISC_DataBinding.j... (line 51)
          xmlSerialize("elem", Object createdUserName=Smith, Dean fundMinLongInv=1, null, Object objRefs=Object, [], [])ISC_DataBinding.j... (line 50)
          36s("fundSectorList", [Object createdUserName=Smith, Dean fundMinLongInv=1, Object createdUserName=Smith, Dean fundMinLongInv=1, Object createdUserName=Smith, Dean fundMinLongInv=1, 13 more...], ".operations[0].oldValues.fundSectorListJSON[0].activeFundAssetList[1].fundJSON.fundSectorList", Object obj=[3523] path=[3522], null, false)ISC_DataBinding.j... (line 50)
          xmlSerialize("fundSectorList", [Object createdUserName=Smith, Dean fundMinLongInv=1, Object createdUserName=Smith, Dean fundMinLongInv=1, Object createdUserName=Smith, Dean fundMinLongInv=1, 13 more...], null, Object objRefs=Object, undefined, undefined)ISC_DataBinding.j... (line 50)
          36w("fundJSON", Object annualizeReturnID=3 betaAdj=false companyID=3, ".operations[0].oldValues.fundSectorListJSON[0].activeFundAssetList[1].fundJSON", Object obj=[3523] path=[3522], null, false)ISC_DataBinding.j... (line 51)
          xmlSerialize("fundJSON", Object annualizeReturnID=3 betaAdj=false companyID=3, null, Object objRefs=Object, [], [])ISC_DataBinding.j... (line 50)
          36w("elem", Object analysisConfidenceID=50 analystID=10, ".operations[0].oldValues.fundSectorListJSON[0].activeFundAssetList[1]", Object obj=[3523] path=[3522], null, false)ISC_DataBinding.j... (line 51)
          xmlSerialize("elem", Object analysisConfidenceID=50 analystID=10, null, Object objRefs=Object, [], [])ISC_DataBinding.j... (line 50)
          36s("activeFundAssetList", [Object analysisConfidenceID=50 analystID=9, Object analysisConfidenceID=50 analystID=10], ".operations[0].oldValues.fundSectorListJSON[0].activeFundAssetList", Object obj=[3523] path=[3522], null, false)ISC_DataBinding.j... (line 50)
          xmlSerialize("activeFundAssetList", [Object analysisConfidenceID=50 analystID=9, Object analysisConfidenceID=50 analystID=10], null, Object objRefs=Object, undefined, undefined)ISC_DataBinding.j... (line 50)
          36w("elem", Object createdUserName=Smith, Dean fundMinLongInv=1, ".operations[0].oldValues.fundSectorListJSON[0]", Object obj=[3523] path=[3522], null, false)ISC_DataBinding.j... (line 51)
          xmlSerialize("elem", Object createdUserName=Smith, Dean fundMinLongInv=1, null, Object objRefs=Object, [], [])ISC_DataBinding.j... (line 50)
          36s("fundSectorListJSON", [Object createdUserName=Smith, Dean fundMinLongInv=1, Object createdUserName=Smith, Dean fundMinLongInv=1, Object createdUserName=Smith, Dean fundMinLongInv=1, 1 more...], ".operations[0].oldValues.fundSectorListJSON", Object obj=[3523] path=[3522], null, false)ISC_DataBinding.j... (line 50)
          xmlSerialize("fundSectorListJSON", [Object createdUserName=Smith, Dean fundMinLongInv=1, Object createdUserName=Smith, Dean fundMinLongInv=1, Object createdUserName=Smith, Dean fundMinLongInv=1, 1 more...], null, Object objRefs=Object, undefined, undefined)ISC_DataBinding.j... (line 50)
          36w("oldValues", Object createdUserName=Smith, Dean fundID=3, ".operations[0].oldValues", Object obj=[3523] path=[3522], null, false)ISC_DataBinding.j... (line 51)
          xmlSerialize("oldValues", Object createdUserName=Smith, Dean fundID=3, null, Object objRefs=Object objPath=.operations[0].oldValues, [], [])ISC_DataBinding.j... (line 50)
          36w("elem", Object criteria=Object values=Object, ".operations[0]", Object obj=[3523] path=[3522], null, false)ISC_DataBinding.j... (line 51)
          xmlSerialize("elem", Object criteria=Object values=Object, null, Object objRefs=Object objPath=.operations[0] isRoot=false, [], [])ISC_DataBinding.j... (line 50)
          36s("operations", [Object criteria=Object values=Object], ".operations", Object obj=[3523] path=[3522], null, false)ISC_DataBinding.j... (line 50)
          xmlSerialize("operations", [Object criteria=Object values=Object], null, Object objRefs=Object objPath=.operations isRoot=false, undefined, undefined)ISC_DataBinding.j... (line 50)
          36w("transaction", Object transactionNum=3 operations=[1], "", Object obj=[3523] path=[3522], null, true)ISC_DataBinding.j... (line 51)
          xmlSerialize("transaction", Object transactionNum=3 operations=[1], null, Object objRefs=Object, [], [])ISC_DataBinding.j... (line 50)
          xmlSerialize("transaction", Object transactionNum=3 operations=[1], undefined, undefined, undefined)ISC_DataBinding.j... (line 37)
          serializeTransaction(Object timeout=90000 transactionNum=3 operations=[1])ISC_DataBinding.j... (line 437)
          addTransactionToFields(Object)ISC_Core.js (line 567)
          sendHiddenFrame(Object)ISC_DataBinding.j... (line 661)
          markURLAsRPC("Saving...<br><br><img src='images/progressbar.gif'/>", "smartclient.form?isc_rpc=1&isc_v=6.0&isc_tnum=3")ISC_DataBinding.j... (line 456)
          384(Object operationType=update dataSource=FundSectorGroup)ISC_DataBinding.j... (line 410)
          performSCServerOperation(Object operationType=update dataSource=FundSectorGroup)ISC_DataBinding.j... (line 656)
          performDSOperation(Object operationType=update dataSource=FundSectorGroup)ISC_DataBinding.j... (line 299)
          performDSOperation("update", Object fundSectorGroupID=2 name=Country, "sectorGroupGrid.$337(dsResponse, dsRequest)", Object willHandleError=true showPrompt=true)ISC_DataBinding.j... (line 295)
          fetchData(Object fundSectorGroupID=2 name=Country, "sectorGroupGrid.$337(dsResponse, dsRequest)", Object willHandleError=true showPrompt=true)ISC_DataBinding.j... (line 293)
          invokeSuper(null, "updateData", undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined)ISC_Core.js (line 176)
          Super("updateData", [Object fundSectorGroupID=2 name=Country, "sectorGroupGrid.$337(dsResponse, dsRequest)", Object willHandleError=true showPrompt=true], undefined)ISC_Core.js (line 170)
          (no name)(Object fundSectorGroupID=2 name=Country, "sectorGroupGrid.$337(dsResponse, dsRequest)", Object willHandleError=true showPrompt=true)dpt.form (line 328)
          saveEditedValues(1, 0, Object fundSectorGroupID=2 name=Country, Object createdUserName=Smith, Dean fundID=3, "_0", "programmatic", "sectorGroupGridSaveCallback(success);")ISC_Grids.js (line 752)
          saveEdits("programmatic", "sectorGroupGridSaveCallback(success);", 1, undefined)

          Comment


            #6
            dsRequest.oldValues contains the original values, so you are still sending the complete data you were trying to avoid previously. You can trim these too in transformRequest(), identically to how you currently trim dsRequest.data.

            While it's true that a grid sends only updated values as dsRequest.data by default whereas a form sends all values, in both cases we would expect that you'd have trim oldValues.

            If it seems to be working for a form, it may because you are calling dataSource.updateData() directly rather than letting the form do so via form.saveData(). The oldValues are only automatically incorporated into the request if saveData() is called, otherwise you'd need to add them yourself.

            Comment


              #7
              Thanks! That did the trick.

              Now, I am noticing a new behavior that looks like a bug in Firefox that I figured I should point out to you.

              I tried to edit a ListGrid cell and then it failed server-side validation. Then, the value I tried to enter was still present in the cell so I typed in the value that was there prior to my edit and then attempted to fire ListGrid.saveEdits(). In IE, the cell simply closed and no save occurred since there were no changes. However, the same behavior in Firefox caused a too much recursion error like this:

              too much recursion
              http://localhost:8080/dev/isoversion/6.0.2/isomorphic/system/development/ISC_Core.js?isc_version=6.0.js
              Line 309


              Here is the code that Firebug is pointing to for this error:
              return _1},isc.A.findIndex=function(_1,_2){return this.findNextIndex(0,_1,_2)},isc.A.findNextIndex=function(_1,_2,_3,_4){if(_1==null)_1=0;else if(_1>=this.length)return-1;if(_4==null)_4=this.length-1;if(_2==null)return-1;if(isc.isA.String(_2)){for(var i=_1;i<=_4;i++){if(this[i]&&this[i][_2]==_3)return i}


              Here is what was output to the console for this interaction:

              Code:
              21:00:30.159:MUP9:INFO:gridEdit:sectorGroupGrid:validateFieldValue, newValue: "Country12", passed validation: true, resultingValue: undef
              21:00:30.191:MUP9:INFO:gridEdit:sectorGroupGrid:saveEdits: no actual change, not saving
              21:00:30.191:MUP9:INFO:gridEdit:sectorGroupGrid:creating new edit values for row: 1
              21:00:30.191:MUP9:INFO:gridEdit:sectorGroupGrid:creating new edit values for row: 1
              
              .......MANY MANY ROWS OF THIS
              
              for row: 1
              21:00:32.472:MUP9:INFO:gridEdit:sectorGroupGrid:creating new edit values for row: 1
              21:00:32.488:MUP9:INFO:gridEdit:sectorGroupGrid:creating new edit values for row: 1
              21:00:32.519:MUP9:INFO:gridEdit:sectorGroupGrid:creating new edit values for row: 1
              21:00:32.534:MUP9:INFO:gridEdit:sectorGroupGrid:creating new edit values for row: 1
              21:00:32.566:MUP9:INFO:gridEdit:sectorGroupGrid:creating new edit values for row: 1
              21:00:32.581:MUP9:INFO:gridEdit:sectorGroupGrid:creating new edit values for row: 1
              21:00:32.613:MUP9:INFO:gridEdit:sectorGroupGrid:creating new edit values for row: 1
              21:00:32.628:MUP9:INFO:gridEdit:sectorGroupGrid:creating new edit values for row: 1
              21:00:32.659:MUP9:INFO:gridEdit:sectorGroupGrid:creating new edit values for row: 1
              21:00:32.675:MUP9:INFO:gridEdit:sectorGroupGrid:creating new edit values for row: 1
              21:00:32.706:MUP9:INFO:gridEdit:sectorGroupGrid:creating new edit values for row: 1
              21:00:32.738:MUP9:INFO:gridEdit:sectorGroupGrid:creating new edit values for row: 1
              21:00:32.753:MUP9:INFO:gridEdit:sectorGroupGrid:creating new edit values for row: 1
              21:00:32.784:MUP9:INFO:gridEdit:sectorGroupGrid:creating new edit values for row: 1
              21:00:32.800:MUP9:INFO:gridEdit:sectorGroupGrid:creating new edit values for row: 1
              21:00:32.831:MUP9:INFO:gridEdit:sectorGroupGrid:creating new edit values for row: 1
              21:00:32.847:MUP9:INFO:gridEdit:sectorGroupGrid:creating new edit values for row: 1
              21:00:32.878:MUP9:INFO:gridEdit:sectorGroupGrid:creating new edit values for row: 1
              21:00:34.066:MUP9:WARN:Log:InternalError: too much recursion

              Comment


                #8
                Hi again
                Thanks for the info.
                Its not immediately obvious what could be causing this, but we'd very much like to get to the bottom of it.
                Could you provide us with some more details?

                - can you enable "debug" level logging for the category "gridEdit", re-run the test case, and send us whatever gets logged in the results pane of the developer console?
                - If you can get a stack trace from the error this would be helpful. If you can get the bug to occur on IE this will show up in the developer console automatically -- if it's firefox only, you can get stack traces using Firebug.

                Of course the most reliable way for us to figure out the error would be to have a standalone test-case we can run on our end to see the error. Is there any chance you could put one together for us? Tips on how to do this are included in the debugging topic of the SmartClient Reference.


                Thanks for your help

                Isomorphic Software

                Comment


                  #9
                  Ok, I was able to recreate it in the SDK. I've pasted in the JSP I modified in the SDK. Follow these steps to recreate in Firefox.

                  1.Select Employee Datasource
                  2.Edit the Employee ID of the first record and change the value to a string
                  3.Click the Save button below that has been modified to call boundList.saveEdits()
                  4. It will fail validation, now manually type 4 back into the Employee ID cell to try to set it back to the original value
                  4. Click Save again
                  5. It seems to hang now but you can still edit the field, type in a string again and click Save again
                  6. You should get the too much recursion error now in Firefox.

                  Let me know if you have any troubles recreating.

                  Code:
                  <!--------------------------------------------------------------------
                      SmartClient SDK
                      Component Data Binding example
                  
                      Copyright 2001-2007 Isomorphic Software, Inc. (www.isomorphic.com)
                  ---------------------------------------------------------------------->
                  
                  <%@ taglib uri="/WEB-INF/iscTaglib.xml" prefix="isomorphic" %>
                  <HEAD><TITLE>
                          SmartClient SDK - Component Data Binding example
                  </TITLE></HEAD><isomorphic:loadISC skin="SmartClient"/>
                  <BODY BGCOLOR=#D3D3D3><SCRIPT>
                  
                  
                  // load datasources
                  <isomorphic:loadDS ID="supplyItem" />
                  <isomorphic:loadDS ID="employees" />
                  <isomorphic:loadDS ID="animals" />
                  
                  
                  // create clickable list of datasources
                  //    This is a good example of a small, read-only list of data for which
                  //    it is appropriate to set the listGrid.data property directly.
                  ListGrid.create({
                      ID:"dsList",
                      left:20, top:75, width:130,
                      leaveScrollbarGap:false,
                      showSortArrow:"none",
                      canSort:false,
                      fields:[
                          {title:"Select a DataSource", name:"dsTitle"}
                      ],
                      data:[
                          {dsTitle:"Animals", dsName:"animals"},
                          {dsTitle:"Office Supplies", dsName:"supplyItem"},
                          {dsTitle:"Employees", dsName:"employees"}
                      ],
                      selectionType:"single",
                      recordClick:"bindComponents(record.dsName)"
                  });
                  
                  
                  // bind components to the selected datasource, and execute
                  // a fetch operation with no criteria to populate the boundList
                  function bindComponents(ds) {
                      boundList.setDataSource(ds);
                      boundViewer.setDataSource(ds);
                      boundForm.setDataSource(ds);
                      boundList.fetchData();
                      newBtn.enable(); // can't create a new record until a datasource is selected
                      saveBtn.disable(); // no record selected for editing, so disable save button
                  }
                  
                  
                  // create ListGrid, DetailViewer, & DynamicForm components to bind to datasources
                  // (nested inside a VStack to manage layout)
                  VStack.create({
                      left:170, top:75,
                      width:"70%",
                      membersMargin:20,
                      members:[
                  
                          Label.create({
                              ID:"helpText",
                              contents:"<ul>" +
                                  "<li>select a datasource from the list at left to bind to these components</li>" +
                                  "<li>click a record in the grid to view and edit that record in the form</li>" +
                                  "<li>click <b>New</b> to start editing a new record in the form</li>" +
                                  "<li>click <b>Save</b> to save changes to a new or edited record in the form</li>" +
                                  "<li>click <b>Clear</b> to clear all fields in the form</li>" +
                                  "<li>click <b>Filter</b> to filter (substring match) the grid based on form values</li>" +
                                  "<li>click <b>Fetch</b> to fetch records (exact match) for the grid based on form values</li>" +
                                  "<li>double-click a record in the grid to edit inline (press Return, or arrow/tab to another record, to save)</li>" +
                                  "</ul>"
                          }),
                  
                          // databound ListGrid
                          //   * click records to edit in boundForm and view in boundViewer
                          //   * double-click record to edit inline (Return or arrow/tab off current row to save)
                          ListGrid.create({
                              ID:"boundList",
                              height:200,
                              canEdit:true,
                              recordClick:"boundForm.editRecord(record); saveBtn.enable(); boundViewer.viewSelectedData(boundList)"
                          }),
                  
                          // databound DynamicForm
                          //   * click boundList records to edit
                          DynamicForm.create({
                              ID:"boundForm",
                              numCols:"6",
                              autoFocus:false
                          }),
                  
                          // toolbar to perform various actions using the boundForm values (see helpText above)
                          Toolbar.create({
                              autoDraw:false,
                              membersMargin:10,
                              buttonConstructor: "IButton",
                              height: 22,                               
                              buttons:[
                                  // click can be defined as a function or a string of script to execute.
                                  {title:"Save", click: function () {
                                                      boundList.saveEdits();
                                                  }, 
                                   ID:"saveBtn", disabled:true},
                                  {title:"New", click:"boundForm.editNewRecord(); saveBtn.enable()", ID:"newBtn", disabled:true},
                                  {title:"Clear", click:"boundForm.clearValues(); saveBtn.disable()"},
                                  {title:"Filter", click:"boundList.filterData(boundForm.getValuesAsCriteria()); saveBtn.disable()"},
                                  {title:"Fetch", click:"boundList.fetchData(boundForm.getValuesAsCriteria()); saveBtn.disable()"}
                              ]
                          }),
                          
                          // databound DetailViewer
                          //   * click boundList records to display
                          DetailViewer.create({
                              ID:"boundViewer"
                          })
                      ]
                  });
                  
                  
                  
                  </SCRIPT>
                  </BODY></HTML>

                  Comment


                    #10
                    Hi Senordhuff
                    I'm still not reproducing this, even with the attached example.
                    However - one thing to note here is that you're editing the primary key field of an existing record which is not going to be supported - if you really need to change primary key on an existing record you're essentially going to need to remove and then re-add the record in question.
                    Also this is a hierachical dataSource, so by dropping the root element you're going to break the tree hierachy if you then attempt to display the data in a treeGrid.

                    Are you actually encountering this error in a real usage in your application?

                    Thanks
                    Isomorphic Software

                    Comment

                    Working...
                    X