【问题标题】:PrimeFaces radiobutton styles not updating when clicked via Javascript通过 Javascript 单击时 PrimeFaces 单选按钮样式未更新
【发布时间】:2016-11-07 07:31:50
【问题描述】:

我有一个 p:selectOneRadio 设置如下:

<p:selectOneRadio id="positionRadio" value="#{employeeBean.empPosition}" converter="#{empPositionConverter}" layout="custom"
                    required="true" requiredMessage="Please select a position">
    <f:selectItems value="#{employeeBean.positionList}" var="pos"
                                itemLabel="#{pos.name}" itemValue="#{pos}" />
    <p:ajax process="@this" update="@this"/>
</p:selectOneRadio>

<ui:repeat id="iterator" value="#{employeeBean.positionList}" var="template" varStatus="iterStat">
    <div class="form-group" onclick="document.getElementById('employeeForm:positionRadio:#{iterStat.index}').click();">
        <h:outputText styleClass="form-control" value="#{pos.name}"/>
        <p:radioButton for=":employeeForm:positionRadio" itemIndex="#{iterStat.index}" />
        <div style="display: inline">
            <p style="display: inline">
                <h:outputText value="#{pos.description}"/>
            </p>
        </div>
    </div>
</ui:repeat>

如果单击了包含它的 div 中的任何内容,我需要检查相应的单选按钮。我正在尝试使用

onclick="document.getElementById('employeeForm:positionRadio:#{iterStat.index}').click();"

这只是工作了一半。当我单击 div 时,我确实看到了 POST 请求触发,但是样式没有更新,所以我的单选按钮都没有被检查客户端。

这当然是因为 p:radioButton 被呈现为具有隐藏输入单选元素和相应样式的可见跨度的 div。为什么通过javascript点击时span样式没有更新,有办法解决吗?

使用 JSF 2.1.7、PrimeFaces 5.0 和 Java 1.7

【问题讨论】:

    标签: javascript css jsf primefaces


    【解决方案1】:

    您似乎点击了“错误”的 html 元素。如果您查看生成的&lt;p:radioButton... 的 id,例如custom layout example in the PrimeFaces showcase中的第一个按钮:

    <div id="j_idt88:opt1" class="ui-radiobutton ui-widget">
        <div class="ui-helper-hidden-accessible">
            <input value="Red" id="j_idt88:customRadio:0_clone" name="j_idt88:customRadio" class="ui-radio-clone" data-itemindex="0" type="radio">
        </div>
        <div class="ui-radiobutton-box ui-widget ui-corner-all ui-state-default">
            <span class="ui-radiobutton-icon ui-icon ui-icon-blank ui-c"></span>
        </div>
    </div>
    

    然后在 div 下方创建一个带有“ui-widget”类的点击

    所以

    $('#j_idt88\\:opt1 .ui-widget').click();  # The \\ is for escaping the colon in the jQuery selector)
    

    然后就可以了。我试过这个并在 PrimeFaces 6.0 展示中进行了测试

    如果您没有明确分配 id,您可能需要使用自己的 id 或查看生成的 id 中是否存在一些逻辑。

    【讨论】:

    • 嗯,这对我不起作用(我使用 Primefaces 5.0,但也快速升级到 6.0 进行测试)。我会创建一个测试环境来弄清楚我的问题是什么,但我可能只能下周才能回复。
    • “不工作”是最终用户描述。幕后发生了什么?在例如浏览器中的开发者控制台。下次请在问题中添加版本信息。 PF 版本中的情况可能有所不同,这可以节省我花在旧版本上的时间...
    • 很抱歉没有包含版本号,完全忘记了。我说当时不工作是因为我想以某种方式让人们知道我已经看到了答案(不希望人们认为我不再参与其中,并且可能会失去一个很好的讨论)。我检查了开发控制台,那里没有任何反应,没有日志,没有 POST,什么也没有,好像 div 在单击时没有任何操作。我确实想建立一个独立的项目,看看我是否可以复制你的解决方案或我的问题,但恐怕下周只有时间了。
    • 没问题。祝你好运
    • 好的,所以我设置了一个全新的工作区来测试它。使用普通的 javascript 只是单击该 div 并没有做任何事情。如果我使用 jQuery 选择器提供的样式确实会发生变化,但我看不到任何 POST 请求将值更新到后端。我添加了一个 h:outputText 和一个按钮来测试以防 firebug/mozilla 开发控制台错过请求,但后端的值没有更新。您能否确认该值确实会在后端为您更新?
    【解决方案2】:

    我一直在进一步解决这个问题并找到了解决方案。 我仍然更喜欢不同的,但我目前的解决方案是通过 javascript 手动更新样式。

    首先,我在 ui:repeat 之外添加了一个隐藏的输入字段来跟踪之前单击的单选按钮索引

    <input type="hidden" name="prevClicked" id="prevClicked" value="-1"/>
    

    我还给了 ui:repeat 中的 p:radioButton 一个 raBtn 的 id 并将 onclick javascript 移动到一个函数中,如下所示

    function radioBtnDivClicked(event, radioIndex){
        // check prevClicked field to revert styles if necessary
        if(document.getElementById('prevClicked').value != -1){
            var prevIndex = document.getElementById('prevClicked').value;
            document.getElementById('employeeForm:iterator:' + prevIndex + ':raBtn').children[1].className = 'ui-radiobutton-box ui-widget ui-corner-all ui-state-default';
            document.getElementById('employeeForm:iterator:' + prevIndex + ':raBtn').children[1].children[0].className = 'ui-radiobutton-icon ui-icon ui-icon-blank';
        }
    
        // set styles for clicked div
        document.getElementById('employeeForm:positionRadio:' + radioIndex).click();
        document.getElementById('employeeForm:iterator:' + radioIndex + ':raBtn').children[1].className = 'ui-radiobutton-box ui-widget ui-corner-all ui-state-default ui-state-active';
        document.getElementById('employeeForm:iterator:' + radioIndex + ':raBtn').children[1].children[0].className = 'ui-radiobutton-icon ui-icon ui-icon-bullet';
        document.getElementById('prevClicked').value = radioIndex;
    
        // stop bubbling
        event.stopPropagation();
    }
    

    转换成 jQuery 应该相当简单。

    另外我只改onclick到

    onclick="radioBtnDivClicked(event,#{iterStat.index});"
    

    这可行,但我更喜欢单选按钮在直接单击时的行为(即 Primefaces 处理样式更改)的解决方案。

    【讨论】:

      猜你喜欢
      • 2013-04-17
      • 2021-07-16
      • 1970-01-01
      • 2019-02-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多