2

How would I create custom data type to a UIComponent attribute?

Example: Suppose one has a UIInputDate (an UIInput) and has an attribute Date maxDate, how will I make sure that whatever maxDate is entered will always be resulted as Date?

Buhake Sindi
  • 87,898
  • 29
  • 167
  • 228
  • You mean, you want to validate the attribute value specified by the enduser (specifically, the developer using your custom component)? – BalusC Aug 12 '13 at 19:09
  • Not really! My custom component accepts a `minDate` and `maxDate`. I want that, irrespective of date format in Java, I can verify that the value entered (by the user) matches the `minDate` and `maxDate` as specified by the developer. – Buhake Sindi Aug 12 '13 at 19:23
  • Hm, I understood that you asked how to validate if the developer specified `java.util.Date` and not e.g. `java.lang.String` as `maxDate`. In any way, the answer is simple, use a validator (you can add one in component's constructor). But, still, I find your question after all confusing. – BalusC Aug 12 '13 at 19:24
  • Oh sorry, I thought of using String as an attribute type but to cater for all RFC3339 date formats makes it challenging. So, I decided to use `Date` as attribute types. The problem is how will developers set the date value to these attributes and use it on Validation and conversion later? The value of the component, I can use a converter, that's not the problem, it's the additional attributes. – Buhake Sindi Aug 12 '13 at 19:36

1 Answers1

1

You can just create a custom validator the usual way. The input component is already available as 2nd argument, you just have to cast it.

public class UIInputDateRangeValidator implements Validator {

    public void validate(FacesContext context, UIComponent component, Object value) {
        UIInputDate inputDate = (UIInputDate) component;
        Date minDate = inputDate.getMinDate();
        Date maxDate = inputDate.getMaxDate();
        Date date = (Date) value;

        // ... Use Date#after(), Date#before(), etc.
    }

}

You can create and add the validator in custom component's constructor.

public UIInputDate() {
    addValidator(new UIInputDateRangeValidator());
    // You can use setConverter() with new DateTimeConverter() if you didn't already do that.
}
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Thanks BalusC, my question would be, how would the developer enter `minDate` and `maxDate` as a value on their xhtml page (where these attributes are `Date`)? – Buhake Sindi Aug 12 '13 at 19:43
  • Just the usual way? ``, etc. I'm not understanding your concrete problem here. It's not different from all other attributes. – BalusC Aug 12 '13 at 19:45
  • I was thinking of something more like ``, in that effect. If that is not possible, then I will take your previous comment instead. – Buhake Sindi Aug 12 '13 at 19:52
  • As to `new Date()` in EL, no that's not possible. It really needs to be a bean property or even a whole bean. You can register `java.util.Date` as managed bean in faces-config.xml. OmniFaces has also two of such beans in request and application scope, available as `#{now}` and `#{startup}` respectively. Related: http://stackoverflow.com/questions/9174310/display-current-date-on-jsf-page/9177715#9177715 – BalusC Aug 12 '13 at 19:55
  • Thanks BalusC, I will like to know how to make `java.util.Date` as managed bean in faces-config.xml. Anyways, is it correct to say that if a component has a default converter and a developer explictly links another converter on xhtml, does the default converter gets overridden? – Buhake Sindi Aug 12 '13 at 19:58
  • Click link in previous comment for the how. As to converter being overridden, yes that's correct. Just do if necessary some checking in `setConverter()` if it's an instance of `DateTimeConverter`, or before the cast in validator if it's an instance of `Date`. – BalusC Aug 12 '13 at 20:00
  • Brilliant. Kudos to you buddy! :-) – Buhake Sindi Aug 12 '13 at 20:04