title: HTML5/webcomponents: Call prototype function from template code
body: <p>I'm making some tests for using (or not) web components in a single page app I'm creating.</p>
  
  <p>Here's an example for the problem:</p>
  
  <p><div class="snippet" data-lang="js" data-hide="false">
  <div class="snippet-code">
  <pre class="snippet-code-html lang-html prettyprint-override"><code>&lt;!DOCTYPE html&gt;
  &lt;html lang="en"&gt;
  &lt;head&gt;
      &lt;meta charset="UTF-8"&gt;
  &lt;/head&gt;
  &lt;body&gt;
  
  &lt;template id="aTemplate"&gt;
      &lt;div style="border:1px solid red"&gt;
          &lt;p&gt;text &lt;input type="text"&gt;&lt;/p&gt;
          &lt;button&gt;ClickMe&lt;/button&gt;
      &lt;/div&gt;
  &lt;/template&gt;
  
  &lt;script&gt;
      var Proto = Object.create(HTMLElement.prototype);
  
      Proto.createdCallback = function () {
          var t = document.querySelector('#aTemplate');
          var clone = document.importNode(t.content, true);
          this.createShadowRoot().appendChild(clone);
      };
  
      Proto.aFunction = function() {
          alert("proto " + "text value?");
      }
  
      document.registerElement('x-proto', {prototype: Proto});
  
      var ProtoChild = Object.create(Proto);
  
      ProtoChild.createdCallback = function () {
          Proto.createdCallback.call(this)
      };
  
      ProtoChild.aFunction = function() {
          alert("child " + "text value?");
      }
  
      document.registerElement('x-proto-child', {
          prototype: Proto
      });
  
  &lt;/script&gt;
  
  &lt;x-proto&gt;&lt;/x-proto&gt;
  
  &lt;x-proto-child&gt;&lt;/x-proto-child&gt;
  
  &lt;/body&gt;</code></pre>
  </div>
  </div>
  </p>
  
  <p>The problem is that I cannot find a way to set a "onclick" handler in the button (inside the template) that calls the method "aFunction" in the object created using the prototype. The method should be called in the correct object instance, with access to the internal DOM components, and the attributes and functions in the prototype.</p>
  
  <p>I've tried a lot of things, (binding the event after construction, using JS or JQuery, using the created/attached callbacks, a ) but I'm out of ideas.</p>
  
  <p>Thanks in advance.</p>
  
  <p>EDIT:</p>
  
  <p>Thanks to MinusFour for the answer. The line:  </p>
  
  <blockquote>
  <pre><code>clone.querySelector('button').addEventListener('click', this.aFunction); 
  </code></pre>
  </blockquote>
  
  <p>in what I was trying to do, anyway, resulted in (same but with JQuery, for testing compatibilitiy):  </p>
  
  <blockquote>
  <pre><code>$(this.showButton).on("click", this.aFunction.bind(this));
  </code></pre>
  </blockquote>
  
  <p>The "bind" makes 'this' AKA the container, the complete component, available in JS code, what I needed.</p>
  
  <p>Here's the completed final example, someone may find it helpful:</p>
  
  <p><div class="snippet" data-lang="js" data-hide="false">
  <div class="snippet-code">
  <pre class="snippet-code-html lang-html prettyprint-override"><code>&lt;!DOCTYPE html&gt;
  &lt;html lang="en"&gt;
  &lt;head&gt;
      &lt;meta charset="UTF-8"&gt;
      &lt;script src="http://code.jquery.com/jquery-2.1.4.min.js"&gt;&lt;/script&gt;
  &lt;/head&gt;
  &lt;body&gt;
  
  &lt;template id="aTemplate"&gt;
      &lt;div style="border:1px solid darkgray;padding:10px;margin: 10px;"&gt;
          &lt;h2 class="theCaption"&gt;&lt;/h2&gt;
          &lt;p&gt;text &lt;input class="theText" type="text"&gt;&lt;/p&gt;
          &lt;button class="showButton"&gt;Show val&lt;/button&gt;
          &lt;button class="closeButton"&gt;Close&lt;/button&gt;
      &lt;/div&gt;
  &lt;/template&gt;
  
  &lt;script&gt;
  
      // The .bind method from Prototype.js
      if (!Function.prototype.bind) { // check if native implementation available
          Function.prototype.bind = function () {
              var fn = this, args = Array.prototype.slice.call(arguments),
                      object = args.shift();
              return function () {
                  return fn.apply(object,
                          args.concat(Array.prototype.slice.call(arguments)));
              };
          };
      }
  
      function createProto() {
         $("#spawnPoint").append("&lt;x-proto x-caption='proto'&gt;&lt;/x-proto&gt;");
      }
  
      function createChild() {
          $("#spawnPoint").append("&lt;x-proto-child x-caption='a child of proto'&gt;&lt;/x-proto-child&gt;");
      }
  
      var Proto = Object.create(HTMLElement.prototype);
  
      Object.defineProperty(Proto, "x-caption", {value: "no caption"});
  
      Proto.createdCallback = function () {
          var t = document.querySelector('#aTemplate');
          var clone = document.importNode(t.content, true);
          this.shadowRoot = this.createShadowRoot();
          this.shadowRoot.appendChild(clone);
          $(clone).children("div").append("&lt;p&gt;ssss&lt;/p&gt;")
          this.showButton = this.shadowRoot.querySelector('.showButton');
          this.closeButton = this.shadowRoot.querySelector('.closeButton');
          this.shadowRoot.querySelector('.theCaption').textContent = $(this).attr("x-caption");
          this.theText = this.shadowRoot.querySelector('.theText');
          $(this.showButton).on("click", this.aFunction.bind(this));
          $(this.closeButton).on("click", this.close.bind(this));
      };
  
      Proto.aFunction = function () {
          alert("in proto = " + $(this.theText).val());
      }
  
      Proto.close = function () {
          $(this).detach();
      }
  
      document.registerElement('x-proto', {prototype: Proto});
  
      var ProtoChild = Object.create(Proto);
  
      ProtoChild.createdCallback = function () {
          Proto.createdCallback.call(this);
      };
  
      ProtoChild.aFunction = function () {
          alert("overrided in child = " + $(this.theText).val());
      }
  
      document.registerElement('x-proto-child', {
          prototype: ProtoChild
      });
  
  &lt;/script&gt;
  
  &lt;button onclick="javascript:createProto()"&gt;Create proto&lt;/button&gt;
  &lt;button onclick="javascript:createChild()"&gt;Create child&lt;/button&gt;
  
  &lt;div id="spawnPoint"&gt;
  
  &lt;/div&gt;
  
  &lt;/body&gt;</code></pre>
  </div>
  </div>
  </p>