【问题标题】:JSF disable inputbox with a checkbox in a ui:repeat on a composite componentJSF 使用 ui 中的复选框禁用输入框:在复合组件上重复
【发布时间】:2015-08-13 17:12:44
【问题描述】:

我如何从<h:selectBooleanCheckbox> 中引用<h:inputBox>,它们位于<ui:repeat> 和复合组件的一部分中,以便我可以禁用输入框并将其变灰,如下面的屏幕截图所示?

<ui:repeat var="qAndA" value="#{cc.attrs.checklist.answer_attribute_list}">
   <td class="chklist"><h:selectBooleanCheckbox  onclick="toggleBox(this, qty_#{qAndA.attribute.attribute_id})" value="#{qAndA.na_value}"> </h:selectBooleanCheckbox></td>
   <td class="chklist"><h:inputText value="#{qAndA.quantity}" id="qty_#{qAndA.attribute.attribute_id}" /></td>

生成此 HTML

<input id="j_idt48:2:j_idt94:j_idt94:j_idt167:j_idt171:1:qty_" type="text" name="j_idt48:2:j_idt94:j_idt94:j_idt167:j_idt171:1:qty_" value="6" />

我的qty_#{qAndA.attribute.attribute_id} 被截断为qty_

我试过了

<h:selectBooleanCheckbox  onclick="toggleBox(this, #{cc.attrs.id}_qty)"  value="#{qAndA.na_value}"></h:selectBooleanCheckbox>
<h:inputText value="#{qAndA.quantity}" size="3" maxlength="3" id="#{cc.attrs.id}_qty"/>

我正在尝试将这个旧的 jsp 重构为 JSF:

原始 JSP 包括:

<SCRIPT>
   function toggleBox(checkName, quantityName) {
      if(checkName.checked) {
         quantityName.disabled=true;
         quantityName.style.backgroundColor="#808080"; 

      } else {
         quantityName.disabled=false;
         quantityName.style.backgroundColor="#FFFFFF"; 
      }
   }
</SCRIPT>

<c:forEach var="qAndA" items="${checklist.answer_attribute_list}">
<c:choose>
   <c:when test="${empty qAndA.na_value || qAndA.na_value == '0'}">
     <td class="chklist"><input type="checkbox" name="check_<c:out value="${qAndA.attribute_id}" />" onclick="toggleBox(this, qty_<c:out value="${qAndA.attribute_id}" />)" value="1"></td>
     <td class="chklist"><input name="qty_<c:out value="${qAndA.attribute_id}" />" type="text" value="<c:out value="${qAndA.quantity}" />" ></td>
  </c:when>

并生成此 HTML

<td class="chklist"><input type="checkbox" name="check_1346788339807" onclick="toggleBox(this, qty_1346788339807)" value="1"></td>
<td class="chklist"><input name="qty_1346788339807" type="text" value="6" size="3" maxlength="3"></td>

编辑

quantity_checklist.xhtml 复合组件。侦听器在checklist.receiving_email 上被调用,但不是在它是迭代的一部分时,无论我使用数据表还是 ui:repeat

<p:selectBooleanCheckbox value="#{cc.attrs.checklist.receiving_email}">
    <p:ajax listener="#{checklistEdit.listenerTest()}" />
</p:selectBooleanCheckbox>
<h:dataTable var="qnA" value="#{cc.attrs.checklist.answer_attribute_list}">
    <p:column>
       <p:selectBooleanCheckbox value="#{qnA.na_value}">
      <p:ajax render="qty" listener="#{checklistEdit.listenerTest}" update="@all"/>
   </p:selectBooleanCheckbox>
 </p:column>
 <p:column>
    <h:inputText value="#{qnA.quantity}" id="qty" disabled="#{qnA.na_value}" />
 </p:column>
 </h:dataTable>

编辑 2

