Announcement

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

    ListGrid DateTime field with custom format

    Hello,

    I am struggling with trying to achieve that seconds are also displayed in a ListGrid DateTime field.

    (By the way: as I see ListGrid uses short date format for this purpose, it would be nice to be able to simply change it to the default normal date format...)

    So, as per the documentation, I need to change the ShortDatetimeDisplayFormatter and the DateParser.
    The datetime values are displayed as expected but when I try to change the value, some default validator of the editor complains that the value "Must be a date", despite it fits to the format I had set. The date parser is not called at all.

    SmartClient Version: v11.1p_2017-09-27/LGPL Development Only (built 2017-09-27)

    Sample code: (try to add a new row and set any datetime)

    Code:
        public void onModuleLoad() {
    
            DateTimeFormat dateFormatter = DateTimeFormat.getFormat("yyyy.MM.dd. hh:mm:ss");
    
            //DateUtil.setShortDatetimeDisplayFormatter(DateUtil.TOLOCALESTRING);
            DateUtil.setShortDatetimeDisplayFormatter(date -> dateFormatter.format(date));
            DateUtil.setDateParser(dateString -> {SC.say("Not called"); return null;});
    
            Canvas canvas = new Canvas();  
            final ListGrid grid = new ListGrid();  
            grid.setWidth(400);  
            grid.setHeight(200);  
            grid.setShowAllRecords(true);  
            grid.setCanEdit(true);  
            canvas.addChild(grid);  
    
            DataSource ds = new DataSource();
            ds.setClientOnly(true);
            DataSourceTextField countryNameDsField = new DataSourceTextField("countryName", "Country Name");  
            DataSourceTextField someDateTimeDsField = new DataSourceTextField("someDateTime", "Some DateTime");  
            someDateTimeDsField.setType(FieldType.DATETIME);
    
            ds.setFields(countryNameDsField, someDateTimeDsField);
            grid.setDataSource(ds);  
    
            Button btn = new Button("Add");
            btn.addClickHandler(event -> grid.startEditingNew());
            btn.setTop(220);
            canvas.addChild(btn);
    
            canvas.draw();  
        }
    I can't find out why is that validator complaining, how to get through it.

    Can you kick me to the right direction please?

    Thanks,
    Balázs

    #2
    We can't replicate this issue. We'd suggest getting rid of the lambda expressions in case GWT is generating something wrongly. Also, use logging instead of SC.say(), as your parser can be called multiple times.

    Note you shouldn't need a parser at all in this use case. The default parser will parse seconds, but make sure your inputFormat is set to YMD.

    Comment


      #3
      Dear Isomorphic,

      Getting rid of the lambda expressions does not change the result, nor setting inputFormat to YMD.

      Based on the following, the default parser doesn't seem to parse dates of the format yyyy.MM.DD, while it works for example for yyyy/MM/DD (note the dots between the parts).

      I did set debug level to DEBUG and saw the following on developer console:

      Code:
      11:51:46.038:KPR0:DEBUG:gridEdit:isc_ListGrid_0:change detection: newValues: {someDateTime: "2017.10.31. 11:51:00"}, oldValues: undef
      11:51:46.041:KPR0:DEBUG:gridEdit:isc_ListGrid_0:At field: countryName applying validators: [
      {type: "isString",
      typeCastValidator: true,
      _generated: true,
      defaultErrorMessage: undef}
      ] to value:undefined
      11:51:46.044:KPR0:INFO:gridEdit:isc_ListGrid_0:validateFieldValue, newValue: undef, passed validation: true, resultingValue: null
      11:51:46.045:KPR0:DEBUG:gridEdit:isc_ListGrid_0:At field: someDateTime applying validators: [
      {type: "isDate",
      typeCastValidator: true,
      _generated: true,
      stopIfFalse: true,
      defaultErrorMessage: "Must be a date."}
      ] to value:2017.10.31. 11:51:00
      11:51:46.047:KPR0:INFO:gridEdit:isc_ListGrid_0:validateFieldValue, newValue: "2017.10.31. 11:51:00", passed validation: false, resultingValue: null
      This suggests that there is an "isDate" validator (which is not configured by me, it must be set by SmartGWT framework automatically) and this validator claims the date is not valid.

      I digged into the scrambled javascript code of the framework to find out what is going on and I found that the validator is the following from ISC_Forms.js:

      Code:
      isDate:{type:"isDate",description:"Value is a date",valueType:"none",dataType:"none",
      condition:function(_1,_2,_3){
      console.log("1");
      console.log(_1);
      console.log("2");
      console.log(_2);
      console.log("3");
      console.log(_3);
      console.log(isc.Validator.$93n);
          if(_3==null||isc.is.emptyString(_3)||isc.isA.Date(_3))
              return true;
      console.log("4");
          if(!_2.errorMessage)
              _2.defaultErrorMessage=isc.Validator.notADate;
      console.log("5");
          var _4=isc.Validator.$93n?isc.DateUtil.parseInput(_3):isc.DateUtil.parseSchemaDate(_3);
      console.log("6");
      console.log(_4);
          if(_4==null||isNaN(_4.getTime()))
              return false;
      console.log("7");
          _2.resultingValue=_4;
          return true}
      }
      I don't know what is isc.Validator.$93n but it is false so isc.DateUtil.parseSchemaDate is called to parse the date (ISC_Core.js) which checks it with the following regexp

      Code:
      var _2=_1.match(/(\d{4})[\/-](\d{2})[\/-](\d{2})([T ](\d{2}):(\d{2})(:(\d{2}))?)?(\.(\d+))?([+-]\d\d?:\d{2}|Z)?/);
      Which does not match of course - please note that there are dots between year/month/day.

      In the end, it seems SmartGWT framework won't allow me to specify any other datetime format than it is hardcoded to accept.
      Or rather, isc.Validator.$93n might help to drive the validator to go to isc.DateUtil.parseInput() direction, but I couldn't find out where this value comes from.

      Could you be so kind as to help me find out what isc.Validator.$93n is?

      Thank you!


      Comment


        #4
        We just noticed that you create a DataSourceTextField then try to change the type to datetime. This scrambles the notion of what type the field is and could lead to your weird results. Just use a DataSourceDateTimeField instead.

        Comment


          #5
          Dear Isomorphic,

          Changing the type to DataSourceTextField doesn't change anything, everything goes exactly as described above.

          I also found out that isc.Validator.$93n is some internal stuff of the framework, which is used somewhere internally to allow date parsing with parseInput() instead of parseSchemaDate().

          Therefore, it really seems that although the framework allows to specify datetime format pretty freely, it will accept in the end only those formats that are hardcoded, as I described the corresponding javascript snipplets from the framework above.

          Comment


            #6
            We said to change the type to DataSourceDateTimeField.

            What's happening here is that the editor being used for your field doesn't realize the field type is datetime, so parseInput(), which is a very lenient parser that handles all kinds of punctuation variations, isn't being called.

            You then fall back to parseSchemaDate(), which is a stricter parser intended for network communication only, not user input.

            Correct your code and you will not longer be hitting the wrong parser.

            Comment


              #7
              And I said "Changing the type to DataSourceTextField doesn't change anything".
              You can trust me I tried it.

              If I am correct, the code you insist working is

              Code:
                  public void onModuleLoad() {
              
                      DateTimeFormat dateFormatter = DateTimeFormat.getFormat("yyyy.MM.dd. hh:mm:ss");
              
                      //DateUtil.setShortDatetimeDisplayFormatter(DateUtil.TOLOCALESTRING);
                      DateUtil.setShortDatetimeDisplayFormatter(date -> dateFormatter.format(date));
                      DateUtil.setDateParser(dateString -> {SC.say("Not called"); return null;});
              
                      Canvas canvas = new Canvas();  
                      final ListGrid grid = new ListGrid();  
                      grid.setWidth(400);  
                      grid.setHeight(200);  
                      grid.setShowAllRecords(true);  
                      grid.setCanEdit(true);  
                      canvas.addChild(grid);  
              
                      DataSource ds = new DataSource();
                      ds.setClientOnly(true);
                      DataSourceTextField countryNameDsField = new DataSourceTextField("countryName", "Country Name");  
                      DataSourceDateTimeField someDateTimeDsField = new DataSourceDateTimeField("someDateTime", "Some DateTime");  
                      someDateTimeDsField.setType(FieldType.DATETIME);
              
                      ds.setFields(countryNameDsField, someDateTimeDsField);
                      grid.setDataSource(ds);  
              
                      Button btn = new Button("Add");
                      btn.addClickHandler(event -> grid.startEditingNew());
                      btn.setTop(220);
                      canvas.addChild(btn);
              
                      canvas.draw();  
                  }
              But it does NOT work.
              Would you please be so kind as actually try whether it really works as you expect?
              If you tried and it works at your side then what should I do?
              Capture a video of the code-compilation-test-fail as a proof would make sense?


              Comment


                #8
                A quick update to note that we do see this issue, and we'll update again here when it's been fixed - but note that it's queued behind issues from customers with Support contracts.
                Last edited by Isomorphic; 16th Oct 2017, 19:59.

                Comment


                  #9
                  Which locale is your browser in? Are you actually loading that locale in your test?

                  We've made an internal change to have this work for you as-is, in builds dated October 18 and later, but your locale details could indicate why you've hit this issue and no-one else has.

                  Comment


                    #10
                    By way of a follow-up, note that while you will no longer see failed validations in your test case with today's builds, you will note that your custom parser is still not actually running.

                    We've just applied a fix for that, and you'll find your parser running as expected in builds dated October 19 and later.

                    Comment


                      #11
                      It is working, thank you!

                      Comment


                        #12
                        Just to round this out - the original test failed because it hit an edge case where if you applied *only* a datetime format, and left the date format unchanged, and *also* were not using a locale (despite changing formats to non-US).

                        Obviously, this situation (mismatched date and datetime formats, making date input impossible) is useless, but we've made it work anyway just so that an isolated test like the above doesn't confuse anyone.

                        Comment

                        Working...
                        X