f:viewParam with multiple values
Asked Answered
M

1

5

I have a <f:viewParam> driven search screen. I am trying to implement it to take multiple values for a single <f:viewParam>.

I believe the correct URL would look something like

<url>?state=COMPLETE&state=PENDING

The XHTML section is as follows:

<f:metadata>
   <f:viewParam name="state"
      value="#{backingBean.state}"
      converter="#{stateNameConverter}" />
</f:metadata>

I have tried the following 2 method signatures on backingBean:

public void setState(State... state)

Was hopeful that JSF implementation would build an array for the values and set on the backing bean. JSF implementation failed with error stating it cannot convert enum to array of enums.

public void setState(State state)

Thought that maybe the JSF implementation would set the converted values as it found them in the URL. Only the first value was set.

The stateNameConverter converts between String and enum value.

Is it possible to have multiple values for <f:viewParam> in JSF 2?

Mowery answered 17/10, 2011 at 13:3 Comment(0)
C
7

No, unfortunately, there's no such tag as <f:viewParams>. There's also a comment in Mojarra's UIViewParameter#decode() implementation (which is the code behind <f:viewParam> tag) which confirms that:

@Override
public void decode(FacesContext context) {
    if (context == null) {
        throw new NullPointerException();
    }

    // QUESTION can we move forward and support an array? no different than UISelectMany; perhaps need to know
    // if the value expression is single or multi-valued
    // ANSWER: I'd rather not right now.
    String paramValue = context.getExternalContext().getRequestParameterMap().get(getName());

    // submitted value will stay as previous value (null on initial request) if a parameter is absent
    if (paramValue != null) {
        setSubmittedValue(paramValue);
    }

    rawValue = (String) getSubmittedValue();
    setValid(true);

}

Right now your best bet to workaround this is by gathering the values yourself from ExternalContext#getRequestParameterValuesMap() in a @PostConstruct or <f:viewAction> or maybe a @ManagedProperty("#{paramValues.state}") on a String[] property.

You could also create a custom <my:viewParams> tag which achieves that, but this isn't exactly trivial.

Crabwise answered 17/10, 2011 at 13:15 Comment(4)
This is not so easy as there are many ways to do that (for example with a comma separated list : state=COMPLETE,PENDING). See microprofile eclipse and the enum QueryParamStyle.Alleyne
@grigouille: in your specific case just use a Converter. The original question is about multiple params with same name as in foo.xhtml?state=COMPLETE&state=PENDING. You don't have multiple params with same name. Just a single param with a value in a format which could be reinterpreted as multiple values. In case you happen to use OmniFaces, take a look at ToCollectionConverter.Crabwise
Well state=COMPLETE,PENDING is org.eclipse.microprofile.rest.client.ext.QueryParamStyle.COMMA_SEPARATED and state=COMPLETE&state=PENDING is org.eclipse.microprofile.rest.client.ext.QueryParamStyle.MULTI_PAIRSAlleyne
@grigouille: the original question is about JSF <f:viewParam>. If you have a single param with comma separated value as in state=COMPLETE,PENDING, then just use a JSF Converter as in <f:viewParam ... converter="toCollectionConverter">. It will automatically convert to List<String> property.Crabwise

© 2022 - 2024 — McMap. All rights reserved.