当通过Javascript点击时,PrimeFaces单选按钮样式不更新

PrimeFaces radiobutton styles not updating when clicked via Javascript

本文关键字:单选按钮 PrimeFaces 样式 更新 Javascript      更新时间:2023-09-26

我有一个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,带有一个隐藏的输入单选元素和一个相应样式的可见span。为什么跨度风格不更新时,通过javascript点击,有没有办法解决它?

使用JSF 2.1.7, PrimeFaces 5.0和Java 1.7

我一直在进一步研究这个问题,并有一个解决方案。我仍然喜欢一个不同的,但我目前的解决方案是通过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处理样式变化)。

您似乎正在点击'错误'的html元素。如果你查看生成的<p:radioButton...的id,例如,PrimeFaces展示中自定义布局示例中的第一个按钮:

<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上创建一个click,并在其下面添加ui-widget类

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

那就行了。我在PrimeFaces 6.0中进行了测试

你可能需要使用你自己的id,或者如果你没有显式地分配id,看看在生成的id中是否有一些逻辑。