How to global firebase polymer data binding? - polymer

I want to use <firebase-login> user object to check if user logged in for my elements. How do I global the user object without calling below code in every custom element?
<firebase-login id="login"
user="{{user}}"
statusKnown="{{statusKnown}}"
location="FIREBASE_URL"
provider="{{provider}}"
on-error="{{error}}"></firebase-login>

Create a custum-element that looks something like this,
<polymer-element name="example" attributes="user">
<template>
<firebase-login
id="login"
user="{{user}}"
statusKnown="{{statusKnown}}"
location="FIREBASE_URL"
provider="{{provider}}"
on-error="{{error}}">
</firebase-login>
</template>
<script>
Polymer({
})
</script>
</polymer-element>
Then use pvc-globals or create another custom element that passes globals Polymer has an example app-globals where they show how to do this.
<polymer-element name="app-example" attributes="globals">
<template>
<pvc-globals value="{{globals}}"></pvc-globals>
<example-element user="{{user}}"></example-element>
</template>
<script>
Polymer({
ready: function () {
this.globals.user = this.user;
}
});
</script>
</polymer-element>
Or from within the example element:
<polymer-element name="example" attributes="user globals">
<template>
<pvc-globals value="{{globals}}"></pvc-globals>
<firebase-login
id="login"
user="{{user}}"
statusKnown="{{statusKnown}}"
location="FIREBASE_URL"
provider="{{provider}}"
on-error="{{error}}">
</firebase-login>
</template>
<script>
Polymer({
ready: function () {
this.globals.user = this.user;
}
})
</script>
</polymer-element>
Hope this helps!

Related

Multiple elements which can be called via one element

I have a set of Polymer 1.x components which act as fillable forms. Each form can be called via <form-one></form-one>, <form-two></form-two> etc...
<dom-module id="form-one">
<template>
form content
</template>
</dom-module>
<script>
Polymer({
is: "form-one"
});
</script>
I'm looking for a solution to combine them and to have only one element and call the forms like:
<form-handler form="form-one"></form-handler>
Where to start? And is it also possible to keep the dom modules in separated files?
Thanks in advance.
You can have your element like this:
<dom-module id="form-handler">
<template>
<div id="formContainer">
</template>
</dom-module>
<script>
Polymer({
is: "form-handler",
properties:{
form: {type:String, observer:'_formChanged'}
},
_formChanged: function(){
var formElement = document.createElement(this.form);
this.$.formContainer.empty();
this.$.formContainer.append(formElement);
}
});
</script>

how to pass data from host element to child element

Having trouble getting my data to work across elements. Say I have an object "records" in my host element. It is usable in that element no problem. But when I try to spin off the view into a separate element, it no longer works.
Here's an example snippet of code. The .template part works fine but I'm not able to replicate the functionality in the child element .my-list. When I try, nothing happens.
<dom-module id="host-element">
...
<template is="dom-repeat" items="{{records}}">
<p>{{item.userName}} - {{item.number}}</p>
</template>
<my-list></my-list>
<script>
Polymer({
is: 'host-element',
ready: function() {
this.records = [
{userName: 'Bob'},
{userName: 'Sally'}
];
}
});
</script>
</dom-module>
If I try simply taking the current .template code and placing it into .my-list, it doesn't work.
I assume I need someway to bind the data into the child element, but I'm not able to figure this out. Adding a: record="{{records}}" to the tag, and then using that in the child element didn't work.
Imagine this is pretty simple, just can't find the answer in the documentation.
It's important that each element's top-level template is a plain template (not is="dom-repeat" or other specialization), otherwise, it should be straightforward:
<link rel="import" href="//polygit.org/components/polymer/polymer.html">
<i>(Requires Chrome)</i>
<host-element></host-element>
<dom-module id="my-list">
<template>
<template is="dom-repeat" items="{{records}}">
<p>{{item.userName}} - {{item.number}}</p>
</template>
</template>
<script>
Polymer({
is: 'my-list'
});
</script>
</dom-module>
<dom-module id="host-element">
<template>
<my-list records="{{records}}"></my-list>
</template>
<script>
Polymer({
is: 'host-element',
ready: function() {
this.records = [{userName: 'Bob'}, {userName: 'Sally'}];
}
});
</script>
</dom-module>

Polymer iron-list dynamically adding items?

