2012-12-07 14 views
8

Problem, który mam z kalendarzem PrimesFaces 3.4.1. Podczas korzystania z wyskakującego menu kontekstowego aktywowanego za pomocą przycisku lub pola wejściowego można wybrać tylko ważne daty, które działają dobrze, szczęśliwe dni!Kalendarz PrimeFaces akceptuje nieprawidłowe daty jako dane wejściowe

Problemy pojawiają się, gdy ręcznie dodajesz datę do pola wejściowego, jeśli dodasz niepoprawną datę, składnik kalendarza PrimeFaces najprościej zgodzi się na przekształcenie tego w prawidłową datę, a następnie wysłanie, co oznacza, że ​​walidacja back-end nie ma wyjścia. Kilka ciekawych tłumaczenia poniżej:

  • 30/02/2012 staje 2/6/2014
  • 322/05/2012 staje 5/10/2038
  • 01/14/2012 staje 4/1/2012

Aby odtworzyć to szaleństwo, spójrz na PrimeFaces Calendar Showcase.

Widziałem rozwiązanie wokół za pomocą atrybutu readOnlyInput='true', ale wydaje się, że tylko zapobiega wpisaniu liter w polu, nie numer lub ukośników. Poniżej jest jedna instancja kalendarzu I wprowadziły:

<p:calendar id="fldDateOfBirth" 
      value="#{pc_CreateUser.user.dateOfBirth}" 
      binding="#{pc_CreateUser.dobComp}" 
      navigator="true" 
      pattern="dd/MM/yyyy" 
      maxlength="10" 
      yearRange="-100" 
      validator="#{pc_CreateUser.validateDOB}" 
      title="#{msg.user_date_format_default_tip}" 
      converterMessage="#{msg.user_error_dob_invalid}" 
      readOnlyInput="true" 
      showOn="button" /> 

Rozwiązanie mądry jestem otwarty na wszelkie propozycje:

  1. Czy to jest typowe problemy w PrimeFaces? Czy istnieje sztuczka, której mogę użyć do naprawy?
  2. Czy mogę użyć JavaScript do sprawdzenia daty przed wysłaniem lub do zablokowania wszystkich danych wejściowych przez użytkownika?
  3. Coś jeszcze o czym nie pomyślałem!

Z góry dziękuję, to powoduje problemy przez wiele tygodni!

Odpowiedz

13

Używane pod pokrywami <p:calendar> używa pod pokrywami SimpleDateFormat, który z kolei używa domyślnie analizy lenient, powodując przepełnienie wartości do przeniesienia na następny poziom danych daty. Na przykład. 32 stycznia stanie się 1 lutego itd.

W prostych słowach Java można to wyłączyć przez DateFormat#setLenient(), przekazując false. Zobacz także między innymi to pytanie: validating a date using dateformat.

W kategoriach JSF, zasadniczo trzeba dostarczyć niestandardowy konwerter, który używa nie pobłażliwego DateFormat. Na szczęście standardowy JSF już dostarcza takie pudełko w smaku <f:convertDateTime>, więc możesz po prostu użyć go bezpośrednio.

<p:calendar ...> 
    <f:convertDateTime pattern="dd/MM/yyyy" /> 
</p:calendar> 
+0

ta pracowała doskonale! Dziękuję za rozwiązanie i wyjaśnienie, bardzo doceniane. – JonnyIrving

+0

Nie ma za co. – BalusC

+0

Jeśli używasz starszych wersji primefaces przy użyciu tego convertDateTime powoduje konwersji, aby zwrócić null, a otrzymasz błędy javascript. (getDate == null). Jeśli możesz uaktualnić do wersji PF 4, to niestety nie mogę i szukam alternatywy :) – VeenarM

0

W twarze-config.xml dodać

<converter> 
    <converter-id>localDateConverter</converter-id> 
    <converter-class>com.utility.LocalDateConverter</converter-class> 
</converter> 

W powyższej klasy tj LocaldateConverter dodać to poniżej kod

/** 
* @param facesContext . 
* @param uiComponent . 
* @param input . 
* @return Object . 
*/ 
@Override 
public Object getAsObject(final FacesContext facesContext, final UIComponent uiComponent, final String input) { 
    if (StringUtils.isBlank(input)) { 
     return null; 
    } 
    final String componentPattern = (String) uiComponent.getAttributes().get("datePattern"); 
    final String patternToUse = componentPattern != null ? componentPattern : CommonConstants.OUTPUT_DATE_FORMAT; 
    try { 
     final DateFormat fmt = new SimpleDateFormat(patternToUse); 
     Date convertedDate = new java.sql.Date(fmt.parse(input).getTime()); 
     return convertedDate; 
    } catch (Exception e) { 
     throw new ConverterException(new FacesMessage(FacesMessage.SEVERITY_ERROR, "Invalid Date Format", null)); 
    } 
} 

/** 
* @param facesContext . 
* @param uiComponent . 
* @param obj . 
* @return String . 
*/ 
@Override 
public String getAsString(final FacesContext facesContext, final UIComponent uiComponent, final Object obj) { 
    if (obj==null) { 
     return null; 
    } 
    final Date date = (Date) obj; 
    return date.toString(); 
} 
+0

Jak to jest pomocne? nawet nie mów im, co robisz. Wszystko, co robisz, to kopiowanie obecnego, już standardowego konwertera datetime jsf. – VeenarM

Powiązane problemy