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

前端 未结 1 1387
醉话见心
醉话见心 2020-12-06 22:33

I have a JSF composite component like this:

 
   
相关标签:
1条回答
  • 2020-12-06 22:47

    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.

    0 讨论(0)
提交回复
热议问题