recap:尝试使用复合材料在输入框中禁用和变灰的动态复选框数组,但除非我将代码移出复合材料,否则没有运气。下面是使用复合的代码(与How to refactor snippet of old JSP to some JSF equivalent?相关):

WorkItem.xhtml

<ui:repeat var="actionItem" value="#{workItemController.wfiwi.work_action_list}">

<ui:fragment rendered="#{actionItem.workActionClass.workActionType.action_type_id == '2'}">
     <stk:dynamic_checklist actionItem="#{actionItem}" checklist="#{actionItem.meat}" />
</ui:fragment>

dynamic_checklist.xhtml 复合

<ui:fragment rendered="#{cc.attrs.checklist.checkListClass.type == '3'}">
    <stk:quantity_checklist actionItem="#{cc.attrs.actionItem}" checklist="#{cc.attrs.checklist}" />
</ui:fragment>

quantity_checklist.xhtml 复合在我的第一次编辑中显示在上面

如果我将 quantity_checklist 代码上移到 WorkItem.xhtml 文件中,则 ajax 更新有效,并且 Qty 输入框灰显并禁用。但这不适用于复合组件。

编辑 3

见下面的代码...接收电子邮件复选框上的 ajax 更新正确地影响 id ddd 和 poppy 但 qnA.na_value ajax 更新不是这样。换句话说,我在屏幕截图中选中了 Qty 6 旁边的 N/A 复选框,监听器被触发并且我在监听器中设置的 primefaces 消息被显示。但是输入框仍然处于活动状态并且没有变灰。但是,如果我随后切换接收电子邮件复选框,它的侦听器被触发,标题消息出现,AND 屏幕截图中 6 旁边的数量框现在变为灰色并被禁用。

<h:panelGroup id="ccc">
    <p:selectBooleanCheckbox value="#{cc.attrs.checklist.receiving_email}">
        <p:ajax listener="#{checklistEdit.listenerTest()}" update="ddd,poppy" />
    </p:selectBooleanCheckbox>
</h:panelGroup>
<h:panelGroup id="ddd">
    <h:outputText value="Email Checkbox:"></h:outputText>
    <h:outputText value="#{cc.attrs.checklist.receiving_email}" />
</h:panelGroup>

<h:dataTable var="qnA" value="#{cc.attrs.checklist.answer_attribute_list}" id="poppy">
    <p:column headerText="NA">
        <p:outputLabel id="navalue" value="#{qnA.na_value}"></p:outputLabel>
    </p:column>
    <p:column headerText="NA Checkbox">
        <p:selectBooleanCheckbox value="#{qnA.na_value}">
            <p:ajax listener="#{checklistEdit.checkBoxListenerTest}" update="poppy" />
        </p:selectBooleanCheckbox>
    </p:column>
    <p:column headerText="Quantity">
        <h:inputText value="#{qnA.quantity}" id="qty" disabled="#{qnA.na_value}" />
    </p:column>
</h:dataTable>

