Необязательное поле типа календаря в форме JSF

1

Я хочу сделать вкладку "Календарь" в форме JSF необязательной. Когда пользователь не сообщает о рождении, поле "Календарь" должно оставаться равным нулю.

Мой код:

@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>, которая зависит от getTime() для Calendar чтобы сделать преобразование. Он выдает NPE (исключение Null Pointer) при исполнении. Я знаю, что если я инициализирую рождение, проблема решена, но я действительно хочу, чтобы поле было нулевым, когда пользователь не заполнил поле.

Любые мысли о способе достижения этого?

Теги:
jsf
jsf-2
calendar

2 ответа

1
Лучший ответ

Хорошо, я отправлю это для потомков. Я думаю, что это сработает:

@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>.

1

Проблема не связана с преобразованием, а с выражением:

#{registration.user.birth.time}

Infact это код 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;
  }

Как вы можете заметить, нулевые и пустые значения управляются правильно. Но когда применяются значения, birth.time выражение birth.time, но ссылка на birth равна нулю, поэтому, когда birth.time сеттер по времени называется, вы получаете NPE.

Возможным решением является привязка поля birth к прямому виду java.util.Date, который является типом, управляемым DateTimeConverter, как DateTimeConverter ниже:

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню