在h:dataTable中重新呈现具有相同id的所有h:inputText字段

时间:2014-11-19 21:21:42

标签: ajax jsf

我想我浪费时间再次弄清楚如何在JSF中做这么简单的事情,但假设以下设置:

 <h:form id="form">
    <h:dataTable id="table">
        <! -- not shown: other columns with other input fields -->
        <h:column>
          <h:inputText id="myinput">
                <f:ajax execute="@this" render="????" listener="#{bean.action}" />
          </h:inputText> 
        </h:column>
    </h:dataTable>
</h:form>

我在渲染标记中指定什么才能重新渲染所有&#34; myinput&#34;数据表中所有行的组件,即没有指定&#34; @ form&#34;那将重新渲染其他组件?我试过@this和&#34;:form:table:myinput&#34;,但它总是只重新渲染dataTable的第一行。看起来这应该是一个简单的用例,所以我显然必须误解一些东西。

注意:我不知道内部JSF是为每一行创建N HtmlInputTextComponents还是仅为1,但显然当我说&#34;所有myinput组件&#34;时,我的意思是所有渲染的输入字段都返回到从h:inputText标记生成并且具有相同浏览器DOM id的浏览器:table:myinput:n。

作为一个推论和附加问题,由于可能的验证/转换错误,我不想处理或重新呈现整个表单组件。我只想要发生以下事情:只有发起&#34; myinput&#34;触发ajax调用的组件被验证,如果成功,则所有其他&#34; myinput&#34;组件被填充并随后使用从动作侦听器更改的新模型值重新呈现&#34;#{bean.action}&#34;。

其他信息: 我目前正在使用JSF 2.1的mojarra实现版本(我认为)。我想避免任何第三方JSF库。

奖金问题(也许我原来问题的答案也可以回答):

  
      
  1. 如何重新渲染和/或执行所有输入组件,但仅限于单行
  2.   
  3. 如何重新渲染和/或执行一组输入组件,但仅限于单行
  4.   
  5. 如何为一组行(不是全部)重新呈现和/或执行所有输入组件
  6.   
  7. 如何为一组行(不是全部)重新呈现和/或执行一组输入组件
  8.   

每个人都回复说我可以根据当前的rowIndex或当前迭代变量设置inputText的id - NO,这不起作用。请参阅:Set id of a component within JSF dataTable to value from current item in the array

我真的认为实现我想要的唯一方法是放弃使用数据表并使用JSTL自己渲染表列/ rpws,这样我就可以分配唯一ID并拥有完全控制权。但是,我仍然认为这是JSF中一个巨大的设计缺陷,不支持这种看似简单的用例。

2 个答案:

答案 0 :(得分:3)

  

我在render标记中指定什么才能在数据表中的所有行上重新渲染所有“myinput”组件,即不指定将重新渲染其他组件的“@form”? / em>的

     

TL; DR:如何重新渲染整个列?

使用标准JSF工具无法做到这一点。您基本上需要(自动)根据行数/索引自行生成客户端ID form:table:0:myinputform:table:1:myinputform:table:2:myinput等的集合,并手动将它们全部添加到{{3在#{bean.action}期间收集。由于在JSF组件树PartialViewContext#getRenderIds()中不存在这些客户端ID,因此无法在render属性中指定它们(因此您最终会混淆“无法找到客户端ID”异常)。

我知道你想要避免使用第三方库,但是but JSF strictly wants to validate them OmniFaces提供了这个功能,它只将表组件和(从零开始)列索引作为参数。 E.g。

public void action() {
    // ...
    UIData table = Components.findComponent("form:table");
    Ajax.updateColumn(table, 2); // Updates third column.
}

如果OmniFaces的其余部分不够方便不再将其视为“普通”第三方库,请随意借用/窃取/改进Apache 2.0许可下的Ajax#updateColumn()

顺便提一下,OmniFaces未来版本的队列可能会增强,这必须使这类要求更加适合头发:source


  
      
  • 如何重新渲染和/或执行所有输入组件,但仅限于一行?
  •   
  • 如何重新渲染和/或执行一组输入组件,但仅限于一行?
  •   

您可以使用相关客户端ID在render属性中指定它们,如下所示:

<h:column><h:inputText id="input1" ... /></h:column>
<h:column><h:inputText id="input2" ... /></h:column>
<h:column><h:inputText id="input3" ... /></h:column>
<h:column><h:inputText id="input4" ...><f:ajax render="input1 input2 input3" ... /></h:inputText></h:column>

注意:没有办法明确说出“所有输入组件”。你必须单独指定它们。如果您碰巧使用PrimeFaces,或者可以使用它,那么event driven updates会使这更容易。另见其他PrimeFaces Selectors


  
      
  • 如何为一组行(不是全部)重新呈现和/或执行所有输入组件
  •   
  • 如何为一组行(不是全部)重新呈现和/或执行一组输入组件
  •   

此外,没有标准设施。您可以扩展前面提到的Ajax#updateColumn()源代码。关键问题是您希望更新其他行,而不仅仅是当前行。为此,您确实需要(自动)生成完整的客户端ID并将其添加到PartialViewContext#getRenderIds()

答案 1 :(得分:-2)

<h:form id="form">
    <h:dataTable id="table" rowIndexVar="idx">
        <! -- not shown: other columns with other input fields -->
        <h:column>
          <h:inputText id="myinput#{idx.index}">
                <f:ajax execute="@this" render="????" listener="#{bean.action}" />
          </h:inputText> 
        </h:column>
    </h:dataTable>
</h:form>

使用firebug,您可以看到所有输入现在都有id。现在,您可以根据此ID将您想要的内容放入渲染中。

你必须使用

RequestContext.getCurrentInstance().update(lstIndex);

在您的java代码中 lstIndex 是您要更新的ID列表