2012-12-07 3 views
8

Il problema che sto avendo è con il calendario PrimesFaces 3.4.1. Quando si utilizza il selettore di date popup attivato tramite il pulsante o sul campo di input, è possibile selezionare solo date valide che funzionano bene, giorni felici!Il calendario PrimeFaces accetta date non valide come input

I problemi viene quando si aggiunge manualmente una data nel campo di inserimento, se si aggiunge una data non valida componente primefaces calendario prende il migliore congettura a convertire questo in una data valida e poi inviarlo, il che significa che la validazione di back-end è un no go Alcune traduzioni interessanti sotto:

  • 30/02/2012 diventa 2/6/2014
  • 322/05/2012 diventa 5/10/2038
  • 01/14/2012 diventa 2012/04/01

Per ricreare questa follia dai un'occhiata allo PrimeFaces Calendar Showcase.

Ho visto la soluzione in giro usando l'attributo readOnlyInput='true' ma sembra solo che le lettere non vengano immesse nel campo, non il numero o le barre. Di seguito è riportato un esempio di calendario ho implementato:

<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" /> 

soluzione saggia Sono aperto a qualsiasi suggerimento:

  1. questo è un problemi comuni a primefaces? C'è un trucco che posso usare per risolvere ?
  2. Posso utilizzare JavaScript per convalidare la data prima che sia inviata o per bloccare tutto l'input dell'utente interamente?
  3. Qualsiasi altra cosa a cui non avessi pensato!

Grazie in anticipo, questo mi ha causato problemi per settimane!

risposta

13

Il <p:calendar> utilizza sotto le coperte SimpleDateFormat che a sua volta utilizza di default lenient analisi, causando i valori overflow a rotolare sopra al livello successivo metrica data. Per esempio. Il 32 gennaio diventerebbe l'1 febbraio ecc.

In termini Java semplici, questo può essere disattivato da DateFormat#setLenient(), passando false. Vedi anche tra gli altri questa domanda: validating a date using dateformat.

In termini JSF, è fondamentalmente necessario fornire un convertitore personalizzato che utilizza uno DateFormat non indulgente. Fortunatamente, il JSF standard fornisce già tale funzionalità in <f:convertDateTime>, quindi è possibile utilizzarlo direttamente.

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

Questo ha funzionato a meraviglia! Grazie per la soluzione e la tua spiegazione, molto apprezzata. – JonnyIrving

+0

Prego. – BalusC

+0

Se si utilizza la versione precedente di primefaces utilizzando questo convertDateTime, la conversione restituisce null e verranno visualizzati errori javascript. (getDate == null). Se è possibile effettuare l'aggiornamento a PF 4, purtroppo non posso e sto cercando alternative :) – VeenarM

0

In faces-config.xml aggiungere questo

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

Nella classe superiore cioè LocaldateConverter aggiungere questo codice sotto

/** 
* @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

Come è utile? non gli dici nemmeno quello che stai facendo. Tutto quello che stai facendo è copiare l'attuale convertitore jsf datetime standard. – VeenarM