5
votes

In a basic registration screen (with button register records the screen) there are two panels:

Data panel:

enter image description here

Address panel:

enter image description here

I can register by completing only the Data panel. It is not necessary to fill the Address panel. However, if at least one field of the Address panel is filled, then all other fields in the same panel should be required.

enter image description here

How can I achieve this?

2
-1 for not saying what you've tried so far and not showing any code.Andre

2 Answers

7
votes

You need to check in the required attribute if the other inputs have submitted a non-empty value. Since this can result in quite some boilerplate, here's a kickoff example with only 3 input components.

<h:form id="form">
    <h:inputText id="input1" value="#{bean.input1}" required="#{empty param['form:input2'] and empty param['form:input3']}" />
    <h:inputText id="input2" value="#{bean.input2}" required="#{empty param['form:input1'] and empty param['form:input3']}" />
    <h:inputText id="input3" value="#{bean.input3}" required="#{empty param['form:input1'] and empty param['form:input2']}" />
</h:form>

An alternative is to bind the components to the view and use UIInput#getValue() to check the value of the previous components and UIInput#getSubmittedValue() to check them for next components (components are namely processed in the order as they appear in the component tree). This way you don't need to hardcode client ID's. You only need to ensure that binding names doesn't conflict with existing managed bean names.

<h:inputText binding="#{input1}" value="#{bean.input1}" required="#{empty input2.submittedValue and empty input3.submittedValue}" />
<h:inputText binding="#{input2}" value="#{bean.input2}" required="#{empty input1.value and empty input3.submittedValue}" />
<h:inputText binding="#{input3}" value="#{bean.input3}" required="#{empty input1.value and empty input2.value}" />

You'll understand that this produces ugly boilerplate when you have more and more components. The JSF utility library OmniFaces has a <o:validateAllOrNone> validator for the exact purpose. See also the live demo. Based on your quesiton tags, you're using OmniFaces, so you should already be set with just this:

<o:validateAllOrNone components="input1 input2 input3" />
<h:inputText id="input1" value="#{bean.input1}" />
<h:inputText id="input2" value="#{bean.input2}" />
<h:inputText id="input3" value="#{bean.input3}" />
1
votes

First you should add a method to backing bean something like this:

public boolean isAddressPanelRequired() {
    // Check if at least one field is entered
    // and return true if it is and false othervise
}

Each input element on address panel should have required="#{backingBean.addressPanelRequired}"

Then add onblur ajax listener on each input component on address panel which process that component, and updates address panel.