1

I have a problem mentioned in the topic. I have

    <h:selectOneMenu class="time" id="time" value="#{auctionBean.expDate}">
                                    <f:convertDateTime pattern="dd/MM/yyyy HH:mm:ss"/>
                                    <f:selectItem itemValue="11/11/1111 11:11:11" itemLabel="1 day" />
                                    <f:selectItem itemValue="#{auctionBean.calculateExpDate(4)}" itemLabel="4 days" />
                                    <f:selectItem itemValue="#{auctionBean.calculateExpDate(7)}" itemLabel="7 days" />
                                    <f:selectItem itemValue="#{auctionBean.calculateExpDate(14)}" itemLabel="14 days" />
</h:selectOneMenu>

The problem is i am getting Validation Error: Value is not valid message for all items but first one. The method:

public String calculateExpDate(int days) {
    Calendar cal = Calendar.getInstance();
    cal.setTime(new Date());
    cal.add(Calendar.DATE, days);
    Format formatter = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
    System.out.println("data: " + formatter.format(cal.getTime()));
    return formatter.format(cal.getTime());
}

It returns String in good format. Output from system.out:

INFO:   data: 10/10/2013 20:40:04

Where is the problem? I have no clue at all

Mateusz Gaweł
  • 673
  • 1
  • 8
  • 22

2 Answers2

2

A good one!

If what you are getting is a VALIDATION error, not a CONVERSION problem, then the probable scenario is:

  • the list of available values is created, and the values have precision of 1 second,
  • user picks one of them,
  • but on postback the available values get recalculated, and they are all a couple of seconds later than the original ones.
  • so the value that your user picked is no more available on the list of possible values,
  • and so a validation error happens (which is what JSF does always when the value chosen is no longer on the list of select items).
  • you do not get it with the first item, because it's the only one that does not change with time :-).

If you move the backing bean to view scope (or session scope), or cut the precision, it should work. Or better yet - make an enum with values of NOW, IN_2_DAYS, IN_4_DAYS and so on. And calculate the real date after the enum is chosen.

fdreger
  • 12,264
  • 1
  • 36
  • 42
1

fdreger is right! I marked his post as an answer. Thanks:) This is my solution if you are lazy (however it might be done better I guess):

JSF:

<h:selectOneMenu class="time" id="time" value="#{auctionBean.choosenOption}">
                                <f:selectItems value="#{auctionBean.days}" var="days" itemValue="#{days}" itemLabel="#{days.label}"/>
                            </h:selectOneMenu>

fragment of my auctionBean:

public enum Days {

    IN_1_DAY("1 dzień", 1),
    IN_4_DAYS("4 dni", 4),
    IN_7_DAYS("7 dni", 7),
    IN_14_DAYS("14 dni", 14);
    private String label;
    private int days;
    private Days(String label, int days) {
        this.label = label;
        this.days = days;
    }

    public String getLabel() {
        return label;
    }

    public Date calculateExpDate() {
        Calendar cal = Calendar.getInstance();
        cal.setTime(new Date());
        cal.add(Calendar.DATE, this.days);
        return cal.getTime();
    }
}
private Days choosenOption;

public void setChoosenOption(Days choosenOption) {
    this.choosenOption = choosenOption;
    expDate = choosenOption.calculateExpDate();
}

public Days getChoosenOption() {
    return choosenOption;
}

public Days[] getDays() {
    return Days.values();
}

User chooses how many days his auction should be active and i calculate what is an expiration date. expDate is Date object which i set only once, after choosing the single enum and sumbitting the form. Pretty good solution suggested :)

Mateusz Gaweł
  • 673
  • 1
  • 8
  • 22