JSF skip Required-Validation without immediate=true

后端 未结 6 1286
余生分开走
余生分开走 2020-12-04 12:11

I have multiple forms, where I have mandatory fields and optional fields.

To submit such a form I require the validation on the required-attribute to be exe

相关标签:
6条回答
  • 2020-12-04 12:40

    I use skipValidators for such a case (assuming all validations are skipped). Code from omnifaces

    <h:form>
      <h:dataTable value="#{bean.items}" var="item">
        <h:column>
            <h:inputText value="#{item.value}" required="true" />
        </h:column>
      </h:dataTable>
      <h:commandButton value="add new row" action="#{bean.add}">
        <o:skipValidators />
      </h:commandButton>
      <h:commandButton value="save all data" action="#{bean.save}" />
      <h:messages />
    </h:form>
    
    0 讨论(0)
  • 2020-12-04 12:47

    if you want to skip validation when click on button then easly add parameter to button where you want to skip it. Example:

    <p:commandButton value="button1" action="#{bean.action()}" >
       <f:param name="skipValidator" value="true"/>
    </p:commandButton>
    

    Then in validator you can read this parameter and if it is true then skip it:

    @FacesValidator("com.validators.MyValidator")
    public class MyValidator implements Validator{
    
      public void validate(FacesContext ct, UIComponent co, Object obj) throws ValidatorException { 
        if(!continueValidation()){
          return;
        }
        // validation process
      }
    
    protected boolean continueValidation() {
        String skipValidator= FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("skipValidator");
        if (skipValidator != null && skipValidator.equalsIgnoreCase("true")) {
          return false;
        }
        return true;
      } 
    }
    
    0 讨论(0)
  • 2020-12-04 12:49

    Each Button creates an entry inside the Param-List as long as it's member of the form. So I simple applied a check for the presence of that entry to the "required" parameter:

    <h:form id="form" prependId="true">
    ...
    <p:inputText id="someId"
        required="#{param['form:save']==null}" ... />
    ...
    <p:commandButton id="save" value="Save" />
    <p:commandButton id="submit" value="Submit" />
    <p:commandButton id="cancel" value="Cancel" immediate="true" />
    </h:form>
    

    When I click "Submit" the param['form:save'] is NULL, which then turns the expression to true so the validation is executed.

    When I click "Save" the param['form:save'] is NOT NULL (but empty!), which resolves to false so the validation is ignored. (Or let's say JSF thinks it is not a required field due to the expression beeing evaluated to false)

    0 讨论(0)
  • 2020-12-04 12:49

    An alternative to what others proposed is to use a custom BeanValidator that will validate the form if say, clicked the button with id save. Any other button not implicitly defined to perform validation will not validate but just submit your data available. Find the full nice and clean example here

    0 讨论(0)
  • 2020-12-04 13:03

    This is an excellent question and a very helpful answer. This approach saves a lot of hassle with immediate="true".

    I'd like to add this info (but am not allowed to comment yet). Your code examples seem to require JSF 2.0 or above (correct me). If you are like me damned to use JSF 1.1/1.2 then consider these changes/additions:

    <h:form id="form">
    ...
    <p:inputText id="someId" required="#{!empty param['save']}" ... />
    ...
    <p:commandButton id="save" value="Save" />
    </h:form>
    
    • There is no attribute prependId in JSF 1.1
    • Therefore in the param[...] you must only specify the button id
    • You are using a syntax ="{true and ...}" that might be a mistake (no #)?
    • As you can see from your own editing history the "null or not null" logic is not very intuitive :) Thats why I immediately liked the !empty ... version when I stumbled upon it.
    0 讨论(0)
  • 2020-12-04 13:04

    In my case I didn't find the clientId of the button in the params but I found this param['javax.faces.source'] = buttonClientId in the requestmap. The value will be the clientId of the clicked button.

    0 讨论(0)
提交回复
热议问题