Announcement

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

    How to use DetailViewer/DynamicForm to observe changes done to their data to redraw

    Using SmartGWT 3.1p from 26.06.2013.

    I would like to know how to create a DetailViewer and a read only DynamicForm to observe the changes done through their datasource by other form.
    The PatternReuse demo shows how the ListGrid does that. I enhanced that example with a new DetailViewer and a read only DynamicForm, but without success.
    I succeeded only by adding a callback to form.saveData method and updating manually the components with new data, but that is not what I need and like.

    Is it possible without that callback and how?

    Thanks,
    Mihnea
    Attached Files

    #2
    Just like ListGrid, DetailViewer needs to have a ResultSet in order to observe changes to DataSource data. So you can either use DetailViewer.fetchData() to fetch the same record, or manually form a ResultSet from the Record you have already retrieved.

    A form will not auto-update from a save by an external component - this is normally extremely undesirable (wipes out user changes). For this special case of a read-only form, you would need to use the callback in order to refresh it.

    Comment


      #3
      Thanks. I updated the example and attached it again for further reference.

      We use read-only DynamicForm instead of DetailViewer because it provides the possibility to display the fields on multiple columns.
      Is it any plan for DetailViewer to support that?
      Attached Files

      Comment


        #4
        A read-only form is a good way to display data if you need a tabular-style layout for it, and this capability will not be added to DetailViewer.

        If you want to create a read-only form that observes data changes and refreshes the displayed record, you can do so by creating a ResultSet from the record that the form is editing, and watching the DataChanged event, then using editRecord() to refresh the form. You could encapsulate this into a reusable component if you wanted.

        Comment


          #5
          Thanks for hints.
          Could you please tell me how to create a ResultSet for the read only form to observe the changes done through the datasource. I've tried with the following code but it doesn't work. I don't know what are the minimum necessary settings for the ResultSet to do that.
          Code:
          formReadOnly.editRecord(event.getRecord());
          //formReadOnly.fetchData(new Criteria("pk", pk));
          
          final ResultSet formReadOnlyResultSet = new ResultSet(datasource);
          formReadOnlyResultSet.setID(SC.generateID("ResultSet_formReadOnly"));
          formReadOnlyResultSet.setDisableCacheSync(false);
          formReadOnlyResultSet.setCriteria(new Criteria("pk", pk));
          formReadOnlyResultSet.setFetchMode(FetchMode.LOCAL);
          formReadOnlyResultSet.setFetchOperation("fetch");
          formReadOnlyResultSet.setAllRows(new Record[]{event.getRecord()});
          formReadOnlyResultSet.addDataChangedHandler(new DataChangedHandler() {
          	
          	@Override
          	public void onDataChanged(DataChangedEvent event) {
          		SC.logWarn("formReadOnlyResultSet - onDataChanged() called");
          		if(formReadOnlyResultSet.isEmpty()){
          			formReadOnly.editNewRecord();
          		}else{
          			formReadOnly.editRecord(formReadOnlyResultSet.get(0));
          		}
          	}
          });

          Comment


            #6
            Remove all your settings except the DataSource passed on construction and setAllRows() (and of course retain the DataChangedHandler). Your setFetchOperation() makes it so the ResultSet would only listen for changes for fetches done with an operationId of "fetch".

            Comment


              #7
              It doesn't work. I used the code you suggested:
              Code:
              final ResultSet formReadOnlyResultSet = new ResultSet(datasource);
              formReadOnlyResultSet.setAllRows(new Record[]{event.getRecord()});
              formReadOnlyResultSet.addDataChangedHandler(new DataChangedHandler() {
              	
              	@Override
              	public void onDataChanged(DataChangedEvent event) {
              		SC.logWarn("formReadOnlyResultSet - onDataChanged() called");
              		if(formReadOnlyResultSet.isEmpty()){
              			formReadOnly.editNewRecord();
              		}else{
              			formReadOnly.editRecord(formReadOnlyResultSet.get(0));
              		}
              	}
              });
              but for DetailViewer this code works well:
              Code:
              ResultSet resultSet = new ResultSet(datasource);
              resultSet.setAllRows(new Record[]{event.getRecord()});                    
              detailViewer.setData(resultSet);
              Last edited by mpretorian; 27 Jun 2013, 13:36.

              Comment


                #8
                Could you elaborate on "it doesn't work"?

                Comment


                  #9
                  The read only form is not refreshed when the other writable form executes an update operation on the common displayed record.
                  I have attached previously the showcase example and the new code. I attached again the whole java file that you can test yourself and the console log file with ResultSet on DEBUG level where you can see that there is no log entry for the instance "ResultSet_formReadOnly". That instance is not notified of the update like the other two isc_ResultSet_0 and isc_ResultSet_detailViewer_0.
                  Attached Files

                  Comment


                    #10
                    The usage is now correct, the problem turned out to be that the underlying SmartClient ResultSet is not created by this series of calls. A manual call to getOrCreateJSObj() would fix it; in tomorrow's nightlies this series of calls will handle it automatically.

                    Comment


                      #11
                      Thank you. With the smartgwt-3.1p.2013-06-30 it worked well.
                      Btw, I find pretty useful and interesting the ResultSet features that observer the datasource changes.
                      A demo that shows them, like the one I attached based on PatternReuseSample would be very good.
                      Best regards,
                      Mihnea

                      Comment


                        #12
                        We had to adjust how this is handled because it introduced other, subtler issues. You should now call the new ResultSet.ensureCreated() API in this scenario (and the need for this call is now documented on ResultSet).

                        This is required only for a scenario like yours, where a ResultSet is being created but is not provided to a component, asked to fetch data, or anything else that would make its creation automatic and implied.

                        Comment


                          #13
                          Used smartgwt-3.1p-2013-07-07.

                          I tested also with ResultSet.ensureCreated() and it works well.
                          See the attached file.

                          Thanks,
                          Mihnea
                          Attached Files

                          Comment

                          Working...
                          X