How to make same JSF Composite Component included multiple times to have its own javascript scope?

做~自己de王妃 提交于 2019-12-31 04:00:23

问题


I have a JSF composite component like this:

 <cc:implementation>
   <div id="#{cc.clientId}">
        <h:outputScript library="js" name="helper.js"/>

        <script type="text/javascript">
        if(typeof variables === "undefined"){
             var variables = {};
        }

        (function(){
            variables.formid = '#{cc.clientId}'; 
        })();
        </script>
    </div>

Value of variables.formid I'm using in a helper.js file. When I include this composite component only once, it's working like it should. When I include multiple composite components, every component receives the value of a last included composite component, how can I solve this issue?


回答1:


There are basically 2 ways.

  1. Add kind of "register" function to helper.js, so that you can explicitly register it there, instead of letting it to search for composites.

    <h:outputScript name="js/helper.js" target="head" />
    <div id="#{cc.clientId}">
        ...
    </div>
    <h:outputScript>helper.register("#{cc.clientId}", { foo: "somevalue" });</h:outputScript>
    

    Options can be provided via a JS object as argument. This is also how a.o. PrimeFaces work with PrimeFaces.cw() function, whereby the "widget name" is also passed as an option.

  2. Give the composite an unique style class like so:

    <h:outputScript name="js/helper.js" target="head" />
    <div id="#{cc.clientId}" class="your-foo-composite">
        ...
    </div>
    

    This way the helper.js can just collect them by class name during document ready.

    // Vanilla JS:
    var yourFooComposites = document.getElementsByClassName("your-foo-composite");
    
    // Or if you happen to use jQuery:
    var $yourFooComposites = $(".your-foo-composite");
    

    Options can be provided as HTML5 data attributes (browser support is good these days).

    <div id="#{cc.clientId}" class="your-foo-composite" data-foo="somevalue">
    

    Which can be obtained as:

    // Vanilla JS:
    for (var i = 0; i < yourFooComposites.length; i++) {
        var yourFooComposite = yourFooComposites[i];
        var clientId = yourFooComposite.id;
        var dataFoo = yourFooComposite.dataset.foo;
        // ...
    }
    
    // Or if you happen to use jQuery:
    $yourFooComposites.each(function(index, yourFooComposite) {
        var $yourFooComposite = $(yourFooComposite);
        var clientId = $yourFooComposite.attr("id");
        var dataFoo = $yourFooComposite.data("foo");
        // ...
    });
    

    It also keeps your HTML output free of inline scripts.


Unrelated to the concrete problem, usage of "js" as library name as in your initial code is not good. Carefully read What is the JSF resource library for and how should it be used? Also note that I added target="head" attribute to the <h:outputScript>. In case you're properly using JSF <h:head> component, it will let JSF autorelocate the script to the generated HTML <head> element.



来源:https://stackoverflow.com/questions/34817479/is-it-possible-to-add-a-javascript-function-to-a-hform-in-jsf2

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!