JSF表单中的可选日历类型字段



我想让JSF表单中的Calendar输入成为可选的。当用户不通知出生时,Calendar字段必须保持为空。

我的代码:

@Model
public class Registration {
private User user = new User();
    public void register() {
        // stuff
    }
//getUser
}

模型类:

public class User { 
    //other fields
    private Calendar birth;
    // gets and sets
}

页面:

<h:outputLabel for="birth" value="Birth Date" />
<h:inputText id="birth" value="#{registration.user.birth.time}" >
    <f:convertDateTime pattern="dd/MM/yyyy" />
</h:inputText>

到目前为止,这里的问题是<f:convertDateTime>,它依赖于CalendargetTime()方法来进行转换。它在执行时抛出一个NPE(空指针异常)。我知道,如果我初始化出生,问题就解决了,但是我真的希望当用户不填充字段时,字段为空。

有什么方法可以做到这一点吗?

问题与转换无关,而与表达式有关:

#{registration.user.birth.time}

实际上这是DateTimeConverter代码:

 public Object getAsObject(FacesContext context, UIComponent component,
                          String value) {
    ...
    Object returnValue = null;
    DateFormat parser = null;
    try {
        // If the specified value is null or zero-length, return null
        if (value == null) {
            return (null);
        }
        value = value.trim();
        if (value.length() < 1) {
            return (null);
        }
        ...
         returnValue = parser.parse(value);
     } catch (ParseException e) {
       ...
     }
     return returnValue;
  }

您可以注意到,null和空值是正确管理的。但是当这些值被应用时,表达式birth.time被求值,但是birth引用是空的,所以当调用setter on time时,你得到NPE。

一个可能的解决方案是将birth字段直接绑定到java.util.Date类型,这是DateTimeConverter管理的类型,如下所示:

public class User { 
    //other fields
    private Date birth;
    // gets and sets
} 

好吧,我会把这个贴出来给后人看的。我想这样就可以了:

@FacesConverter("CustomCalendarConverter")
public class CalConverter implements Converter{
@Override
public Object getAsObject(FacesContext context, UIComponent component, String value) {
    if(value != null && !value.toString().isEmpty()){
        try {
            String pattern = (String) component.getAttributes().get("pattern");
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(new SimpleDateFormat(pattern).parse(value));
            return calendar;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    return null;
}
@Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
    if(value != null && !value.toString().isEmpty()){
        Calendar cal = (Calendar) value;
        String pattern = (String) component.getAttributes().get("pattern");
        return new SimpleDateFormat(pattern).format(cal.getTime());
    }
        else return null;
    }
}

视图应该是:

<h:outputLabel for="birth" value="Birth Date" />
<h:inputText id="birth" value="#{registration.user.birth}">
    <f:converter converterId="CustomCalendarConverter" />
    <f:attribute name="pattern" value="dd/MM/yyyy" />
</h:inputText>

您也可以创建一个复合组件,例如<custom:inputCalendar>

相关内容

  • 没有找到相关文章

最新更新