【问题讨论】:

    标签: javascript jsf


    【解决方案1】:

    我的qty_#{qAndA.attribute.attribute_id} 被截断为qty_,更不用说所有其他前置的JSF id,这是因为复合组件是另一个复合组件的子组件,并且两个组件都使用&lt;ui:fragement&gt; 有条件地包含在内。 /em>

    没有。这是因为#{qAndA} 仅在视图渲染期间可用,而不是在视图构建期间可用。 &lt;ui:repeat&gt; 在视图渲染期间运行。如果您使用了&lt;c:forEach&gt;,那么它会按您预期的方式工作。但是,正如您的previous question 所指出的那样,您可能由于被限制在旧的 Mojarra 2.1.7 中而遗憾地不使用 JSTL 以您想要的方式动态构建视图。

    但毕竟,您不需要像那样手动使 ID 动态化。只需指定一个固定的 ID。

    <h:inputText id="qty" ... />
    

    &lt;ui:repeat&gt; 将自动在 ID 中添加迭代索引。另见How to use EL with <ui:repeat var> in id attribute of a JSF component。


    我如何从 &lt;h:selectBooleanCheckbox&gt; 中引用 &lt;h:inputText&gt;,它们位于 &lt;ui:repeat&gt; 和 custom 复合组件的一部分中,以便我可以禁用输入并将其变灰如下图所示的框

    只需将输入的 disabled 属性设置为复选框的值,并使用 JSF 提供的 ajax 工具在复选框被切换时更新输入:

    <h:selectBooleanCheckbox value="#{qAndA.na_value}">
        <f:ajax render="qty" />
    </h:selectBooleanCheckbox>
    ...
    <h:inputText id="qty" value="#{qAndA.quantity}" disabled="#{qAndA.na_value}" />
    

    不需要额外的 JS。对于样式,只需将其放入普通的 CSS 文件中即可:

    input[disabled] {
        background-color: #808080;
    }
    

    否则,如果输入最初被禁用,并且您在没有通知 JSF 的情况下使用 JavaScript 重新启用它(通过例如&lt;f:ajax&gt;),那么 JSF 将作为防止被黑请求的一部分仍然拒绝提交的值。另见How to disable/enable JSF input field in JavaScript?


    与具体问题无关,您似乎想使用 &lt;ui:repeat&gt; 呈现 HTML &lt;table&gt;。您是否考虑过改用&lt;h:dataTable&gt;?它应该减少一些 HTML 样板。而且,在那个旧的 Mojarra 版本中,它具有更强大的状态保存功能,而众所周知,&lt;ui:repeat&gt; 在带有 ajax 内容的复杂视图中到处都有错误。

    【讨论】:

    • 嗯。该复选框不影响输入框,我得到“表单组件需要在其祖先中有一个 UIForm。建议:将必要的组件包含在
      中”但我确实有一个 包装 CC.
    • 我刚刚注意到,如果我在“#{qAndA.na_value}”的设置器上放置了一个调试标记,当我单击复选框时它永远不会被调用。我假设这就是 inputText 永远不会被禁用的原因,但我不知道为什么不会调用 setter。
    • 在浏览器中按 F12 并检查控制台。有什么线索吗?
    • 在迭代期间为“#{qAndA.na_value}”调用getter。但是当我点击复选框时不应该调用setter吗?
    • 如果没有 f:ajax,表单是否可以正常工作?如果是这样,这表明您的 ui:repeat 构造对该状态保存错误很敏感。尝试改用 h:dataTable。
    【解决方案2】:

    修复是在ui:repeat 上使用p:dataTable ...并在ajax 更新上使用@form。我觉得自从 BalusC 向我透露了 ui:repeat 错误后,我会接受他的回答,因为它最有帮助。但这是有效的

    <composite:implementation>
    
      <p:dataTable id="table" value="#{cc.attrs.checklist.answer_attribute_list}" var="qnA">
        <p:column headerText="NA" width="50px;">
          <p:selectBooleanCheckbox value="#{qnA.not_applicable}">
            <p:ajax listener="#{checklistEdit.checkBoxListenerTest}" update="@form" />
          </p:selectBooleanCheckbox>
    
          <h:outputText value="X" rendered="#{qnA.not_applicable}" />
    
        </p:column>
    
    
        <p:column headerText="Quantity" width="75px;">
           <h:inputText value="#{qnA.quantity}" id="qty" rendered="#{qnA.not_applicable == false}" size="1" />
           <h:outputText value="#{qnA.quantity}" rendered="#{qnA.not_applicable == false}" />
    
           <h:outputText value="-" rendered="#{qnA.not_applicable}" />
    
        </p:column>
    
    </p:dataTable>
    

    【讨论】:

      猜你喜欢
      • 2012-07-30
      • 1970-01-01
      • 2014-12-12
      • 2022-01-08
      • 2023-04-04
      • 1970-01-01
      • 2011-04-03
      • 2017-11-12
      • 1970-01-01
      相关资源
      最近更新 更多