Announcement

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

    formItem.changed not firing

    SmartClient Version: v12.1p_2023-06-06/AllModules Development Only (built 2023-06-06)

    Chrome and FF on MacOS Ventura 13.4

    Hello, please modify the showcase sample https://www-demos.smartclient.com/sm...jdbcOperations
    like this:

    Code:
    isc.DynamicForm.create({
      ID: "form",
      dataSource:"lastUpdated",
      items:[
        {name:"lastUpdatedTime", type:"time", changed:"isc.logEcho('changed')"}
      ]
    });
    
    
    form.editNewRecord({lastUpdatedTime: new Date('2023-05-05T14:30:00')})
    in my time zone (GMT+2), if I change the time, setting it one hour earlier (ie 13:30), and tab out, the changed is not fired.

    After that, with every other change seems to work.

    #2
    Thanks for the notification. We'll take a look and follow up when we have more information

    Comment


      #3
      This is a slightly tricky case to do with the difference between JavaScript Dates and "logical times".

      This area is discussed in the "date format and storage" docs here: https://smartclient.com/smartclient-...rmatAndStorage
      [See the"time handling" paragraph in particular]

      In SmartClient we have a notion of a "Logical Time" data type, which is represented by a JavaScript Date object with the date info set to the epoch (1/1/1970), and the actual time portion offset from that : https://smartclient.com/smartclient-...id=class..Time

      In your test case you have a Time type formItem, and you're telling it to edit a date with a different year/month/day in your local timezone (2023-05-05T14:30:00).
      Due to timezones and daylight savings time, etc, this happens to have a different UTC-Hour-offset to a "Logical Time", such that the local hour (14) is equivalent to (13) for a date of 1/1/1970

      If you initially set this field value to the result of a call to DateUtil.createLogicalTime(), this will behave correctly.

      Code:
      form.editNewRecord({lastUpdatedTime: isc.DateUtil.createLogicalTime(14,30)})
      Or - if you're actually working with true dates in your data and you want to display the time-portion of it, you may want to use a DateItem with a custom format instead.
      Here's an example of that approach:

      Code:
      isc.DynamicForm.create({
        ID: "form",
        dataSource:"lastUpdated",
        items:[
          {name:"lastUpdatedTime", type:"datetime", showPickerIcon:false,
           format:"H:mm", changed:"isc.logEcho('changed')"}
        ]
      });
      
      
      form.editNewRecord({lastUpdatedTime: new Date('2023-05-05T14:30:00')})

      Comment


        #4
        Thank you very much for the detailed explanation and suggestion, the custom format with the DateTime item does the trick for me.

        Comment


          #5
          Hello, actually at first I didn't test it thoroughly, but now I noticed that if I use format then I get a string as a value, so it fails validation.

          Is it expected? Should I use formatEditorValue/parseEditorValue?


          Code:
          isc.DynamicForm.create({
              dataSource: "supplyItem",
              fields: [
                  {name: "nextShipment", format:"H:mm", type:"datetime", changed:"isc.logEcho(value)"},
                  {name: "saveBtn", title: "Save", type: "button", click: "form.saveData()"}
              ]
          });
          
          <DataSource isSampleDS="true"
              ID="supplyItem"
              serverType="sql"
              tableName="supplyItem"
              titleField="itemName"
              testFileName="/examples/shared/ds/test_data/supplyItem.data.xml"
              dbImportFileName="/examples/shared/ds/test_data/supplyItemLarge.data.xml"
          >
              <fields>
                  <field name="nextShipment"  type="datetime" title="Next Shipment"/>
              </fields>
          </DataSource>

          Comment


            #6
            I also noticed that if I use a Week Year in format, the changed prints sometimes a string, and sometimes a date:

            https://youtube.com/shorts/0MtL2Rlik-8?feature=share

            Code:
            isc.DynamicForm.create({
                dataSource: "supplyItem",
                fields: [
                    {name: "nextShipment", format:"dd-MM-YYYY H:mm", type:"datetime", changed:"isc.logEcho(value)"},
                    {name: "saveBtn", title: "Save", type: "button", click: "form.saveData()"}
                ]
            });

            Comment


              #7
              With the first example, what are you hoping for - you have a field declared as type "datetime" but a format that shows only time. The type should be "time".

              More generally, your "format" and inputFormat need to match. Otherwise, you end up with automated formatting of the date such that it doesn't match the expected input format, so that's going to fail validation.

              Comment


                #8
                I think I can achieve the behaviour I'm looking for with this code:

                Code:
                isc.DynamicForm.create({
                    ID: "form",
                    dataSource: "lastUpdated",
                    items: [
                        {
                            name: "lastUpdatedTime", type: "datetime", showPickerIcon: false,
                            parseEditorValue: function (value, form, item) {
                                var split = value ? value.split(":") : null;
                                return value && split && split.get(0) && isc.isA.Number(Number(split.get(0))) && (!split.get(1) || isc.isA.Number(Number(split.get(1))))
                                    ? isc.DateUtil.combineLogicalDateAndTime(item.getValue(), isc.DateUtil.createLogicalTime(split[0], split[1] || 0))
                                    : null;
                            },
                            formatEditorValue: function (value, record, form, item) {
                                return isc.DateUtil.getDisplayHours(value) + ':' + isc.NumberUtil.stringify(isc.DateUtil.getDisplayMinutes(value), 2);
                            }
                        }
                    ]
                });
                My goal is to allow editing of only the time part in a datetime value.

                Comment


                  #9
                  That works, although another approach would be to have an additional field of type "time", which you populate with just the time portion of the value from the datetime field. Then when it changes, update the datetime value to match.

                  Comment


                    #10
                    thank you very much for the suggestion, the code gets even simpler:

                    Code:
                    isc.DynamicForm.create({
                        ID: "form",
                        dataSource: "lastUpdated",
                        items: [
                            {
                                name: "lastUpdatedTime",
                                type: "datetime",
                                showPickerIcon: false,
                                hidden: true
                            },
                            {
                                name: "timeOnly",
                                type: "time",
                                showPickerIcon: false,
                                changed: function(form, item, value) {
                                    var datetimeValue = form.getValue("lastUpdatedTime");
                                    var newDatetimeValue = isc.DateUtil.combineLogicalDateAndTime(datetimeValue, value);
                                    form.setValue("lastUpdatedTime", newDatetimeValue);
                                }
                            }
                        ]
                    });
                    
                    var aDatetime = new Date();
                    form.setValue('lastUpdatedTime', aDatetime);
                    form.setValue('timeOnly', aDatetime);

                    Comment

                    Working...
                    X