JSF datatable:添加和删除行清除行值 [英] JSF datatable: adding and removing rows clear rows values

查看:262
本文介绍了JSF datatable:添加和删除行清除行值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有啊:datatable显示行的列表,每行的字段是输入字段。



我在表之前渲染添加行按钮,和表的每一行上的删除行按钮。



烘焙bean是viewScoped,并且按钮从后台的java列表中添加/删除元素bean,然后返回到相同的视图。



我将button中的immediate属性设置为true,以便在添加或删除时无法验证输入字段一行。



一切正常,但有一件事情:输入文件的值被清除。我认为这个视图保持了值beacuse的bean是viewScoped。



如何实现添加/删除行而不触发验证并保留已经输入的值用户的形式?



我的观点:

 < h :形式> 
< h:commandButton value =AñadirFilaimmediate =trueaction =#{tablaController.addRowAction}/>
< h:dataTable value =#{tablaController.lista}var =filacellpadding =0cellspacing =0border =1>
< f:facet name =header> TABLA< / f:facet>
< h:column>
< f:facet name =header>< h:outputLabel value =NOMBRE/>< / f:facet>
< h:inputText id =nomvalue =#{fila.nombre}/>
< h:message for =nomclass =msjError/>
< / h:column>
< h:column>
< f:facet name =header>< / f:facet>
< h:commandButton value =Quitar Filaimmediate =trueaction =#{tablaController.removeRowAction(fila)}/>
< / h:column>
< / h:dataTable>
< / h:form>

我的支持bean:

  @ManagedBean(name =tablaController)
@ViewScoped
public class TablaController {

private List< Fila>清单
...
public TablaController(){}
...
@PostConstruct
public void init(){
this.lista = new ArrayList< ; Fila>(); (int i = 0; i <5; i ++){
Fila fila = new Fila();

fila.setNombre();
this.lista.add(我,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;
}
...
}

更新 - >我的解决方案:



如果有人感兴趣,我在这里写下我的解决方案。



问题是我使用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ñadirFilaaction =#{tablaController.addRowAction}>
< f:param name =disableValidationvalue =true/>
< / h:commandButton>
< h:dataTable value =#{tablaController.lista}var =filacellpadding =0cellspacing =0border =1>
< f:facet name =header> TABLA< / f:facet>
< h:column>
< f:facet name =header>< h:outputLabel value =NOMBRE/>< / f:facet>
< h:inputText id =nomvalue =#{fila.nombre}/>
< h:message for =nomclass =msjError/>
< / h:column>
< h:column>
< f:facet name =header>< / f:facet>
< h:commandButton value =Quitar Filaaction =#{tablaController.removeRowAction(fila)}>
< f:param name =disableValidationvalue =true/>
< / h:commandButton>
< / h:column>
< / h:dataTable>
< h:commandButton value =Submitaction =#{tablaController.saveData}/>
< / f:validateBean>
< / h:form>

支持bean:

  @ManagedBean(name =tablaController)
@ViewScoped
public class TablaController {

private List< Fila>清单
...
public TablaController(){}
...
@PostConstruct
public void init(){
this.lista = new ArrayList< ; Fila>(); (int i = 0; i <5; i ++){
Fila fila = new Fila();

fila.setNombre(fila+ i);
this.lista.add(我,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(){
...
//处理有效数据
//例如,调用一种将数据存储在数据库中的服务方法
...
return;
}
...
}


解决方案


我在按钮中将immediate属性设置为true,以便在添加或删除行时无法验证输入字段。


immediate =true是作业的错误工具。应该用于确定优先级,而不是启用/禁用验证。你遇到自己的区别是相当大的。



你想有条件地触发验证。在例如 required =true,这将像

  ; h:inputText ... required =#{saveButtonPressed}/> 

其中#{saveButtonPressed} 评估<$当按下保存按钮时,c $ c> 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>


I have a h:datatable showing a list of rows, and the fields of each row are input fields.

I render an "Add Row" button before the table, and a "Remove Row" button on each row of the table.

The baking bean is viewScoped, and the buttons add/remove elements from the java list in the backing bean, and then return to the same view.

I set the immediate attribute to "true" in the buttons in order to not validate the input fields when I add or remove a row.

Everything works ok but one thing: the values of the input fileds are cleared. I thought that the view kept the values beacuse the bean is viewScoped.

How can I achieve adding/removing rows without triggering validations and keeping the values that were already typed by the user in the form?

My view:

<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>

My backing 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 "";
}
...
}

UPDATE --> MY SOLUTION:

I write here my solution if someone is interested.

The problem is that I use immediate="true" to skip validations, but this makes to skip the update_model_values too, so that the values entered by the user in the form are lost after clicking the add/remove buttons and re-redenring the page.

As I use "JSR-303 bean validation", my solution was to skip validations using the f:validateBean to enable/disable them. Depending on the button I click, if I want the validations to execute, I enable the bean validation (for example in a "submit" button), and if I want to skip them, I disable bean validation (like in the add/remove row buttons). But anyway the update_model_values always executes, so the values are not lost.

Here's the view:

<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>

The backing 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 "";
}
...
}

解决方案

I set the immediate attribute to "true" in the buttons in order to not validate the input fields when I add or remove a row.

immediate="true" is the wrong tool for the job. It should be used to prioritize validation, not to enable/disable validation. The difference is rather huge as you encountered yourself.

You want to trigger validation conditionally. In case of e.g. required="true" that'd be as easy as

<h:inputText ... required="#{saveButtonPressed}" />

where #{saveButtonPressed} evaluates true when the save button is pressed. E.g. when its client ID is present in request parameter map.

In case of JSR 303 bean validation, that'd be a matter of

<f:validateBean disabled="#{not saveButtonPressed}">
    <h:inputText ... />
</f:validateBean>

or with OmniFaces <o:validateBean> which allows controlling that on a per-command basis.

<h:commandButton id="add" ...>
    <o:validateBean disabled="true" />
</h:commandButton>

这篇关于JSF datatable:添加和删除行清除行值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