我有一个显示行列表的h:datatable,每行的字段都是输入字段。
我在表格之前呈现“添加行”按钮,并在表格的每一行上显示“删除行”按钮。
烘焙bean是viewScoped,按钮在辅助bean的java列表中添加/删除元素,然后返回到同一视图。
我在按钮中将immediate属性设置为“true”,以便在添加或删除行时不验证输入字段。
一切正常但只有一件事:输入文件的值被清除。我认为视图保留了值,因为bean是viewScoped。
如何在不触发验证的情况下实现添加/删除行,并保留用户在表单中输入的值?
我的观点:
<h:form>
<h:commandButton value="Añadir Fila" immediate="true" action="#{tablaController.addRowAction}" />
<h:dataTable value="#{tablaController.lista}" var="fila" cellpadding="0" cellspacing="0" border="1">
<f:facet name="header">TABLA</f:facet>
<h:column>
<f:facet name="header"><h:outputLabel value="NOMBRE" /></f:facet>
<h:inputText id="nom" value="#{fila.nombre}" />
<h:message for="nom" class="msjError" />
</h:column>
<h:column>
<f:facet name="header"></f:facet>
<h:commandButton value="Quitar Fila" immediate="true" action="#{tablaController.removeRowAction(fila)}" />
</h:column>
</h:dataTable>
</h:form>
我的支持bean:
@ManagedBean(name="tablaController")
@ViewScoped
public class TablaController {
private List<Fila> lista;
...
public TablaController() { }
...
@PostConstruct
public void init() {
this.lista = new ArrayList<Fila>();
for (int i=0; i<5; i++) {
Fila fila = new Fila();
fila.setNombre("");
this.lista.add(i,fila);
}
}
...
public String addRowAction () {
Fila fila = new Fila();
fila.setNombre("");
this.lista.add(fila);
return "";
}
public String removeRowAction (Fila f) {
boolean exito = this.lista.remove(f);
return "";
}
...
}
更新 - &gt;我的解决方案:
如果有人有兴趣,我会在这里写下我的解决方案。
问题是我使用immediate =“true”来跳过验证,但是这也会跳过update_model_values,因此单击添加/删除按钮后,用户在表单中输入的值将丢失重新登录页面。
当我使用“JSR-303 bean验证”时,我的解决方案是使用f:validateBean跳过验证来启用/禁用它们。根据我点击的按钮,如果我想要执行验证,我启用bean验证(例如在“提交”按钮),如果我想跳过它们,我禁用bean验证(如添加/删除行按钮)。但无论如何,update_model_values总是执行,因此值不会丢失。
以下是观点:
<h:form>
<f:validateBean disabled="#{!empty param['disableValidation']}">
<h:commandButton value="Añadir Fila" action="#{tablaController.addRowAction}">
<f:param name="disableValidation" value="true" />
</h:commandButton>
<h:dataTable value="#{tablaController.lista}" var="fila" cellpadding="0" cellspacing="0" border="1">
<f:facet name="header">TABLA</f:facet>
<h:column>
<f:facet name="header"><h:outputLabel value="NOMBRE" /></f:facet>
<h:inputText id="nom" value="#{fila.nombre}" />
<h:message for="nom" class="msjError" />
</h:column>
<h:column>
<f:facet name="header"></f:facet>
<h:commandButton value="Quitar Fila" action="#{tablaController.removeRowAction(fila)}">
<f:param name="disableValidation" value="true" />
</h:commandButton>
</h:column>
</h:dataTable>
<h:commandButton value="Submit" action="#{tablaController.saveData}" />
</f:validateBean>
</h:form>
支持bean:
@ManagedBean(name="tablaController")
@ViewScoped
public class TablaController {
private List<Fila> lista;
...
public TablaController() { }
...
@PostConstruct
public void init() {
this.lista = new ArrayList<Fila>();
for (int i=0; i<5; i++) {
Fila fila = new Fila();
fila.setNombre("fila "+i);
this.lista.add(i,fila);
}
}
...
public String addRowAction () {
Fila fila = new Fila();
fila.setNombre("");
this.lista.add(fila);
return "";
}
public String removeRowAction (Fila f) {
this.lista.remove(f);
return "";
}
...
public String saveData () {
...
//processes the valid data
//for example, calls to a service method to store them in a database
...
return "";
}
...
}
答案 0 :(得分:2)
我在按钮中将immediate属性设置为“true”,以便在添加或删除行时不验证输入字段。
immediate="true"
是错误的工具。它应该用于优先级验证,而不是启用/禁用验证。你遇到自己时,差异非常大。
您希望有条件地触发验证。在例如required="true"
就像
<h:inputText ... required="#{saveButtonPressed}" />
其中#{saveButtonPressed}
在按下保存按钮时评估true
。例如。当客户端ID出现在请求参数映射中时。
在JSR 303 bean验证的情况下,这是
的问题<f:validateBean disabled="#{not saveButtonPressed}">
<h:inputText ... />
</f:validateBean>
或OmniFaces <o:validateBean>
允许在每个命令的基础上控制它。
<h:commandButton id="add" ...>
<o:validateBean disabled="true" />
</h:commandButton>
答案 1 :(得分:0)
我有完全相同的问题。简而言之,您不能立即使用更新数据表(UIData)或facelet重复的操作。简短说明:如果UIData中的输入未通过验证,则不会保留提交的值以供重新显示。可在此处找到详细说明:long explanation和a related bug in Mojarra