Success! Looks like we've fixed this one. According to our records the fix was applied for EXTGWT-2983 in a recent build.
  1. #1
    Sencha Premium Member
    Join Date
    Jul 2012
    Posts
    28
    Vote Rating
    1
    flying-w is on a distinguished road

      0  

    Default Understanding DateField validation

    Understanding DateField validation


    Here's a code snippet for a datefield:
    Code:
    private final DateField _submissionDateCtrl = new DateField(); _submissionDateCtrl.addParseErrorHandler(new ParseErrorHandler() { @Override public void onParseError(ParseErrorEvent event) { Info.display("Parse Error", event.getErrorValue() + " could not be parsed."); } });
    _submissionDateCtrl.addValueChangeHandler(_submissionChangeHandler); _submissionDateCtrl.setValue(_originalProperties.getSubmissionTime()); _submissionDateCtrl.setClearValueOnParseError(false); _submissionDateCtrl.setAllowBlank(false); _submissionDateCtrl.addValidator(new Validator<Date>() { @Override public List<EditorError> validate(Editor<Date> editor, Date value) { if (value == null) { final List<EditorError> errors = new ArrayList<EditorError>(); errors.add(new DefaultEditorError(editor, "Not a valid date", value)); return errors; } return null; } });
    I'm curios about how the validator is working, as it seems to be invoked with a valid date object even when the date value typed by the user appears invalid. Let's say the initial value of the date is "2012-01-15" (YYYY-MM-DD). If I enter "2012-01-15-" I get a valid date object in the validator representing the original date. If I enter "2012-01-16-", again I get a valid date object but still representing the original value of the 15th. It is the case that when the date is invalid, I get the original value supplied to the validator? If I enter "garbage" (literally) that is correctly detected by the default validator, and my validator gets a null. In each case the parse error handler is fired correctly.

    Can you help me understand the subtle behaviour here, and how to detect it as an invalid date?

  2. #2
    Sencha User
    Join Date
    Sep 2007
    Posts
    13,971
    Vote Rating
    132
    sven is a glorious beacon of light sven is a glorious beacon of light sven is a glorious beacon of light sven is a glorious beacon of light sven is a glorious beacon of light sven is a glorious beacon of light

      0  

    Default


    Validation happens in the DateTimePropertyEditor class. We simple use the GWT parser for this.

    EDIT:

    I run that code and tried to reproduce the problem and failed so far. Which version of GXT/GWT are you using exactly? Would it be possible for you to provide a fully working testcase implementing EntryPoint?

  3. #3
    Sencha Premium Member
    Join Date
    Jul 2012
    Posts
    28
    Vote Rating
    1
    flying-w is on a distinguished road

      0  

    Default


    I am using GXT 3.04.

    If I manually type a date "2013-03-01", everything works fine. If I type "2013-03-99", my validator receives a date representing the current date, which is the value I initially populated into the date field rather than what the user entered. While my validator is doing nothing here, I presume GXT is also validating however the validate() method is returning true for the "99" date. How should I detected invalidly entered dates?

    Here's the code:

    Code:
    /**
     * Entry point classes define <code>onModuleLoad()</code>.
     */
    public class DateSample implements EntryPoint {
    
    
        private DateField dateField = new DateField();
        private Dialog dlg = new Dialog();
        /**
         * This is the entry point method.
         */
        public void onModuleLoad() {
            dateField.setValue(new Date());
            dateField.setClearValueOnParseError(false);
            dateField.addValidator(new Validator<Date>() {
                @Override
                public List<EditorError> validate(Editor<Date> editor,    Date value) {
                    Info.display("Date", "Date for validation: " + value);
                    return null;
                }
            });
            
            dlg.add(dateField);
            dlg.setPredefinedButtons(PredefinedButton.OK, PredefinedButton.CANCEL);
            dlg.setHideOnButtonClick(true);
            dlg.addHideHandler(new HideHandler() {
                @Override
                public void onHide(final HideEvent event) {
                    boolean result = dateField.validate();
                    Info.display("Date", "Date valid: " + result);
                }
            });
            dlg.show();
        }
    }

  4. #4
    Sencha Premium Member
    Join Date
    Jul 2012
    Posts
    28
    Vote Rating
    1
    flying-w is on a distinguished road

      0  

    Default


    Just wanted to bump this one for Sencha to comment on, it may have gone unnoticed.

  5. #5
    Sencha User
    Join Date
    Sep 2007
    Posts
    13,971
    Vote Rating
    132
    sven is a glorious beacon of light sven is a glorious beacon of light sven is a glorious beacon of light sven is a glorious beacon of light sven is a glorious beacon of light sven is a glorious beacon of light

      0  

    Default


    Sorry, somehow i missed this reply.
    I run that code and now i fully understand what you are trying to do. Cells only publish the new value after editing and only if editing was successfull. That is why validate runs against the old value. The logic can be found in TriggerFieldCell.finishEditing.


    Instead of using validate, you might want to use validateCurrent(false). This will first get the real value from the field and validate this.
    However the problem here will be that your custom validator needs to prevent that null is accepted is valid (getCurrentValue() returns null if its invalid).

    I will move this thread to the bugs forum for further investigation. The real problem starts that DateCell calls forceInvalid onCellParseError.

  6. #6
    Sencha - GXT Dev Team
    Join Date
    Jan 2012
    Location
    Arlington, WA
    Posts
    492
    Vote Rating
    15
    branflake2267 will become famous soon enough

      0  

    Default


    Great question. I'm glad you asked about this.

    So to get the correct validation result when validation fails with junk entered the input box for fields of typeValueBaseField, is field.isCurrentVaild().


    Code:
     // this tests the value seen in the date field input box
     boolean result = dateField.isCurrentValid();

    The reason why dateField.isVaild() won't work is because it checks the value set which only will get set when a new current value passes validation. Which you have noticed noting the previous value comes up which passes validation even in the case a bad value is entered into the input. This got our team to talking about providing a bit more clarity and consistency between the isValid use for the api and we are now looking at some of the changes for 3.1. In the mean time, when the field is of type ValueBaseField, field.isCurrentValid() can be used to test the validation entered has failed because it looks at the current value entered into the input box and not the previous good value set that passed validation.


    Example1 testing ValueBaseField types:
    Code:
    if (f instanceof ValueBaseField) {
      ValueBaseField<?> vfield = (ValueBaseField<?>) f;
      result = vfield.isCurrentValid(true);
    }

    Example2 testing both ValueBaseField and Field types when many fields exist:
    Code:
    Widget w = rowEditor.getFieldContainer().getWidget(i);
        if (w instanceof ValueBaseField<?>) {
      ValueBaseField<?> f = (ValueBaseField<?>) w;
      if (!f.isCurrentValid(true)) {
        return false;
      }
    } else if (w instanceof Field<?>) {
      Field<?> f = (Field<?>) w;
      if (!f.isValid(true)) {
        return false;
      }
    }
    Does this help answer the question?

    Thanks for asking,
    Brandon
    Last edited by branflake2267; 10 May 2013 at 2:32 PM. Reason: Code formatting fix.

  7. #7
    Sencha - GXT Dev Team
    Join Date
    Jan 2012
    Location
    Arlington, WA
    Posts
    492
    Vote Rating
    15
    branflake2267 will become famous soon enough

      0  

    Default


    Sven brought up something I missed. It appears that isCurrentValid() at the moment has a bug and I'm digging deeper. I'll update the thread as soon as I can make some progress on the issue.

    Brandon

  8. #8
    Sencha - GXT Dev Team
    Join Date
    Jan 2012
    Location
    Arlington, WA
    Posts
    492
    Vote Rating
    15
    branflake2267 will become famous soon enough

      0  

    Default


    I've added a validation process flow chart to the field validation guide. This displays when to to use valueBaseField.isCurrentValid() vs field.isValid().
    http://docs.sencha.com/gxt-guides/3/...alidation.html

    Currently I see the best method for checking the current value is value for value base fields is isCurrentValid().

    Brandon

  9. #9
    Sencha Premium Member
    Join Date
    Jul 2012
    Posts
    28
    Vote Rating
    1
    flying-w is on a distinguished road

      1  

    Default


    Just wanted to say thank you for your analysis and solutions concerning this problem. I've been off project for a long while but now I'm back I've integrated your suggestion into my code and it seems to be work well. Thanks once again.

    Simon

Thread Participants: 2