Announcement

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

    How to validate date when useTextItem="true"

    How do I ensure that the user has entered either a valid date or no date in a DateItem when useTextItem is set to true? I'd like this to be the default behavior for all DateItems unless I add other validations to specific DateItems.

    I am already using DateUtil to set formatters and parser so that the current locale is used, as follows. This is fairly old code so if there is a better way to do this now please let me know.
    Code:
    // Set normal input and display format for dates based on locale
    DateUtil.setDateInputFormatter(new DateInputFormatter() {
    
    	@Override
    	public Date parse(String dateString) {
    		if (dateString==null)
    			return null;
    		else
    			return DateTimeFormat.getFormat(PredefinedFormat.DATE_SHORT).parse(dateString);
    	}
    });
    DateUtil.setShortDateDisplayFormatter(new DateDisplayFormatter() {
    
    	@Override
    	public String format(Date date) {
    		if (date==null)
    			return null;
    		else
    			return DateTimeFormat.getFormat(PredefinedFormat.DATE_SHORT).format(date);
    	}
    });
    DateUtil.setNormalDateDisplayFormatter(new DateDisplayFormatter() {
    
    	@Override
    	public String format(Date date) {
    		if (date==null)
    			return null;
    		else
    			return DateTimeFormat.getFormat(PredefinedFormat.DATE_MEDIUM).format(date);
    	}
    });

    #2
    If the field is declared in the DataSource as type "date", there's an implicit "isDate" validator that will reject anything that isn't a valid data (or null, if the field is not marked required="true"). Does this answer your question?

    Comment


      #3
      That doesn't seem to be working. The field definition is simple.
      <field name="INCI" title="Next Cost Effective Date" type="date" useTextField="true"/>

      But I can basically type anything into the field and not get a validation error. For example, if I type 55/55/55 it gets transformed into 8/24/59 and accepted. Is is something wrong I'm doing in my setDateInputFormatter?

      The behavior I'm looking for is simply to have the date interpreted based on the current locale and rejected if it is not a valid date (or empty). I can see from the developer console that there is an isDate validator on the field.
      Code:
      Evaluator: result of 'isc_DynamicForm_40.getItem("INCI").validators[0]...' (1ms):
      {type: "isDate",
      typeCastValidator: true,
      _generated: true,
      stopIfFalse: true}

      Comment


        #4
        Try setEnforceDate(true) on your dateItem.

        Comment


          #5
          I first tried enforceDate="true" in the ds.xml and saw no affect. Looking at the DateItem I can see that it had an attribute enforceDate: "true", a String value, not a boolean enforceDate: true. So I then tried setEnforceDate(true) on the DateItem directly. Now I can see the attribute is set correctly, but I can still type in something like 999 in the date field and get no error.

          Here is the DateItem definition and it's 3 validators (one custom).
          Code:
          Evaluator: result of 'isc_DynamicForm_21.getItem("HODI")...' (1ms):
          DateItem{eventParent: [DynamicForm ID:isc_DynamicForm_21],
          containerWidget: [DynamicForm ID:isc_DynamicForm_21],
          form: [DynamicForm ID:isc_DynamicForm_21],
          name: "HODI",
          editorType: "DateItem",
          enforceDate: true,
          validators: Array[3],
          menuItem: "Dates>Order",
          required: true,
          title: "Order Date",
          type: "date",
          useTextField: "true",
          ID: "isc_DateItem_11",
          items: Array[1],
          dateTextField: [TextItem ID:isc_TextItem_91 name:dateTextField],
          textField: [TextItem ID:isc_TextItem_91 name:dateTextField],
          hasFocus: false}
          Evaluator: result of 'isc_DynamicForm_21.getItem("HODI").validators...' (1ms):
          [Obj{type:custom}, Obj{type:isDate}, Obj{type:required}
          ]
          Evaluator: result of 'isc_DynamicForm_21.getItem("HODI").validators[0]...' (1ms):
          {type: "custom",
          condition: anonymous(),
          errorMessage: "Order date must be on or before ship dat..."[42]}
          Evaluator: result of 'isc_DynamicForm_21.getItem("HODI").validators[1]...' (1ms):
          {type: "isDate",
          typeCastValidator: true,
          _generated: true,
          stopIfFalse: true}
          Evaluator: result of 'isc_DynamicForm_21.getItem("HODI").validators[2]...' (1ms):
          {type: "required"}

          Comment


            #6
            FYI - I tried getting rid of the custom validator and even adding validateOnExit(true). Still I can type anything into the Date field.

            Interesting, if I type "jkjhkj" into the field and use the developer console to examine values I see this.

            Evaluator: result of 'isc_DynamicForm_21.getItem("HODI").getValue()...' (1ms):
            Date(2/19/11)
            Evaluator: result of 'isc_DynamicForm_21.getItem("HODI").getEnteredValue()...' (1ms):
            "jkjhkj"

            This is after tabbing out of the field. The field is not flagged with any sort of error and the "EnteredValue" is still displayed.
            Last edited by jay.l.fisher; 2 Mar 2011, 08:50.

            Comment


              #7
              Apparently it is the use of DateUtil.setDateInputFormatter. Here is a test case. If you remove the setDateInputFormatter the field behaves as expected. Adding it back the validation stops happening.
              Code:
              package com.smartgwt.sample.client;
              
              import java.util.Date;
              
              import com.google.gwt.core.client.EntryPoint;
              import com.google.gwt.i18n.client.DateTimeFormat;
              import com.google.gwt.i18n.client.DateTimeFormat.PredefinedFormat;
              import com.smartgwt.client.util.DateInputFormatter;
              import com.smartgwt.client.util.DateUtil;
              import com.smartgwt.client.widgets.form.DynamicForm;
              import com.smartgwt.client.widgets.form.fields.DateItem;
              
              public class BuiltInDS implements EntryPoint {
              
              
              	public void onModuleLoad() {
              		DateUtil.setDateInputFormatter(new DateInputFormatter() {
              
              			@Override
              			public Date parse(String dateString) {
              				if (dateString==null)
              					return null;
              				else
              					return DateTimeFormat.getFormat(PredefinedFormat.DATE_SHORT).parse(dateString);
              			}
              		});
              		DynamicForm form = new DynamicForm();
              		DateItem dateItem = new DateItem("dateItem", "Date Item");
              		dateItem.setEnforceDate(true);
              		dateItem.setUseTextField(true);
              		form.setItems(dateItem);
              		form.draw();
              	}
              }
              Is this even necessary to have the locale behavior I'm looking for. It seems that all of this would be automatic DateItem behavior. So whatever the solution is, I'd like it to be something I can apply globally and not have to code something on each specific DateItem.

              Comment


                #8
                What this suggests is that your DateTimeFormat always returns a Date instance no matter what garbage it's handed. If so, you're basically preventing validation from functioning by removing the ability for the validator to ever see the bad value.

                Comment


                  #9
                  So how should I define date fields so that they respect the current locale for formatting purposes and reject invalid dates, but accept null?

                  Comment


                    #10
                    You can already switch between MDY vs DMY input via DateItem.setInputFormat(), without providing a parsing function. That should be all you need unless you are trying to support localized input of month and day names (much harder).

                    There will soon be a system-wide setting for this on DateUtil.

                    Comment


                      #11
                      Changing the formatter to use parseStrict and returning null if there is an error seems to do the trick.
                      Code:
                      DateUtil.setDateInputFormatter(new DateInputFormatter() {
                      
                      	@Override
                      	public Date parse(String dateString) {
                      		if (dateString==null)
                      			return null;
                      		else
                      			try {
                      				return DateTimeFormat.getFormat(PredefinedFormat.DATE_SHORT).parseStrict(dateString);
                      			} catch (Exception e) {
                      				return null;
                      			}			
                      	}
                      });

                      Comment


                        #12
                        Using 2012-27-2 3.0p

                        we are using our own dateinput and parse formatter.

                        There is following behavior:

                        consider date is the following:

                        11/24/2000

                        If you set year = 9999 , it's fine.
                        month to 50, fine.
                        but setting and removing field, so that form will be validated:
                        to day=99 (+8 years) or month=99 ( +2 years in this case), or other invalid values,
                        it will switch the year.


                        The higher the value is for e.g. month the year will increase.
                        I don't see a clear consistency in this behavior.

                        I tried to setEnforceDate(true), but doesn't show a difference.
                        Is there a way to stop this autoformatting ?

                        Probably I should use : setUseTextField(false), but this will not work with inputdateformatters

                        Comment


                          #13
                          Nice would be to support a RelativeDateItem chooser with setuseTextfield(false)
                          where type = dateitem, which would also solve it.

                          Comment


                            #14
                            Hi Damend,

                            You've said that you've got your own date parser, but you seem to be complaining a behavior that would be part of the date parser?

                            If you think there's a SmartGWT problem, please start a new thread with this question and include runnable sample code.

                            Comment

                            Working...
                            X