2009-12-18 11 views

Répondre

2

Trois façons:

  1. Retour ou intermédiaire, il en java.util.Calendar avec trois getters et trois setters.
  2. Faire usage d'un Converter, cela va cependant être un peu hacky. Faire usage d'un composant tiers comme rich:calendar

Éditez: selon les commentaires, voici comment l'option 2 ressemblerait.

page.jsp:

<h:form> 
    <h:selectOneMenu value="#{myBean.date}"> 
     <f:converter converterId="datePartConverter" /> 
     <f:attribute name="part" value="day" /> 
     <f:selectItems value="#{myBean.days}" /> 
    </h:selectOneMenu> 
    <h:selectOneMenu value="#{myBean.date}"> 
     <f:converter converterId="datePartConverter" /> 
     <f:attribute name="part" value="month" /> 
     <f:selectItems value="#{myBean.months}" /> 
    </h:selectOneMenu> 
    <h:selectOneMenu value="#{myBean.date}"> 
     <f:converter converterId="datePartConverter" /> 
     <f:attribute name="part" value="year" /> 
     <f:selectItems value="#{myBean.years}" /> 
    </h:selectOneMenu> 

    <h:commandButton value="submit" action="#{myBean.submit}"/> 
    <h:messages /> 
</h:form> 

mypackage.MyBean:

package mypackage; 

import java.util.ArrayList; 
import java.util.Date; 
import java.util.List; 

import javax.faces.model.SelectItem; 

public class MyBean { 

    private static List<SelectItem> days = new ArrayList<SelectItem>(); 
    private static List<SelectItem> months = new ArrayList<SelectItem>(); 
    private static List<SelectItem> years = new ArrayList<SelectItem>(); 

    static { 
     // Just do your thing to fill them. Only ensure that those are Strings, 
     // else you'll need to change the type in Converter accordingly. 
     for (int i = 1; i <= 31; i++) days.add(new SelectItem(String.valueOf(i))); 
     for (int i = 1; i <= 12; i++) months.add(new SelectItem(String.valueOf(i))); 
     for (int i = 2000; i <= 2020; i++) years.add(new SelectItem(String.valueOf(i))); 
    } 

    private Date date; 

    public void submit() { 
     // Print submitted date to stdout. 
     System.out.println("Submitted date: " + date); 
    } 

    public List<SelectItem> getDays() { 
     return days; 
    } 

    public List<SelectItem> getMonths() { 
     return months; 
    } 

    public List<SelectItem> getYears() { 
     return years; 
    } 

    public Date getDate() { 
     return date; 
    } 

    public void setDate(Date date) { 
     this.date = date; 
    } 

} 

mypackage.DatePartConverter:

package mypackage; 

import java.text.ParseException; 
import java.text.SimpleDateFormat; 
import java.util.Date; 
import java.util.Map; 

import javax.faces.application.FacesMessage; 
import javax.faces.component.UIComponent; 
import javax.faces.component.UIInput; 
import javax.faces.context.FacesContext; 
import javax.faces.convert.Converter; 
import javax.faces.convert.ConverterException; 

public class DatePartConverter implements Converter { 

    public Object getAsObject(FacesContext context, UIComponent component, String value) { 
     String part = (String) component.getAttributes().get("part"); 
     Date date = null; 

     if (context.getRenderResponse()) { 
      // Convert any default/selected date for display. 
      Date selectedDate = (Date) ((UIInput) component).getValue(); 
      if (selectedDate != null) { 
       if (("day".equals(part) && new SimpleDateFormat("d").format(selectedDate).equals(value)) 
        || ("month".equals(part) && new SimpleDateFormat("M").format(selectedDate).equals(value)) 
        || ("year".equals(part) && new SimpleDateFormat("yyyy").format(selectedDate).equals(value))) 
       { 
        date = selectedDate; 
       } 
      } 
     } else { 
      // Convert submitted date after submit. 
      Map<String, Object> map = context.getExternalContext().getRequestMap(); 
      if ("day".equals(part)) { 
       map.put("DatePartConverter.day", value); // Save until we have all parts. 
      } else if ("month".equals(part)) { 
       map.put("DatePartConverter.month", value); // Save until we have all parts. 
      } else if ("year".equals(part)) { 
       String day = (String) map.get("DatePartConverter.day"); 
       String month = (String) map.get("DatePartConverter.month"); 
       String dateString = String.format("%s-%s-%s", day, month, value); 

       try { 
        date = new SimpleDateFormat("d-M-yyyy").parse(dateString); 
       } catch (ParseException e) { 
        throw new ConverterException(new FacesMessage(e.getMessage()), e); 
       } 
      } 
     } 

     return date; 
    } 

} 

    public String getAsString(FacesContext context, UIComponent component, Object value) { 
     // Not relevant here. Just return SelectItem's value. 
     return (String) value; 
    } 

faces-config.xml

<converter> 
    <converter-id>datePartConverter</converter-id> 
    <converter-class>mypackage.DatePartConverter</converter-class> 
</converter> 

<managed-bean> 
    <managed-bean-name>myBean</managed-bean-name> 
    <managed-bean-class>mypackage.MyBean</managed-bean-class> 
    <managed-bean-scope>request</managed-bean-scope> 
</managed-bean> 

Notez qu'il n'y a pas Validator et que SimpleDateFormat est par défaut lenient. Ainsi, la sélection par exemple 31 novembre produirait le 1er décembre. Vous devrez peut-être implémenter vous-même un DatePartValidator si vous voulez en avertir.

+0

Merci pour votre réponse, BalusC (+1) Pouvez-vous montrer comment puis-je obtenir mon objectif bu en utilisant l'approche numéro 2: Faire usage d'un convertisseur, cela va cependant être un peu hacky –

+0

J'ai édité ma question avec un échantillon de travail. – BalusC

+0

Note: vous devez vraiment mettre les listes déroulantes dans l'ordre du jour-mois-année. Si vous voulez, par exemple, year-month-day, vous devrez réorganiser les blocs if dans le convertisseur pour que la dernière partie crée finalement la date en fonction de l'entrée. Parler de hacky :) – BalusC

0

En disant « liant » et « la sauvegarde de haricots », vous êtes censé se référer à ce qui suit:

<h:inputText binding="#{myBean.myTextField}" /> 

et ont private UIInput dans votre haricot.

Si tel est le cas - non, vous ne pouvez pas lier comme ça. Eh bien, je ne suis pas sûr si vous pouvez techniquement - mais cela aura sûrement un effet inattendu.

Toutefois, si vous souhaitez cibler une propriété de bean géré , vous pouvez, par exemple:

<h:inputText value="#{myBean.myProperty.day}" /> 
<h:inputText value="#{myBean.myProperty.year}" /> 
+0

Merci pour votre réponse. Une solution de contournement? –