validationg DateItem + useTextField with Enter key

hi,

How to validate DateItem + useTextField when I press enter key?
(same as original GWT’s DateBox do)

first, I write following code:

class CustomDateItem extends DateItem {
	CustomDateItem() {
		addKeyPressHandler(new KeyPressHandler() {
			@Override
			public void onKeyPress(KeyPressEvent event) {
				if (ENTER.equals(event.getKeyName()))
					validate();
			}
		});
		setUseTextField(Boolean.TRUE);
		setEnforceDate(true);
		setValidateOnChange(true);
	}
}

“changed” is dispatched only by “blur”, so i call validate() in my “key press” handler.
but this doesn’t work as I expected, unfortunately setEnforceDate(true) work only on blur.
is this intended behaviour ? or bug ?

so i abondoned to use enforceDate, i wrote CustomValidator in second.

class CustomDateItem extends DateItem {
	CustomDateItem() {
		addKeyPressHandler(new KeyPressHandler() {
			@Override
			public void onKeyPress(KeyPressEvent event) {
				if (ENTER.equals(event.getKeyName()))
					validate();
			}
		});
		setUseTextField(Boolean.TRUE);
		setValidateOnChange(true);
		setValidators(new CustomValidator() {
			@Override
			protected boolean condition(Object value) {
				...
			}
		});
	}
}

but condition()'s argument and getValue() gives me null pointer, because:

  1. DateItem have two properties getEnteredValue() and getValue()
  2. at this point(“key press”), former is set, but later is not set(=null).

so, CustomValidator doesn’t work too.
(and now i realized why setEnforceDate(TRUE) doesn’t work…)

kludgely, i change the code such as following:

public class CustomDateItem extends DateItem {
	public CustomDateItem() {
		addKeyPressHandler(new KeyPressHandler() {
			@Override
			public void onKeyPress(KeyPressEvent event) {
				if (ENTER.equals(event.getKeyName())) {
					/* force to sync EnteredValue and Value property */
					setValue(getEnteredValue_fix_invalid_prototype());
					validate();
				}
			}
		});
		setUseTextField(Boolean.TRUE);
		setValidateOnChange(true);
		setValidators(new CustomValidator() {
			@Override
			protected boolean condition(Object value) {
				return value != null;
			}
		});
	}
	/*
	 * it seems that getEnteredValue()'s prototype is wrong, so i correct it by JSNI
	 */
	public native String getEnteredValue_fix_invalid_prototype() /*-{
		var self = this.@com.smartgwt.client.core.DataClass::getJsObj()();
		return self.getEnteredValue();
	}-*/;
}

it almost works fine for me expect one thing:

  1. if this setDateFormatter is TOEUROPEANSHORTDATE(DMY), nothing is wrong.
    entering 99/99/9999 and Enter key cause validation error.
    this is same as DateTimeFormat.parseStrict().

  2. but using TOJAPANESESHORTDATE formatter(YMD) accept 9999/99/99, and convert to 10007/06/07.
    this is same as DateTimeFormat.parse()'s loose conversion.

so i tried setEditorValue{Formatter,Parser}:

setEditorValueFormatter(new FormItemValueFormatter() {
	@Override
	public String formatValue(Object value, Record record, DynamicForm form, FormItem item) {
		return DateTimeFormat.getFormat("yyyy/MM/dd").format((Date)value);
	}
});
setEditorValueParser(new FormItemValueParser() {
	@Override
	public Object parseValue(String value, DynamicForm form, FormItem item) {
		return DateTimeFormat.getFormat("yyyy/MM/dd").parseStrict(value);
	}
});

but this doesn’t make no sense, still accept loose date input.
i suspect this is bug, and i think it is better to make it choosable parse/parseStrict by property.

finally, i stack in mudd, anyone have ideas?

i’m now using latest nightly build SmartGWT 2.5(2011-08-15).
GWT-2.3.0 + JDK 1.6.25
tested on Google chrome 13.0.782.112 m.

very truly yours.

Takehiko NOZAKI <takehiko.nozaki@gmail.com>

hi,

i found that exporting and calling updateValue() is more simpler than
setValue(getEnteredValue()) and validate().

public class CustomDateItem extends DateItem {
	public CustomDateItem() {
		addKeyPressHandler(new KeyPressHandler() {
			@Override
			public void onKeyPress(KeyPressEvent event) {
				if (ENTER.equals(event.getKeyName())) {
					updateValue();
				}
			}
		});
		setDateFormatter(DateDisplayFormat.TOJAPANSHORTDATE);
		setEnforceDate(Boolean.TRUE);
		setUseTextField(Boolean.TRUE);
		setValidateOnChange(Boolean.TRUE);
	}
	public native void updateValue() /*-{
		var self = this.@com.smartgwt.client.core.DataClass::getJsObj()();
		self.updateValue();
	}-*/;
}

but still remain the TOJAPANSHORTDATE problem.
is there no way to force DateItem to keep strict date string parsing?

very truly yours.

Takehiko NOZAKI <takehiko.nozaki@gmail.com>