How to access an external element inside a polymerjs element.
<polymer-element attributes="externalDropZoneContainerId">>
<script>
Polymer('file-upload', {
ready: function(){
//Here I want to access the externalDropZoneContainerId so that I can bind drag and drop functionality to this ID
//$('#' + externalDropZoneContainerId) does not work.
}
})
</script>
<polymer-element>
The attribute is accessible via this.externalDropZoneContainerId, the standard DOM API to get elements is document.getElementById:
<polymer-element attributes="externalDropZoneContainerId">>
<script>
Polymer('file-upload', {
ready: function(){
var elem = document.getElementById(this.externalDropZoneContainerId);
}
})
</script>
<polymer-element>
Instead of the ready event you should maybe use the domReady event instead, otherwise the other element may not yet be guaranteed to exist.
Related
Let's say I have an element that has an insertion point inside.
<dom-module id="some-el">
<template>
<content id="con"></content>
</template>
<script>
(function () {
Polymer({
is: 'some-el',
ready:function(){
var placeholder = Polymer.dom(this).querySelector('div[id*="placeholder"]');
this._observer=Polymer.dom(placeholder ).observeNodes(function(info){
console.log(info.addedNodes)
});
}
});
})();
</script>
</dom-module>
and in DOM it looks like this where #placeholder... is a spinning wheel container, which replaces the span inside with content received via ajax.
<some-el><div id="placeholder_GUIDstuff"><span>spinner</span></div></some-el>
So basically I need to know when the #placeholder_... is changed, but I can't subscribe to it (when i do, nothing is returned when it changes), only to the content element, but it doesn't trigger when its immediate children get changed.
What can be the solution?
I'd like to ask you people about workflow with Polymer. I know that I should use my own elements or double check if element that I need isn't alredy published. It's really nice, I admit it. However the Polymer Starter Kit comes as single-page app. Is it the recommended approach for using Polymer? What about large pages that would need a lot of data to be loaded? Are there alternative approaches?
You don't need to have all your elements rendered at same time. They can be created on the fly only when needed, and can be destroyed as well.
To create your elements on the fly, you can use DOM Manipulation methods like:
var myElement = document.createElement("my-element");
this.$.container.appendChild(myElement);
myElement.myProperty = "anything";
To remove, just do this way:
var myElement = this.$.container.querySelector("my-element");
myElement.parentNode.removeChild(myElement);
If you need dynamic load a HTML Import, you can use this.importHref if your code is inside a polymer Element (and it should be).
this.importHref('myElement.html', function(e) {
// Create your element here
});
Putting things together...
Suppose you have a polymer element like that:
<dom-module id="my-app">
<template>
<div id="container"></div>
<paper-button on-click="_loadElement">Load Element</paper-button>
<paper-button on-click="_removeElement">Remove Element</paper-button>
</template>
</dom-module>
<script>
Polymer({
is: 'my-app',
_loadElement: function() {
this.importHref('myElement.html', function(e) {
var myElement = document.createElement("my-element");
this.$.container.appendChild(myElement);
myElement.myProperty = "anything";
});
},
_removeElement: function() {
var myElement = this.$.container.querySelector("my-element");
myElement.parentNode.removeChild(myElement);
}
});
</script>
I am having a problem accessing paper-input elements that are inside a paper-dialog. I cant seem to get the value of the paper-input while its inside the paper-dialog, I just get a return value of null. I know there is something like this.$.element but I am confused on how to actually use it. Does the paper-dialog have to be inside a self binding template?
once a paper-dialog is opened it goes into the shadowdom of core-overlay-layer scoping the elements from regular selectors. you can access it's children with the this.$.element syntax if the dialog is inside a auto-binding template
<body>
<template id="app" is="auto-binding">
// other html content
<paper-dialog id="dialog">
<paper-input id="input"></paper-input>
</paper-dialog>
</template>
<script>
(function () {
var app = document.querySelector("#app");
app.addEventListener('template-bound', function () {
this.getValue = function () {
return this.$.input.value;
};
});
}());
</script>
</body>
the other option would be to use a auto-binding template like before and create a declarative variable for the input value
<body>
<template id="app" is="auto-binding">
// other html content
<paper-dialog id="dialog">
<paper-input value="{{inputValue}}"></paper-input>
</paper-dialog>
</template>
<script>
(function () {
var app = document.querySelector("#app");
app.addEventListener('template-bound', function () {
this.getValue = function () {
return this.inputValue;
};
});
}());
</script>
</body>
a way to get around using the auto-binding template would be to put the dialog in a custom element and enclose all it's functionality there that would allow you to use either of these methods.
i hope this helps.
When I try document.querySelector('core-drawer-panel').togglePanel() in the console it works but when I do the following core-drawer-panel is not ready yet?
<template>
<core-drawer-panel forceNarrow>
</core-drawer-panel>
</template>
<script>
document.addEventListener('polymer-ready', function() {
document.querySelector('core-drawer-panel').togglePanel()
console.log('polymer-ready');
});
</script>
Note that I can not wrap it in a polymer element due to issues with other js frameworks.
try this
var template = document.querySelector('template');
template.addEventListener('template-bound', function () {
//code
});
with your element inside a template you need to look for template to be ready not polymer.
I am working on a Polymer project and I a few custom elements nested. For example, I have a custom element called <example-main>. Suppose that this element has a function called displayMessage()
I have another custom element defined inside <example-main> called <example-alerts>. I want the alerts element to be able to use the function in its parent, main, to display a message.
To achieve this, I am trying to select the element <example-main id='mainEl'> by using the Polymer's Automatic Node Finding hash, this.$.mainEl and using the function like so: this.$.mainEl.displayMessage();
However, I get this error message:
Uncaught TypeError: Cannot read property 'displayMessage' of undefined
Am I making a wrong approach of having Polymer elements call functions in other Polymer objects?
To visualize things a little better, the index.html would look something like:
...
<body>
<example-main id='mainEl'></example-main>
</body>
...
while example-main.html looks something like:
<polymer-element name='example-main'>
<template>
...
<example-alerts>
</template>
<script>
Polymer(example-element, {
displayMessage: function(){
//do message showing magic
}
});
</script>
</polymer-element>
and lastly, example-alerts.html looking like:
<polymer-element name='example-alerts'>
<template>
...
<paper-button on-tap='{{callFunction}}'></button>
</template>
<script>
Polymer(example-alerts, {
callFunction: function(){
//call the function in parent
this.$.mainEl.displayMessage();
}
});
</script>
</polymer-element>
You are not doing this correct way , you cannot find nodes this way .
Node finding just search within same element defined in elements outermost template.
You should either change your approach or you can use events to handle the situation pls see the sample demo which can work for you.
<polymer-element name='example-alerts'>
<template>
...
<paper-button on-tap='{{callFunction}}'></button>
</template>
<script>
Polymer(example-alerts, {
callFunction: function(){
//call the function in parent
this.fire('ouch', {msg: 'That hurt!'});
}
});
</script>
</polymer-element>
--Second Element
<polymer-element name='example-main'>
<template>
...
<example-alerts on-ouch='{{displayMessage}}'>
</template>
<script>
Polymer(example-element, {
displayMessage: function(){
//do message showing magic
}
});
</script>
</polymer-element>