Search code examples
javascripthtmlpolymerpaper-elements

How to pass a "function pointer"/ event to a child element in Polymer/HTML


I have created a generic "create X dialog" component that uses paper-dialog and I want to send the generic component the specific action that i want called when the "create button" is fired.

How do I send function / event around in polymer? I am approaching this the wrong way? The polymer dos talk about listeners and firing but i am not sure how to apply that in this example, perhaps I am just missing a key point on that page?

<dom-module id="my-add-dialog">

  <template>

    <style>
    </style>

    <paper-dialog id="dialog" entry-animation="scale-up-animation" exit-animation="fade-out-animation" with-backdrop>
      <h2>{{title}}</h2>
      <p>{{description}}</p>

      <paper-button raisedButton id="test" label="Click" on-click="createGeneric">
      </paper-button>

    </paper-dialog>


  </template>

  </script>

  <script>
    Polymer({
      is: 'my-add-dialog',


      properties: {
        createVirtual: {
          type: Function
        },

      },

      createGeneric: function() {
        alert("I'm alive");
        createVirtual();
      },

      open: function() {
        this.$.dialog.open();
      }


    });
  </script>

</dom-module>

component that composes that:

<dom-module id="my-add-model-dialog">

  <template>
    <my-add-dialog id="dialog" title = "Acount Creation" description="Create Account" createVirtual="createmodel"></my-add-dialog>
  </template>

  <script>
    Polymer({
      is: 'my-add-model-dialog',

      open: function(){
        this.$.dialog.open();
      },

      createmodel: function(){
        alert("Creating a model");
      },


    });
  </script>


</dom-module>


Solution

  • To declaratively add an event listener to a Polymer element, insert an attribute in the form of:

        <custom-element on-EVENTNAME="METHODNAME">
    

    where:

    • EVENTNAME is the lowercase name of the event to listen to (e.g., tap, click, blur, my-custom-event).
    • METHODNAME is the case-sensitive name of the event handler method.

    Then, the element (or its child elements) can trigger that event with this.fire('EVENTNAME'):

        <dom-module id="custom-element">
            ...
            <script>
                Polymer({
                    is: 'custom-element',
                    foo: function() {
                        this.fire('my-custom-event');
                    },
                    ...
                });
            </script>
        </dom-module>
    

    Example

    Using your code as an example...

    1. Listen to create events on my-add-model-dialog, binding createmodel() as an event handler:

      <my-add-model-dialog on-create="createmodel"></my-add-model-dialog>
      
    2. In my-add-dialog, fire the create event, which bubbles up to my-add-model-dialog, invoking createmodel().

      <script>
        Polymer({
          is: 'my-add-dialog',
      
          createGeneric: function() {
            alert("I'm alive");
            this.fire('create');
          },
          ...
        });
      </script>
      

    <head>
      <base href="https://polygit.org/polymer+:master/components/">
      <script src="webcomponentsjs/webcomponents-lite.min.js"></script>
      <link rel="import" href="polymer/polymer.html">
      <link rel="import" href="paper-dialog/paper-dialog.html">
      <link rel="import" href="paper-button/paper-button.html">
    </head>
    
    <body>
      <my-add-model-dialog></my-add-model-dialog>
    
      <dom-module id="my-add-dialog">
        <template>
          <paper-dialog id="dialog" with-backdrop>
            <h2>{{title}}</h2>
            <p>{{description}}</p>
            <paper-button raised on-click="createGeneric">Create</paper-button>
          </paper-dialog>
        </template>
    
        <script>
          Polymer({
            is: 'my-add-dialog',
      
            createGeneric: function() {
              alert("I'm alive");
              this.fire('create');
            },
      
            open: function() {
              this.$.dialog.open();
            },
      
            ready: function() {
              this.open();
            }
          });
        </script>
      </dom-module>
    
      <dom-module id="my-add-model-dialog">
        <template>
          <my-add-dialog id="dialog" title="Account Creation" description="Create Account" on-create="createmodel"></my-add-dialog>
        </template>
    
        <script>
          Polymer({
            is: 'my-add-model-dialog',
      
            open: function() {
              this.$.dialog.open();
            },
      
            createmodel: function() {
              alert("Creating a model");
            }
          });
        </script>
      </dom-module>
    </body>

    jsbin