How to bind events to nested template elements

1,056 views
Skip to first unread message

Martí Planellas

unread,
Mar 13, 2014, 7:14:04 AM3/13/14
to polym...@googlegroups.com
Hi all, I've been fighting this for a while, I have this html in my polymer element:

   <div class="container">
        <ul class="lines">
            <template id="line" repeat="{{line in lines}}">
                <li class="line {{line.class}}">
                    <div class="line-label">
                        <span class="line-name {{line.nameclass}}">
                            {{line.name}}
                        </span>
                        <span class="line-status {{line.class}}">
                            {{line.status}}
                        </span>
                    </div>
                    <ul class="line-disruptions">
                        <template id="disruption" repeat="{{disruption in line.disruptions}}">
                            <li class="line-disruption {{disruption.class}}">{{disruption.from}} to {{disruption.to}}: {{disruption.status}}</li>
                        </template>
                    </ul>
                </li>
            </template>
        </ul>
    </div>

So there're two nested templates, now I want to add some click event on the ul.line-disruptions elements, but I have no idea how to get to these elements...

I tried this.shadowRoot.querySelectorAll('ul.line-disruptions') but nothing is returned.

How do I access those nodes?

Thanks.

Scott Miles

unread,
Mar 13, 2014, 5:18:38 PM3/13/14
to Martí Planellas, polymer-dev
The easiest way is to use Polymer's declarative event sugaring:

  <li class="line-disruption {{disruption.class}}" on-tap="{{tapHandler}}">{{disruption.from}} to {{disruption.to}}: {{disruption.status}}</li>


>> this.shadowRoot.querySelectorAll('ul.line-disruptions') 

This should work, as long as those elements exist at the time you perform the query. IOW, only after the template has stamped actual 'ul' elements will you be able to query for them.


Follow Polymer on Google+: plus.google.com/107187849809354688692
---
You received this message because you are subscribed to the Google Groups "Polymer" group.
To unsubscribe from this group and stop receiving emails from it, send an email to polymer-dev...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/polymer-dev/76621c93-187f-4810-a3ef-026c080b4383%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Michael Bleigh

unread,
Mar 14, 2014, 12:32:16 AM3/14/14
to polym...@googlegroups.com
This isn't 100% related, but in the event of a declarative event in a repeat, is there any way to pass non-rendered data through to the event handler? For instance, in the example given, would it be possible to make tapHandler aware of the specific disruption instance short of passing some kind of index reference via data attributes etc.

Scott Miles

unread,
Mar 14, 2014, 1:17:45 AM3/14/14
to Michael Bleigh, polymer-dev
First off, I gave the example on the wrong element, I believe this is more accurately what was asked for:

<ul class="line-disruptions" on-tap="{{tapHandler}}">

>> would it be possible to make tapHandler aware of the specific disruption instance

Yes. The handler can do:

tapHandler: function(event) {
  // get the specific `line` object associated with the target element
  var line = event.target.templateInstance.model; 
  // do stuff with `line`
  ...
}

Scott

P.S. This expression `event.target.templateInstance.model` is so handy that we plan on sugaring it in the near future, maybe by promoting the `model` property to the `event` object, or possibly as another argument to the handler.


Michael Bleigh

unread,
Mar 14, 2014, 1:38:23 AM3/14/14
to Scott Miles, polymer-dev
Good to know! Thanks.

Scott Miles

unread,
Mar 14, 2014, 1:47:16 AM3/14/14
to Michael Bleigh, polymer-dev
Thanks for the follow up question. That model-from-event expression is critical information that we (engineering) haven't communicated properly.

marti.p...@acknowledgement.co.uk

unread,
Mar 14, 2014, 6:17:41 AM3/14/14
to polym...@googlegroups.com, Michael Bleigh
Hi Scott,

Thanks for the reply, another small question if I may,

I can't find anywhere how to create an IF statement in the Polymer templating system, I would like to do something like:

{{if line.disruptions}}
   
<ul class"line-disruptions">....</ul>
{{endif}}


How is that done?

Thanks!

Barak Bar Orion

unread,
Mar 14, 2014, 6:42:50 AM3/14/14
to polym...@googlegroups.com, Michael Bleigh, marti.p...@acknowledgement.co.uk
You will have to use nested template, see example at:
https://github.com/Polymer/TemplateBinding/blob/master/examples/how_to/conditional_template.html


<template id="example" bind>
      <span>Show?: <input type="checkbox" checked="{{ show }}"></span>
      <template bind if="{{ show }}">
       <span>Yay! I'm shown</span>
      </template>
 </template>

Other from that you can use conditional attribute inside template:
hidden?="{{ hide }}"

marti.p...@acknowledgement.co.uk

unread,
Mar 14, 2014, 8:17:43 AM3/14/14
to polym...@googlegroups.com, Michael Bleigh, marti.p...@acknowledgement.co.uk
Thanks, worked great!

If any one wants to take a look at the working code or have some other advise please feel free: https://github.com/beldar/polymer-tfl-status

Scott Miles

