ever alian
ever alian

Reputation: 1060

h:selectBooleanCheckbox always pass false to validator

I have h:selectBooleanCheckbox but it passes 'false' to the validator. always.

<h:panelGroup id="tncPanel">
 <label>
  <h:selectBooleanCheckbox id="tncSelection" value="#{businessBean.tncSelection}">
   <f:validator validatorId="checkboxValidator"/>
   <f:attribute name="label" value="Please agree terms and conditions."/>
  </h:selectBooleanCheckbox>
  I have read and agreed to all the
  <a href="#" data-toggle="modal" data-target="#modal-term-and-conditions">
     Terms and Conditions.
  </a>
 </label>
</h:panelGroup>

<h:panelGroup id="buttonPanel">
   <h:commandLink id="nextButton" action="#{businessBean.goNext}">
        Submit
   </h:commandLink>
</h:panelGroup>

Why I have panelGroup here is, based on logic in top of page, I have a logic to display/not the button and checkbox

This is my Validator.

    @FacesValidator("checkboxValidator")
public class CheckboxValidator implements Validator {

    private static final String DEFAULT_LABEL = "Please confirm the address.";

    @Override
    public void validate(FacesContext context, UIComponent component, Object value){
        String checkBoxValue = String.valueOf(((HtmlSelectBooleanCheckbox) component).getSubmittedValue());

        System.out.println("checkBoxValue " + checkBoxValue);
        System.out.println("value2: " + value);   

        String label = String.valueOf(component.getAttributes().get("label"));
        if ("null".equals(label)) {
            label = DEFAULT_LABEL;
        }
        if("false".equalsIgnoreCase(checkBoxValue)){
            FacesMessage msg = new FacesMessage(null, label);
            msg.setSeverity(FacesMessage.SEVERITY_ERROR);
            throw new ValidatorException(msg);
        }
    }
}

Validator sysout always prints checkBoxValue false

UPDATE

After comment on Balusc, I add another sysout to print directly the parameter value. But still it's printing as value2: false.

Upvotes: 0

Views: 1351

Answers (1)

Youans
Youans

Reputation: 5061

There is a bug related to this situation , When you render a container that holds a from from another form you the rendered form loses its view state ,Thus form is submitted to no destination solution is to render the form container and the form its self from the other form

For example that won't work :

  <h:panelGroup id="panel">
       <h:form>
        <h:commandButton value="Submit" rendered="#{not testAction.flag}">
                <f:ajax render=":panel" listener="#{testAction.submit()}"/>
            </h:commandButton>
        </h:form>
      <h:panelGroup id="panel">

        <h:form id="secondForm" rendered="#{testAction.flag}">
            <h:selectBooleanCheckbox id="checkBox" value="#{testAction.boolVal}">
                <f:validator validatorId="checkboxValidator"/>
            </h:selectBooleanCheckbox>
            <h:commandButton value="Go" action="#{testAction.go()}"/>

        </h:form>
     </h:panelGroup>

Second form submit will be like this :

enter image description here

secondForm won't have its view state the form is submitted but with no destination on the server cuz the view object is not fetched on the server that requires the javax.faces.ViewState value to be fetched by what you have to do here is to render form as well in the f:ajax:

<f:ajax render=":panel :secondForm" listener="#{testAction.submit()}"/>

That inform server to backup the second form rendered with the javax.faces.ViewState

Refer to that post : Rendering other form by ajax causes its view state to be lost, how do I add this back? for more info

Hope that was the problem :)

Upvotes: 1

Related Questions