使用 twitter 引导程序的单选按钮 - 无法获得价值

Posted

技术标签:

【中文标题】使用 twitter 引导程序的单选按钮 - 无法获得价值【英文标题】:Radio buttons using twitter bootstrap - unable to get value 【发布时间】:2013-08-24 20:48:05 【问题描述】:

我浏览了 SO,并找到了一些答案,这些答案引导我更接近于获得工作单选按钮,但我现在被困住了。

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

我正在使用 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 属性不起作用。我错过了什么吗?

【问题讨论】:

noone的回答真的解决了你的问题吗?对我来说,他似乎只是发布了一个完全随机的解决方案,该解决方案更多地适用于 JSF 1.x 而不是 JSF 2.x,但您将他的答案标记为已接受。您真的在使用 JSF 1.x 和 RichFaces 3.x 吗?您之前提出的问题中没有任何内容表明这一点。如果您仍然在同一个主要问题上苦苦挣扎,那么您不应该将答案标记为已接受,因此该答案根本没有帮助。 @BalusC 不,它并没有真正回答我的问题 - 我不接受它。我还编辑了我的问题,以使其与我目前正在尝试做的事情保持同步。要么我使用的 valueChangeListener 错误,要么我需要使用其他东西。 好的。只是为了确认一下,您使用的是 JSF 2.x?因此,您可以使用&lt;f:ajax&gt;? 【参考方案1】:

你的具体问题是因为你用错了valueChangeListener

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

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

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

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

但是,这毕竟有点笨拙。您正在发送一个完整的同步请求,并且您的 JS 代码过于复杂(一旦您对表单进行 ajax 更新,就会停止工作)。如果您确实使用 JSF 2.x,我建议引入 &lt;f:ajax&gt; — 不幸的是,这在 &lt;h:inputHidden&gt; 中不起作用,因此 &lt;h:inputText style="display:none"&gt; — 并在 jQuery 中使用 $.on() 来保持即使您对 DOM 进行 ajax 更新,这些功能也能正常工作。

<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 文件中,由&lt;h:outputScript name="some.js" target="body"&gt; 包含;请注意,您不需要$(document).ready()$(function() ) 混乱;也请注意,非常 JS 函数可以在所有其他 &lt;div data-toggle="buttons-radio"&gt; 组上重复使用而无需更改)

用这个 bean:

private Integer dir;

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


// ...

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

【讨论】:

【参考方案2】:

您不能只通过 JavaScript 中的表达式语言调用 (#...) 调用任何支持 bean 函数。

您可以做的是使用 a4j:jsFunction 将您的 bean 方法提供给 java 脚本代码。可能看起来像这样:

<a4j:jsFunction name="setDir" action="#searchFlightsBean.setDir()" ajaxSingle="true">
    <a4j:param name="dir" assignTo="#searchFlightsBean.dir" />
</a4j:jsFunction>

见http://docs.jboss.org/richfaces/latest_3_3_X/en/devguide/html/a4j_jsFunction.html 和http://showcase.richfaces.org/richfaces/component-sample.jsf?demo=jsFunction&skin=blueSky

【讨论】:

谢谢。我刚刚注意到我收到了一个 JS 错误(显然我无法调用 button.live。我将如何从我的 JS 调用 ajax? @Skytiger 查看展示的示例。但是您需要使用 RichFaces 中包含的 A4J 库。您需要使用一些扩展来处理 JS 和 JSF 之间的桥接,否则您需要一些不太好的技巧。见***.com/questions/3710908/… 谢谢,但 A4J 库不会帮我剪掉它。我决定尝试另一种解决方法。

以上是关于使用 twitter 引导程序的单选按钮 - 无法获得价值的主要内容,如果未能解决你的问题,请参考以下文章

如何使用引导程序使表格内的单选按钮看起来像一个按钮?

表单验证失败后表单上的单选按钮无法正确呈现 - 引导

带有 <image>( X ) 标签的 simple_form 渲染单选按钮组与 twitter 引导程序?

Bootstrap单选按钮切换问题

使用 jquery 检查禁用的单选按钮

在swing中获取选定的单选按钮列表