jsf - 使用 twitter bootstrap 的单选按钮 - 无法获取值

标签 jsf twitter-bootstrap radio-button

我浏览过SO,并找到了一些答案,这些答案 Bootstrap 我更接近使用单选按钮,但我现在陷入困境。

我有按钮,但无法获取所选按钮的值。

我使用的是 JSF,因此 #{searchFlightsBean.setDir()}

这是我目前拥有的:

<h:panelGrid>
    <div class="btn-group" data-toggle-name="is_private" data-toggle="buttons-radio" >
        <button type="button" value="0" class="btn" data-toggle="button">Public</button>
        <button type="button" value="1" class="btn" data-toggle="button">Private</button>
    </div>
    <h:inputHidden id="hiddenDir" value="0" valueChangeListener="#{searchFlightsBean.setDir()}"  onchange="submit()"/>
</h:panelGrid>

<script>
$(function() {
    $('div.btn-group[data-toggle-name]').each(function() {
        var group = $(this);
        var form = group.parents('form').eq(0);
        var name = group.attr('data-toggle-name');
        var hidden = $('input[name="' + name + '"]', form);
        $('button', group).each(function() {
            var button = $(this);
            button.on('click', function() {
                hidden.val($(this).val());
            });
            if (button.val() == hidden.val()) {
                button.addClass('active');
                #{searchFlightsBean.setDir(button.value)}
            }
        });
    });
});
</script>

在我的 bean 中,当调用 setDir() 时,我会记录它接收到的值,如下所示:

public void setDir(ValueChangeEvent e) {
    this.dir = e.getNewValue().toString();
    log.info("NEW DIRECTION: " + this.getDir());
}

它不会记录 - setDir() 从未被调用。由于某种原因,h:inputHidden 标记上的 valueChangeListener 属性不起作用。我错过了什么吗?

最佳答案

您的具体问题是因为您使用 valueChangeListener 引起的方法错误。

<h:inputHidden ... valueChangeListener="#{searchFlightsBean.setDir()}">

这与方法签名不匹配。您应该省略括号 ()

<h:inputHidden ... valueChangeListener="#{searchFlightsBean.setDir}">

否则,JSF 需要无参数 setDir()方法。然后,您无法在 JavaScript 中触发 change输入元素上的事件。 onchange="submit()"因此永远不会被调用。你应该做hidden.trigger("change")在 JS 中实现这一点。

但是,这毕竟有些笨拙。您正在发送一个完整的同步请求,并且您的 JS 代码相当复杂(并且一旦您使用 ajax 更新表单就会停止工作)。假设您确实使用 JSF 2.x,我建议引入 <f:ajax> — 不幸的是,这在 <h:inputHidden> 中不起作用,因此 <h:inputText style="display:none"> — 并利用$.on()即使您使用 ajax 更新 DOM,也可以在 jQuery 中保持功能正常工作。

<h:form>
    <div class="btn-group" data-toggle-name="is_private" data-toggle="buttons-radio" >
        <button type="button" value="0" class="btn" data-toggle="button">Public</button>
        <button type="button" value="1" class="btn" data-toggle="button">Private</button>
    </div>
    <h:inputText id="is_private" value="#{bean.dir}" style="display: none;">
        <f:ajax listener="#{bean.changeDir}" />
    </h:inputText>
    <!-- Note: <h:inputText id> must be exactly the same as <div data-toggle-name> -->
</h:form>

<h:outputScript>
    $(document).on("click", "[data-toggle=buttons-radio] button", function() {
        var $button = $(this);
        var id = $button.closest(".btn-group").attr("data-toggle-name");
        var $input = $button.closest("form").find("input[id$=':" + id + "']");

        if ($input.val() != $button.val()) {
            $input.val($button.val()).trigger("change");
        }
    });
</h:outputScript>

(应该注意的是,整个脚本应该真正放置在自己的 .js 文件中,该文件由 <h:outputScript name="some.js" target="body"> 包含;注意,您不需要 $(document).ready() 也不需要 $(function() {}) 困惑;也请注意,JS 函数可以在所有其他 <div data-toggle="buttons-radio"> 组上重用,无需更改)

使用这个 bean:

private Integer dir;

public void changeDir() {
    System.out.println("New direction: " + dir);
}

// ...

(应该注意的是,当您在 changeDir() 方法中没有做任何相关的事情时,那么您可以完全省略整个方法和 <f:ajax> 并将 <h:inputText style="display:none"> 恢复为 <h:inputHidden> 并删除.trigger("change") 并依赖于常规表单提交。它会工作得很好)

关于jsf - 使用 twitter bootstrap 的单选按钮 - 无法获取值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18375074/

相关文章:

javascript - 当我们单击 ul 中的列表项时,如何将 fa-angle-left 更改为 fa-angle-down

css - 覆盖使用 :not Selector 的 CSS

c# - 如何将不同面板中的单选按钮分组为一个组?

jsf - 如何制作 p :graphicImage clickable and invoke bean action

jquery - 如何在jquery中引用JSF组件Id?

css - 如何更改应用于带有消息类型的 jsf div 的 css 样式?

javascript - 防止模态背景叠加在每个打开的新模态上变暗

iphone - 当单选按钮选择检查

jquery - 如何设置动态下拉列表的选定值

java - 使用 EL 访问继承的属性/方法时出错