我有多种形式,我有必填字段和可选字段。
要提交这样的表单,我需要对要执行的required-attribute进行验证,这样可以正常工作。
要取消此类表单,我使用immediate="true"
上的属性p:commandbutton
,这会使其在应用请求值期间执行操作在这里:How to skip validation when a specific button is clicked?
但是,对于大型表单,我想为用户提供一个保存按钮,以便他可以稍后继续。
为了保存当前状态,我还想忽略required-attribute的验证。但是,使用immediate="true"
不起作用,因为我的save方法简单保存,因为JSF生命周期永远不会命中“UpdateModelValues”-Phase。 (根据http://www.javacodegeeks.com/2012/01/jsf-and-immediate-attribute-command.html)
那么,如何绕过所需的检查但不会跳过生命周期的一半?
答案 0 :(得分:64)
每个Button在Param-List中创建一个条目,只要它是表单的成员即可。 所以我简单地检查了该条目是否存在于“required”参数:
<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>
当我点击“提交”时,param['form:save']
为NULL
,然后将表达式转为true
,以便执行验证。
当我点击“保存”时,param['form:save']
为NOT NULL
(但为空!),这会解析为false
,因此会忽略验证。 (或者让我们说JSF认为它不是必需的字段,因为表达式被评估为false
)
答案 1 :(得分:5)
如果要在单击按钮时跳过验证,请轻松地将参数添加到要跳过的按钮。例如:
<p:commandButton value="button1" action="#{bean.action()}" >
<f:param name="skipValidator" value="true"/>
</p:commandButton>
然后在验证器中你可以读取这个参数,如果是,则跳过它:
@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;
}
}
答案 2 :(得分:4)
这是一个很好的问题,也是一个非常有用的答案。这种方法为immediate="true"
节省了很多麻烦。
我想添加此信息(但暂不予评论)。您的代码示例似乎需要 JSF 2.0 或更高版本(请更正)。如果你像我一样使用JSF 1.1 / 1.2,那么请考虑这些更改/添加:
<h:form id="form">
...
<p:inputText id="someId" required="#{!empty param['save']}" ... />
...
<p:commandButton id="save" value="Save" />
</h:form>
="{true and ...}"
可能是错误的(没有#
)?!empty ...
版本的原因。答案 3 :(得分:1)
其他人提议的替代方法是使用自定义BeanValidator
来验证表单,如果说,单击带有id保存的按钮。未隐式定义以执行验证的任何其他按钮将不会验证,只是提交您的数据。找到完整美观的例子here
答案 4 :(得分:0)
在我的情况下,我没有找到params中按钮的clientId,但我发现了这个
请求映射中的param['javax.faces.source'] = buttonClientId
。该值将是单击按钮的clientId。
答案 5 :(得分:0)
在这种情况下,我使用skipValidators(假设跳过了所有验证)。来自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>