Announcement

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

    trouble with form.getChangedValues()

    I am creating log entries when saving my forms using getOldValues and getChangedValues. It works for many formitems. However, I am having trouble getting some new values displayed on the form when the SAVE button is clicked. These are selectItems using the valueField/displayField scheme where the former has a key value and the latter is looked up.

    Having the name of the field (fname) I can get the Old value ok using the result of getDisplayFieldName(fname) and to look in getOldValues. But, that does not work in getChangedValues. Nor does form.getItem(fname).getDisplayValue(). It just returns the key value.

    Any clues how to get a value I can see with my eyes?

    I will, of course, keep looking. But, it is not obvious to me.

    Thanks,

    Rick

    P.S. I am running SmartClient Version: v8.2p_2013-01-14/EVAL Development Only on Mozilla Firefox 12.0 with Firebug using Windows XP Pro 32 bit.

    #2
    The form doesn't track the display value for the prior stored value. If you need it client-side, you would need to retrieve it from the server via doing a fetch against the optionDataSource.

    Comment


      #3
      Hello. I appreciate the quick weekend reply.

      I either disagree or don't understand. Here is my dump of old values etc.
      Code:
      13:01:22.741:MUP5:DEBUG:Log:********************** TaskForm.SaveButton.Click
      13:01:22.871:MUP5:DEBUG:Log:************** taskform.getOldValues {ProjectTitle: "SSN Suppression on checks for Universal ..."[54],
      Description: "This issue was received from Universal M..."[155],
      CommunityID: 101,
      TaskID: 101,
      TaskTitle: "Send reply email",
      TaskDueDate: Date(01/23/2013),
      TaskNumber: 1,
      IssueStatus: "Open",
      IssueID: 101,
      IssueTitle: "Off-cycle checks - problem with SSN fiel..."[54],
      IssueNumber: 1,
      IssueOwner: "Richard Bollinger",
      ProjectNumber: "7633",
      Log: "02/23/2013 12:05: Owner changed from Vic..."[168],
      Created: Date(02/23/2013),
      IssueImpact: "4-Serious",
      Modified: Date(02/23/2013),
      TeamMemberName: "Richard Bollinger",
      TaskStatus: "Open",
      OwnerID: 101,
      LogEntry: "02/23/2013 12:05: Owner changed from Vic..."[79],
      OriginalDueDate: Date(02/01/2012),
      ProjectID: 101,
      _selection_21: true}
      13:01:22.873:MUP5:DEBUG:Log:************** taskform.getChangedValues {OwnerID: 102}
      13:01:22.877:MUP5:DEBUG:Log:************** taskform oldValues[fname] 101
      13:01:22.877:MUP5:DEBUG:Log:************** taskform newValues[fname] 102
      13:01:22.878:MUP5:DEBUG:Log:************** new value should be 102
      It has my OwnerID: 101, and TeamMemberName: "Richard Bollinger". So, my log entry becomes
      Task# 2 updated 02/23/2013 12:29: Owner changed from Richard Bollinger to undefined
      That last line should read "*** new value should be Vicki Spencer". Her ID is 102.

      So, that means the old display value is client-side. And, I have to believe if I can see it, the new value should be client-side. Somewhere. I just don't know where.

      Thanks,

      Rick

      Comment


        #4
        Try using the SelectItem.getSelectedRecord() API ...

        Comment


          #5
          Hi Richard. Thanks for weighing in on my problem. I haven't yet been able to get at the selectitem. But, I am still working on it.

          I am so very close, it is frustrating. The framework goes to so much trouble to get and display the name while working with the key. It is hard to believe that value is discarded.

          I wonder if this has reached the level of some sort of bug. I just looked at the docs. It says
          any FormItem.getDisplayValue() ([value])

          Returns this item's value with any valueMap applied to it - the value as currently displayed to the user.
          Certainly the attached shows what is currently displayed to the user. And, it's not the key value.

          Rick
          Attached Files
          Last edited by RickBollinger; 23 Feb 2013, 13:12. Reason: new info

          Comment


            #6
            Hi Rick
            We're not clear on what the problem is here.
            To clarify the APIs in question:
            - getOldValues() will show you the entire set of values for the form when they were last "remembered" - typically this occurs when editRecord() or setValues() was called on the form so they're the unedited values.
            - getValues() of course returns the current values for the form
            - getChangedValues() shows you a sparse object containing only the changes between the old and the new values

            - formItem.getValue() shows you the current (data) value
            - formItem.getDisplayValue() shows you the current display value -- so that's the data value with any specified valueMap applied to it to get the value the user sees.

            It's unclear from your description which of these APIs you think is not behaving as it should. We may be misunderstanding your use case, or you may be assuming the values-managing logic behaves differently to how it actually does. To clear this up, we'd recommend you show us a little test case that actually demonstrates the unexpected behavior for you.
            Should be as straightforward as a small DynamicForm definition we could drop into the feature explorer, a couple of buttons which report the result of whichever APIs are not behaving as you expect to console and instructions on steps to take to reproduce the problem. That should make it crystal clear what you're expecting vs what's actually happening and allow us to weigh in more precisely on what's going on.

            Thanks
            Isomorphic Software

            Comment


              #7
              Hello,

              I can appreciate the complexity. Before I create a standalone example, let me depict my situation. I have augmented some of my code to reveal my problem. Here is the start of the code that is run when the user hists the SAVE button on the Task form.
              Log.logDebug("********************** TaskForm.SaveButton.Click");

              var form = this.form;

              if (form.validate(false)) { // alert("validation succeeded."); /**/

              isc.say("form.getItem(OwnerID).getDisplayValue() = " + form.getItem("OwnerID").getDisplayValue());
              Below is the top of the form definition showing the OwnerID formitem. It has the ID of a TeamMember, which is looked up, and for which the TeamMemberName is displayed to the user.
              Code:
              <DynamicForm numCols="9" dataSource="Task" ID="TaskForm" autoDraw="false">
                  <fields>
                      <FormItem name="TaskID" title="Taskid" constructor="TextItem">
                          <visible>false</visible>
                          <disabled>false</disabled>
                      </FormItem>
                      <FormItem name="OwnerID" title="Owner" constructor="TextItem">
                          <visible>false</visible>
                          <valueField>TeamMemberID</valueField>
                          <displayField>TeamMemberName</displayField>
                          <optionDataSource><DataSource ref="TeamMember"/></optionDataSource>
                      </FormItem>
              As you can see in the attached image, the new owner is 'Vicki Spencer'. The popup displayed when I hit the SAVE button shows the display value to be '102'. That is her ID, not her name.

              I want the name in this instance. In the general condition for all the ID formitems on a form, I need the displayed value, not the key value. Performing another fetch for each such ID value is out of the question. There are too many and the complexity of doing all that IO and checking callback results is a lot of code for just a SAVE button.

              I don't want the framework to perform another fetch for the display value. I just want some path I can use to get the display value. If getDisplayValue() does not do the job, I don't care what does. The display value can be seen. So, it is somewhere on the form. And, I just cannot figure out where. Even with the development console and Firebug (at least so far).

              The purpose of getChangedValues and sparse results was to tell me just what fields I needed to get and to add to the log entry being prepared that shows all the changes made using displayed values that are meaningful to my users.

              Thanks,

              Rick
              Attached Files

              Comment


                #8
                It seems that getDisplayValue() should behave as expected if your selectItem has an optionDataSource specified, valid display / value fields set [and assuming the associated record is loaded in the client when you call the method].

                Here's a test case we ran to verify this is behaving as expected. Drop this code into the example here:

                Code:
                isc.DynamicForm.create({
                    ID:'testForm',
                    items:[
                     {name:"itemID", editorType:"SelectItem", displayField:"itemName", optionDataSource:"supplyItem" },
                     {editorType:"ButtonItem", title:"Show value", click:function () {
                         isc.say("Data Val:" + testForm.getItem("itemID").getValue() + "<br>DisplayVal:" + testForm.getItem("itemID").getDisplayValue());
                     }}
                    ]
                })
                This seems to imply there's something special about your use case that's causing the display value not to get picked up as expected.

                Comment


                  #9
                  I thought I found the problem in VisualBuilder. I was using it to look at my application. On the screen I was viewing the properties of selectitem OwnerID. It had a valueField and displayField. Looking at the JSP file running, however, I noticed that these were missing and only had the optionDataSource. This was also the case with the XML file.

                  That had me perlplexed. So, I added the valueField and displayField in the XML file, opened it in VB and saved it again. Now the JSP had everything and it worked. That was great.

                  But, I still did not understand how I could see the valueField and displayField in VB and not the XML or JSP. Looking around I noticed that there was ANOTHER OwnerID selectitem. It was just below where the screen cut off the outline.

                  I can only conclude that the duplicate caused VB to have problems. And, that this form just happened to be the first one where I started making my changes to capture the displayed values for the logs and the only field to test was the one with a duplicate. How it got there I have no idea. But, I will certainly keep an eye out similar goof-ball stuff.

                  This gives me great faith in your autotesting and framework design.

                  One thing gives me pause. As you mentioned, this will work when the associated record is loaded in the client when the method is called. I am calling when the user clicks the SAVE button. So, some time may have passed from when the user made the change. I saw the movie "Tron" and know lots can happen between user interactions.

                  I updated the datasources involved to have cacheAllData. It is not clear to me if that causes ALL database records to be brought client-side. Or, only those records fetched using criteria. The former will not scale when there many users.

                  I will press on assuming the current setup will scale, or I can do something about it.

                  Thanks for sticking with me.

                  Again.

                  Rick

                  Comment


                    #10
                    cacheAllData does indeed load all available records from a DataSource the first time any record is requested. It will not help with eliminating the possibility of a delay because requests against a DataSource are always handled asynchronously, even if the response data is coming from cache.

                    For this corner case where the displayValue may not be loaded yet for an extremely fast user or extremely slow server, you can just check whether the displayValue matches the value, and load the value yourself (client or server side).

                    Comment


                      #11
                      I think I am getting closer to what I will need that will scale for larger numbers of users and larger numbers of communities. The situation is that it is almost the case that communities don't share any data.

                      The exceptions are things like languages, regions, timezones, currencies, number and date formats, and some servlet names. These are a handful of records compared to the much, much larger set of user data.

                      Since I have control over fetches in dataSources, can not I restrict here the records that get cached for cacheAllData? I need to create the effect of 'cacheSomeData'.

                      Your advice on this matter would be valuable to me.

                      Thanks,

                      Rick

                      Comment


                        #12
                        Too vague to answer.

                        Think about:
                        1. the volume of data you want to cache
                        2. for how long
                        3. what invalidates it
                        4. is it shared between components

                        Then look at the caching mechanisms you've already seen: clientOnly DataSources, cacheAllData DataSources, ResultSet. Consider how you can use those. If it's not clear what to do, explain all of the above aspects in detail.

                        Comment


                          #13
                          I think I can supply most of what you are looking for.

                          1. the volume of data you want to cache
                          The only volume of data would be user data, not system related data. It is structured like this:

                          Communities (depends on # of customers, 30-2,000) * Projects (10-100) * Issues (100-1000) * Tasks (10-100)
                          At maximums:
                          Communities (2,000 Total) Only one is active at a time.
                          Projects (200,000 Total) (50 cached for the active project)
                          Issues (200,000,000 Total) (100 cached for current project, excludes those Closed)
                          Tasks (20,000,000,000 Total) (500 cached for current project, excludes those Completed)
                          2. for how long
                          I can imagine that the project manager or administrator would have the application open for hours each day. But, the order of magnitude larger group of team members would only access briefly to do updates.
                          3. what invalidates it
                          Since asynchronous updates will be common, changes from one user will need to be reflected to all other users online, but not immediately. The delay could be substantial, if necessary. However, there will typically be only 10-20 team members working within the same project at any one time.
                          4. is it shared between components
                          Yes. A number of lists share the same dataSource.
                          And, thanks for asking. I am just looking for general advice. I have designed myself into this situation with the requirements I devised for the product over a year ago.

                          Rick

                          Comment


                            #14
                            Extensive, automatic caching is already performed by the ResultSet. Do you have in mind a level of caching more aggressive than this? If so, in what specific sequence of fetches would you imagine more caching could take place, in such a way as to actually benefit performance?

                            Comment

                            Working...
                            X