【问题标题】:How to render a h:panelGroup inside ui:repeat based on value from javascript?如何根据来自 javascript 的值在 ui:repeat 中呈现 h:panelGroup?
【发布时间】:2012-11-22 01:50:55
【问题描述】:

我将布尔值放入<h:inputText>,但找不到将其放入<h:panelGroup>rendered 属性的方法。我也没有看到使用 bean 值的方法,因为每次迭代都需要一个独立的值。

这是我的 jsf 代码:

<ui:repeat var="item" value="#{itemBean.items}" id="iterateItems" varStatus="iteration">
    <script type="text/javascript">         
        showItem("#{item.id}","#{iteration.index}");
    </script>
    <h:inputText id="rendered"/>
    <h:panelGroup layout="block" rendered="???">
        Iteration #{iteration.index} rendered
    </h:panelGroup>
</ui:repeat>

这是我的javascript:

function showItem(item,iteration){
    if((clientSideValue==something){
        document.getElementById("iterateItems"+":"+iteration+":"+"rendered").value = true;
    }
    else{
        document.getElementById("iterateItems"+":"+iteration+":"+"rendered").value = false;
    }
}

【问题讨论】:

    标签: javascript jsf jsf-2 el rendered-attribute


    【解决方案1】:

    JavaScript 在客户端运行并在从服务器端检索的 HTML DOM 树上工作(在您的特定情况下由 JSF 生成)。因此,JavaScript 期望您想要显示/隐藏的所需 HTML 元素始终存在于 HTML DOM 树中。

    JSF 在服务器端运行并基于 JSF 组件树(“视图”)生成 HTML 代码。当 JSF 组件的 rendered 属性评估为 false 时,不会为给定组件生成任何 HTML 代码,因此 HTML DOM 树中不会有任何内容,因此 JavaScript 的 @987654323 将无法选择任何内容@。

    您认为这是解决方案的具体功能要求尚不清楚,因此很难为您的具体问题提出正确的解决方案。但是,如果您绝对肯定需要在客户端(通过 JavaScript)而不是服务器端(通过 JSF)执行显示/隐藏,那么您应该为此使用 CSS 的 display 属性可以在blocknone 之间切换。

    这是一个基本的启动示例,假设您最初想隐藏它:

    <ui:repeat var="item" value="#{itemBean.items}" id="iterateItems" varStatus="iteration">
        <script type="text/javascript">         
            showItem(#{iteration.index});
        </script>
        <h:inputText id="rendered" />
        <div id="foo#{iteration.index}" style="display:none">
            Iteration #{iteration.index} shown
        </div>
    </ui:repeat>
    

    function showItem(index) {
        var div = document.getElementById("foo" + index);
    
        if (someCondition) {
            div.style.display = "block"; // Show it.
        } else {
            div.style.display = "none"; // Hide it.
        }
    }
    

    【讨论】:

    • 感谢您的回答。我可以立即应用您的代码。我对自己依赖客户数据并不感到高兴。其实我使用谷歌地图javascript api的距离矩阵服务。这必须在客户端执行,并且提供的数据应该改变我的页面上显示的元素。
    【解决方案2】:

    不要将服务器端脚本与客户端脚本混用!

    随心所欲地使用 EL:

    <ui:repeat var="item" value="#{itemBean.items}" id="iterateItems" varStatus="iteration">
        <h:panelGroup layout="block" rendered="#{item.id le 1}">
            Iteration #{iteration.index} rendered
        </h:panelGroup>
    </ui:repeat>
    

    【讨论】:

    • 首先,谢谢您的回答。我总是发现自己过度简化了代码。实际上javascript在客户端计算一些东西,服务器“不知道”。现在我希望服务器以某种方式“读取”&lt;h:inputText&gt; 的值并将其用于当前迭代的&lt;h:panelGroup&gt;rendered-属性。
    • 我更新了我的问题以明确我们需要来自客户端的一些数据。
    • 好的,你用 BalusC 的方式解决了问题,但是你可以做我建议的事情,而不需要 javascript - 你会得到你所要求的,除非你依赖于其他逻辑正如 BalusC 指出的那样,它没有带给我们。无论如何,谢谢你.. ^^ 很高兴看到你解决了。
    • 好的,谢谢!很抱歉没有在代码和问题描述中更清楚地说明我在标题中提出的问题,从而误导了您。
    【解决方案3】:

    这是不可能的:JSF 标记 - 尤其是渲染的属性在 JSF 的 RenderResponse 阶段使用。当最终的 HTML 生成后,没有更多的 rendered 属性 - 包含该属性的 HTML 元素要么被渲染,要么不被渲染。

    因此,如果您需要根据客户端的值执行某些操作,则需要将该值传输到您的服务器。

    解决方法是设置 css 属性 display:none。但请注意,这将不会显示元素。它仍然在页面源中可用。

    如果您正在使用 Javascript,您应该真正查看最终的源代码。解析 JSF 标记,甚至像 23:58:23 这样的自动生成的 ID 对于某个元素并不总是相同的。

    【讨论】:

    • 感谢您的回答。我选择 BalusC 的答案是因为它提供了我可以立即应用的代码,尽管您的理论课也绝对很有帮助和启发性。
    猜你喜欢
    • 2020-02-28
    • 2012-03-01
    • 1970-01-01
    • 2013-12-03
    • 1970-01-01
    • 2017-06-21
    • 1970-01-01
    • 2020-11-15
    • 1970-01-01
    相关资源
    最近更新 更多