How to create dynamically polymer element\simple tag

568 views
Skip to first unread message

Антон Мирошниченко

unread,
Oct 28, 2014, 1:20:21 PM10/28/14
to polym...@googlegroups.com

I have a polymer-element like this:

<polymer-element name="x-block" attributes="data">
    <template>
        <div class="block-wrapper">
            <div class="plus-button"on-click="{{showMdl}}">+</div>
            <div hidden?="{{!showModal}}" id="modal">
                Modal
            </div>
            <content select="header"></content>
        </div>

    </template>
    /*Polymer */
    <script>
        Polymer({
            ready: function(){
                this.showModal = false;
            },
            showMdl: function(e,detail,sender){
                this.showModal = true;
                this.$.modal.style.top = e.layerY+'px';
                this.$.modal.style.left = e.layerX+'px';
                var newElement = document.createElement('div')
                newElement.innerHTML = 'dynamicllyElement';
                newElement.setAttribute('on-click','{{clickOnDynamicllyElement}}');
                this.$.modal.appendChild(newElement);
            },
            clickOnDynamicllyElement:function(){
                console.log('1111')
            }
        });
    </script>
</polymer-element>

clickOnDynamicllyElement does not work.

Claudius Nicolae

unread,
Oct 28, 2014, 6:42:09 PM10/28/14
to polym...@googlegroups.com
newElement.addEventListener('click', this.clickOnDynamicllyElement);
learn js and dom

Антон Мирошниченко

unread,
Oct 29, 2014, 3:18:04 AM10/29/14
to polym...@googlegroups.com
Thanks. But i suppose it is not polymer way. Meaby my question is not correct. What if i need data-binding for a new element?

среда, 29 октября 2014 г., 1:42:09 UTC+3 пользователь Claudius Nicolae написал:

Max

unread,
Oct 29, 2014, 3:39:55 AM10/29/14
to Антон Мирошниченко, polym...@googlegroups.com
I think you basically "can't do that". Perhaps you can use a template bound to a property that is set in your showMdl function? ...along the lines of this :

<https://www.polymer-project.org/docs/polymer/template.html#if>
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/d39e75e3-65a1-4637-837c-f3ece533acb7%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Антон Мирошниченко

unread,
Oct 29, 2014, 3:52:41 AM10/29/14
to polym...@googlegroups.com, soo...@gmail.com
templates has resolved this problem. But it is not dynamically behavior, templates must be created in polyemer-element early.

среда, 29 октября 2014 г., 10:39:55 UTC+3 пользователь David Waterman написал:

Max

unread,
Oct 29, 2014, 4:07:53 AM10/29/14
to Антон Мирошниченко, polym...@googlegroups.com
Is there something about the template solution that is insufficient compared to what you're trying to do?

You can imagine why it might be that what you're trying won't work, right? You're trying to add an attribute with moustache binding, but they are surely only evaluated and bound when the Polymer element is constructed. To do the same thing, you'd quite likely have to invoke some of the polymer internals to process the element you're adding, after it has been added.

I suppose there might be a way to do this 'correctly', but I don't know it and no one else is answering so I imagine it is not possible. It's certainly not 'the polyer way' as I see it - I mean the moustache binding is, but dynamically adding such an attribute isn't something I've seen before.

I would have done it something like this :

<template bind if="{{ showModal }}">
  <div on-click="{{clickOnDynamicllyElement}} style="top:{{modalTop}}; left:{{modalLeft}}">dynamicllyElement</div>
</template>
...
           created: function() {
                this.showModal = false;
                this.modalTop = '0px';
                this.modalLeft = '0px';
           }
           showMdl: function(e,detail,sender){
                this.modalTop = e.layerY+'px';
                this.modalLeft = e.layerX+'px';
                this.showModal = true;
            },

I've not tried it though, so ymmv.

It occurs to me that it's also possible to do things with classes eg by toggling a class that has 'display: none;'

Max.

Антон Мирошниченко

unread,
Oct 29, 2014, 4:32:05 AM10/29/14
to polym...@googlegroups.com, soo...@gmail.com
Thanks for your answer. I think need change understanding of polymer solutions. They should not be similar to "old javascript" application. 

среда, 29 октября 2014 г., 11:07:53 UTC+3 пользователь David Waterman написал:

Антон Мирошниченко

unread,
Oct 29, 2014, 4:35:44 AM10/29/14
to polym...@googlegroups.com, soo...@gmail.com
Or use injectBoundHTML

this.injectBoundHTML('<div on-click="{{clickOnDynamicllyElement}}">dynamicllyElement</div>', this.$.modal);

среда, 29 октября 2014 г., 11:32:05 UTC+3 пользователь Антон Мирошниченко написал:

santiago esteva

unread,
Oct 29, 2014, 8:21:54 AM10/29/14
to polym...@googlegroups.com
From the Polymer docs

https://www.polymer-project.org/docs/polymer/polymer.html#imperativeregister

Registering imperatively Elements can be registered in pure JavaScript like this:

<script>
Polymer('name-tag', {nameColor: 'red'});
var el = document.createElement('div');
el.innerHTML = '\
<polymer-element name="name-tag" attributes="name">\
<template>\
Hello <span style="color:{{nameColor}}">{{name}}</span>\
</template>\
</polymer-element>';
// The custom elements polyfill can't see the <polymer-element>
// unless you put it in the DOM.
document.body.appendChild(el);
</script>
You need to add the to the document so that the Custom Elements polyfill picks it up.

Important: Since the Polymer call here is outside the , it must include the tag name argument.

Scott Miles

unread,
Oct 29, 2014, 12:24:57 PM10/29/14
to santiago esteva, polymer-dev
Fwiw, you absolutely should use traditional DOM apis, when they serve your purpose. Using higher-level abstractions like templates and so on for simply DOM manipulation will only make your program slower. It's important to remember that Polymer is not magic, the intent is only to provide helpful sugaring for DOM itself.

The Polymer `best-practice` solution for your original problem statement is something like the below. The idea is to use the bindings when it makes life easier (e.g. for `modal.style`) but not to bother with it when it's not needed (e.g. for addEventListener).

<polymer-element name="x-block" attributes="data">
    <template>
        <div class="block-wrapper">

            <div class="plus-button"on-click="{{showModal}}">+</div>
            <div id="modal" hidden?="{{!modalShown}}" style="modalTop: {{top}}px; modalLeft: {{left}}px;">

                Modal
            </div>
            <content select="header"></content>
        </div>
    </template>
    /*Polymer */
    <script>
        Polymer({
            ready: function(){

                this.modalShown = false;
}, showModal: function(e) {
this.modalShown = true;
this.modalTop = e.layerY; this.modalLeft = e.layerX; //
                var newElement = document.createElement('div')

                newElement.innerHTML = 'dynamicElement';
                newElement.addEventListener('click', this.dynamicElementClick.bind(this));
                this.$.modal.appendChild(newElement);
            },
            dynamicElementClick: function(){
                console.log('1111')
            }
        });
    </script>
</polymer-element>

Now, whether or not you actually need the dynamic element is another question altogether. 

Wrt `injectBoundHTML`, this is potentially dangerous API as it opens you up to XSS attacks if it's not used properly (as does `innerHTML` for that matter). I would only use `injectBoundHTML` if I really needed to data-bind some dynamic HTML (as opposed to listening to events, which is easily done as above). For the record, it's a flaw in Polymer today that there isn't a way to data-bind imperatively (via some kind of method) instead of having to go through a `<template>`

Scott


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.
Reply all
Reply to author
Forward
0 new messages