我已经浏览了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()
。由于某些原因,valueChangeListener
标记上的h:inputHidden
属性不起作用。我错过了什么吗?
答案 0 :(得分:1)
您不能通过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
答案 1 :(得分: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不确定,我建议引入<f:ajax>
- 遗憾的是<h:inputHidden>
无效,<h:inputText style="display:none">
- 并使用$.on()
{1}}在jQuery中保持函数正常工作,即使你在ajax-update DOM。
<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() {})
<div data-toggle="buttons-radio">
混乱;还要注意,JS函数可以在所有其他private Integer dir;
public void changeDir() {
System.out.println("New direction: " + dir);
}
// ...
组上重复使用而无需更改)
使用这个bean:
changeDir()
(请注意,当您在<f:ajax>
方法中进一步做任何相关事件时,您可以省略整个方法并完全忽略<h:inputText style="display:none">
并将<h:inputHidden>
还原到.trigger("change")
并删除{{1}}并依赖常规表单提交。它会一样好用)