I'm trying to migrate some code from Polymer 0.5 to 1.x, this means moving from core-list to iron-list. However, I can not figure out an iron equivalent to how I was adding items to the core-list.
<core-list height="85">
<template>
<div class="{{ {selected: selected} | tokenList }}" style="padding:5px;"><paper-fab mini icon="arrow-forward" title="arrow-forward"></paper-fab> <!--{{index}}-->{{model.name}}</div>
</template>
</core-list>
which is called updated via...
document.querySelector('core-list').data = $.parseJSON('[{"name":"One"},{"name":"Two"}]');
Anyone have any suggestions?
Update : Jul-23-2015 12:20PM PST
#Zikes
Following the suggestion posted, I have the following.
<dom-module id="my-element">
<template>
<iron-list items="[[myItems]]" as="item">
<template>
<div>[[item.name]]</div>
</template>
</iron-list>
</template>
<script>
Polymer({
is:'my-element',
properties: {
myItems: Array
},
addItem: function(item) {
this.push('myItems', {name: item});
}
});
</script>
</dom-module>
If this is setup right, how would I go about calling the addItem method from elsewhere?
Update : Jul-23-2015 1:58PM PST
#Zikes
Following is my current code. While I can manipulate the array, values added to it in the ready or addItem method are not being displayed.
<dom-module id="fnord-element">
<template>
<iron-list items="[[myItems]]" as="item">
<template>
<div class="item">[[item.name]]</div>
</template>
</iron-list>
</template>
<script>
Polymer({
is:'fnord-element',
properties: {
myItems: {
type: Array,
notify: true
}
},
addItem: function(item) {
//this.push("myItems", {"name":item});
this.myItems=[{name:item}];
alert(this.myItems[0].name);
//alert(item);
},
ready: function() {
//alert('fnord');
this.myItems=[{name:"One"},{name:"Two"}];
}
});
</script>
</dom-module>
<fnord-element id="fnord"></fnord-element>
<paper-button raised onclick="document.querySelector('#fnord').addItem('John Doe');">Test</paper-button>
iron-list uses the items property to generate its items, similar to dom-repeat. What you can do is simply bind it to an Array in your component, like so:
<dom-module id="my-element>
<template>
<iron-list items="[[myItems]]">
<template>
<div>[[item]]</div>
</template>
</iron-list>
</template>
<script>
Polymer({
is:'my-element',
properties: {
myItems: Array
}
});
</script>
</dom-module>
Then, just follow the rules for modifying an Array property and you're all set!

Computed property with firebase element in polymer 1.0

I have an element where I receive some data from firebase which looks like that:
<dom-module id="my-positions-list">
<template is="dom-bind">
<firebase-collection data="{{aa}}"
location="https://myapp.firebaseio.com/positions">
</firebase-collection>
<template is="dom-repeat" items="[[aa]]" as="item">
<p><span>{{url}}</span></p>
</template>
</template>
<script>
(function () {
Polymer({
is: 'my-positions-list',
properties: {
url:{
type:String,
computed: 'url(this.item.title)'
}
},
url: function(title) {
return "/positions/" + title;
}
});
})();
</script>
</dom-module>
I am trying to create a computed property "url" using the title attribute of the "item" but had no luck, any idea how to achieve that?
I also get this weird message in my console from the polymer-mini.html file:
[my-positions-list::_prepTemplate]: top-level Polymer template must not be a type-extension, found template Move inside simple .
Any idea how to fix it?
Try this:
<dom-module id="my-positions-list">
<template is="dom-bind">
<firebase-collection data="{{aa}}"
location="https://myapp.firebaseio.com/positions/"></firebase-collection>
<template is="dom-repeat" items="[[aa]]">
<p><span>{{url(item.title)}}</span></p>
</template>
</template>
</dom-module>
<script>
(function () {
Polymer({
is: 'my-positions-list',
url: function(title) {
return "/positions/" + title;
}
});
})();
</script>
here the it in jsbin http://jsbin.com/lokegu/edit?html,output

How do I setup an on-click event listener on content elements in polymer?

I'm using polymer 0.8 which I understand has a new API, but I can't find a reference to this issue anywhere. I'm trying to accomplish this:
<center-focusable>
<template is="x-autobind">
<span on-click="setFocus">test?</span>
</template>
</center-focusable>
Which errors out with:
[span].[click]: event handler [setFocus] is null in scope ()
My element is defined as such:
<dom-module id="center-focusable">
<template>
<span on-click="setFocus">I work</span>
<content></content>
</template>
</dom-module>
<script>
Polymer({
is: "center-focusable",
setFocus: function () {
console.log("test");
}
});
</script>
Is this not possible?
What I've ended up doing is to defined another custom element that will trigger a custom event for me to catch.
<dom-module id="focusable-element">
<content></content>
</dom-module>
<script>
Polymer({
is: "focusable-element",
listeners: {
'click': 'setFocus'
},
setFocus: function () {
this.fire("center-focusable:center");
}
});
</script>
Then I'll catch it:
<script>
Polymer({
is: "center-focusable",
listeners: {
'center-focusable:center': 'setFocus'
},
setFocus: function (e) {
e.stopPropagation();
console.log("test");
}
});
</script>
Together:
<center-focusable>
<focusable-element>
This works.
</focusable-element>
</center-focusable>
Seems like an unnecessary amount of effort to handle this way though.
<span> is a regular HTML element, not a polymer element.
on-click is a polymer syntax.
I think you should use a regular html event : onclick (no dash).
Ex : <span onclick="console.log('test')">I work</span>