unread,
Mar 14, 2014, 12:17:55 PM3/14/14
to marti.p...@acknowledgement.co.uk, polymer-dev, Michael Bleigh
Thanks for sharing! 

Btw, another thing we need to communicate better is about element naming. 

The intent of the 'polymer-*' prefix in our stuff is to indicate 'elements made by the polymer team', and not 'element made using polymer'.

Because part of the notion of Polymer is that users of an element don't necessarily *need* to know it's made with Polymer (it should Just Work) then don't feel like you need to identify it as such with 'polymer-*'

Anyway, just making a note of that.

Scott


Barak Bar Orion

unread,
Mar 14, 2014, 1:10:39 PM3/14/14
to polym...@googlegroups.com, marti.p...@acknowledgement.co.uk, Michael Bleigh
Hi Scott.

First thanks for the good work!

Do you know if there is a plan to add some kind of name mapping to the html import
something like:
<link rel="import" href="goodies.html" with-prefix:foo>
That will add the prefix foo to every elements defined in goodies.html 
that way it will be possible to use components without name collisions.

Barak.

Martí Planellas

unread,
Mar 14, 2014, 1:13:14 PM3/14/14
to Scott Miles, marti.p...@acknowledgement.co.uk, polymer-dev, Michael Bleigh
Ok Scott,

Thanks for clearing that out, I'll change it

Martí

El 14/03/2014, a les 16.17, Scott Miles <sjm...@google.com> va escriure:
You received this message because you are subscribed to a topic in the Google Groups "Polymer" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/polymer-dev/jR6SIU3HsNQ/unsubscribe.
To unsubscribe from this group and all its topics, send an email to polymer-dev...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/polymer-dev/CAHbmOLZgKNdKc9hwJQcHaJ%2Bh%2BP9naokyj7JwM5ecMzJUVcqfBQ%40mail.gmail.com.

Scott Miles

unread,
Mar 14, 2014, 1:17:21 PM3/14/14
to Barak Bar Orion, polymer-dev, marti.p...@acknowledgement.co.uk, Michael Bleigh
There's definitely awareness of this issue. I believe it's not quite as easy as you suggest because of the interconnectedness of elements.

IOW, elements and style sheets tend to refer to other elements by name, and it's potentially difficult to modulate all possible references to a name at run-time like that.

But as I say, we recognize this problem and will include your suggestion in the discussions.


Sergey Shevchenko

unread,
Mar 19, 2014, 7:13:04 PM3/19/14
to polym...@googlegroups.com, Michael Bleigh, marti.p...@acknowledgement.co.uk
I think it can be just:

      <template if="{{ show }}">

-- the 'bind' part is unnecessary. True or false?

Eric Bidelman

unread,
Mar 19, 2014, 7:21:27 PM3/19/14
to Sergey Shevchenko, marti.p...@acknowledgement.co.uk, polymer-dev, Michael Bleigh

Zeno Rocha

unread,
Mar 20, 2014, 2:11:42 PM3/20/14
to polym...@googlegroups.com, Sergey Shevchenko, marti.p...@acknowledgement.co.uk, Michael Bleigh
About element naming Scott, I wrote an article on WebComponents.org:

Rob Dodson

unread,
Mar 20, 2014, 4:39:32 PM3/20/14
to Zeno Rocha, polymer-dev, Sergey Shevchenko, marti.p...@acknowledgement.co.uk, Michael Bleigh
This article rocks, thanks Zeno :D


Scott Miles

unread,
Mar 20, 2014, 5:01:57 PM3/20/14
to Rob Dodson, Zeno Rocha, polymer-dev, Sergey Shevchenko, Martí Planellas Rosell, Michael Bleigh
Beauty, thanks #2. 

Especially like the Heisenberg.


Polymered

unread,
Aug 7, 2014, 5:35:01 AM8/7/14
to polym...@googlegroups.com, serg...@google.com, marti.p...@acknowledgement.co.uk, mbl...@gmail.com
Hi,

In my app, I wanted the {{ show }} to be derived from/driven by a child element attribute. Although the child element attribute publishing works, it doesn't seem to propagate to the parent template element like so:

                <template if="{{ loginScreen }}">
<login-screen  page="{{ loginScreen }}"></login-screen>
</template>

and the child element:

<polymer-element name="login-screen" attributes="page">
<template>
.....
 
</template>
<script>
   Polymer('login-screen', {
ready: function() {
this.page = false
}
   });
  </script>
</polymer-element>


My question is: how do I make the parent template conditional to take on the child published attribute value?

My objective, BTW, is to handle screen switching using the template conditionals if that's possible. I did try the app-router and active-route elements but I couldn't get them to work exactly as intended.

P.S.
I come from an AngularJS environment so if my question or objective seems a bit off for Polymer, please show me the light. :)

Thanks for any insight!

Rob Dodson

unread,
Aug 8, 2014, 2:25:33 PM8/8/14
to Polymered, polymer-dev, Sergey Shevchenko, Martí Planellas Rosell, Michael Bleigh
Could you post a slimmed down example on jsbin? 


Reply all
Reply to author
Forward
0 new messages