Ali Fakhraee
Ali Fakhraee

Reputation: 65

Conditional required in jsf 2 when FacesConverter involved

I have a form like this:

<h:form>
    Phone number:
            <h:inputText id="phone_number"
                         value="#{dbUserManager.phoneNumber}"
                         validatorMessage="The phone number is invalid."
                         required="#{auth.value eq 'MOBILE'}"
                         requiredMessage="Phone number is required." />
            </h:inputText>
    Authentication type:
            <h:selectOneMenu  value="#{dbUserManager.authentication}" converter="#{authenticationTypeConverter}"  binding="#{auth}">
                <f:selectItems value="#{dbUserManager.authTypeList}" />
            </h:selectOneMenu>
</h:form>

AuthenticationType is an entity similar to this:

@Entity
public class AuthenticationType implements Serializable 
{
  @Id
  @Basic(optional = false)
  private Short id;
  @Basic(optional = false)
  private String description;
  @Override

  //...

  public String toString() 
  {
    return description;
  }

and finally AuthenticationTypeConverter:

@Stateless
@ManagedBean
@FacesConverter(value="authenticationTypesConverter")
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public class AuthenticationTypeConverter implements Converter
{
    @PersistenceContext(unitName="pu")
    private EntityManager em = null;

    @Override
    public Object getAsObject(FacesContext fc, UIComponent uic, String string)
    {
        TypedQuery<AuthenticationType> q = em.createNamedQuery(
                AuthenticationType.FIND_BY_DESCRIPTION,
                AuthenticationType.class);
        q.setParameter("description", string);
        return q.getSingleResult();
    }

    @Override
    public String getAsString(FacesContext fc, UIComponent uic, Object o)
    {
        if (o == null)
        {
            return "";
        }
        return o.toString();
    }
}

What I tried to do is that to set the required of phone number to true when authentication type is set to 'MOBILE'. But it's not behaving as I expect.

I think the problem lies in the fact that I need to use FacesConverter for AuthenticationType. But I don't know how to solve it.

Can anyone give a hint?

Thanks

Upvotes: 1

Views: 748

Answers (1)

L-Ray
L-Ray

Reputation: 1647

You have to rerender the h:inputText-field after the user chose from your h:selectOneMenu. To do so, change this selection to

<h:selectOneMenu  value="#{dbUserManager.authentication}" 
     converter="#{authenticationTypeConverter}"  binding="#{auth}">
     <f:selectItems value="#{dbUserManager.authTypeList}" />
    <f:ajax event="change" render="phone_number" />
 </h:selectOneMenu>

Also in the inputTexts required-attribute I would expect something more like

{dbUserManager.authentication.description}

Give it a try...

Update 2014/01/22:

If you want to hold already typed informations in the phone_number field, you can tell the <f:ajax> tag to execute not only selectOneMenu but also the input field before rendering it new. In this case replace the upper <f:ajax /> solution with

...
    <f:ajax event="change" execute="@this phone_number" render="phone_number" />
...

Upvotes: 1

Related Questions