【问题标题】:Triggering Primefaces p:selectOneMenu onchange触发 Primefaces p:selectOneMenu onchange
【发布时间】:2013-01-05 17:35:27
【问题描述】:

似乎 Primefaces p:selectOneMenu 组件将呈现的 HTML <select> 标签包装在一个 div 中,并将所选项目显示为不同的标签。我猜用户所做的更改会通过javascript反映到原始<select>,导致绑定到<select>的onchange事件不起作用。因此,我对所有:inputs 的 onchange 事件的以下绑定不适用于p:selectOneMenus。

function applyChangeHandler() {
    $(':input').on('change', function() {
        console.log('on change: ' + this.id);
    });
}

但是p:selectOneMenu 的 onchange 属性正在被触发。所以 Primefaces 在后台触发了这个处理程序(我猜也是)。

<p:selectOneMenu id="myList" onchange="console.log('selectOneMenu')">
    <f:selectItem itemLabel="val1" itemValue="val1"/>
    <f:selectItem itemLabel="val2" itemValue="val2"/>
</p:selectOneMenu>

所以我的要求是以某种方式将 onchange 处理程序绑定到上面 applyChangeHandler() 函数中的所有p:selectOneMenus。或者它可以通过 Primefaces 特定的 API 或我希望你们分享的其他方式手动触发。否则,一个快速的解决方法是改用h:selectOneMenu

我的目标是检测“页面上未保存的更改”。所以上面的脚本将被放置在一个通用模板中:

<p:outputPanel id="sc" autoUpdate="true">
    <script type="text/javascript">
        applyChangeHandler();
    </script>
</p:outputPanel>

【问题讨论】:

    标签: javascript jquery jsf-2 primefaces


    【解决方案1】:

    框架已经为您提供了额外的侦听器,为什么您还需要提供额外的侦听器?

    如果您的目标是使用 jQuery,您只需将处理程序放在可从窗口全局范围访问的 js 文件中。

    function myChangeHandler(that) {
        //wrap the element with jQuery
        var select = jQuery(that);
        //Get the div parent. The actual wrapper of the `selection-menu` widget markup
        var selectMenu = select.parents('div.ui-selectonemenu');
        //From here I can manipulate any HTML child element using jQuery
        jQuery('label.ui-selectonemenu-label', selectMenu).text('mooo');
    }
    

    然后调用您的处理程序onchange,将selectOneMenu 作为参数传递

    <p:selectOneMenu id="myList" onchange="myChangeHandler(this)">
        <f:selectItem itemLabel="val1" itemValue="val1" />
        <f:selectItem itemLabel="val2" itemValue="val2" />
    </p:selectOneMenu>
    

    【讨论】:

    • 我的目标是检测“页面上未保存的更改”。因此 onchange 事件绑定到页面中的所有 *:inputs。该脚本将放置在一个通用模板中。目前不太需要为所有页面中的每个 p:selectOneMenu 放置一个更改处理程序。
    【解决方案2】:

    您可以使用“DOMSubtreeModified”,而不是使用 onChange。

    这适用于 p:selectOneMenu

    $(".ui-selectonemenu-label").each(function(index) {
        $(this).on("DOMSubtreeModified", setDirty());
    });
    

    还有。如果您希望到处都使用相同的通用代码,另一种可能性是覆盖 SelectOneMenu 的原型,如下所示:

    var origTriggerChange = PrimeFaces.widget.SelectOneMenu.prototype.triggerChange;
    // if this code has been run already, don't accumulate triggerChangemethods!
    if(origTriggerChange.isModified != "true"){
          PrimeFaces.widget.SelectOneMenu.prototype.triggerChange = function(b){
          this.jq.find("select").change();
          origTriggerChange.call(this, b);
       };
       PrimeFaces.widget.SelectOneMenu.prototype.triggerChange.isModified = "true";
    }
    

    【讨论】:

      【解决方案3】:

      您需要将 widgetVar 添加到 p:selectOneMenu 以在 JS

      中使用它
      <p:selectOneMenu id="myList" onchange="console.log('selectOneMenu')" widgetVar="myList">
        <f:selectItem itemLabel="val1" itemValue="val1"/>
        <f:selectItem itemLabel="val2" itemValue="val2"/>
      </p:selectOneMenu>
      

      这会将这段代码添加到你的页面

      $(function(){
        PrimeFaces.cw("SelectOneMenu","myList",{
             id:"A2:Form:myList",
             effect:"fade"
        })
      });
      

      希望这会有所帮助。

      【讨论】:

        猜你喜欢
        • 2012-05-06
        • 1970-01-01
        • 2013-02-04
        • 2014-04-19
        • 2013-05-22
        • 1970-01-01
        • 1970-01-01
        • 2012-12-17
        • 1970-01-01
        相关资源
        最近更新 更多