Clear paper-dropdown-menu value - meteor

I can't find a way to clear a paper-dropdown-menu. I would like to reset it to its initial state when my form is sent (ajax). I can't find anything in the demos or doc.
I'm using meteor and polymer 1.0.
Thanks a lot
Here's some code:
<paper-dropdown-menu label="List's Color Tag" id="colorTag">
<paper-menu class="dropdown-content">
{{#each colors}}
<paper-item>{{.}}</paper-item>
{{/each}}
</paper-menu>
</paper-dropdown-menu>

Set the current selected item to null.
This was recently fixed.
https://github.com/PolymerElements/paper-dropdown-menu/pull/47

I had a similar issue and digged quite deep into the polymer code - it seems like there is no way for doing this. I found a quite dirty workaround, using an invisible item, but maybe it helps for you :
<paper-dropdown-menu label="List's Color Tag" id="colorTag">
<paper-menu class="dropdown-content">
<paper-item style="display:none"></paper-item>
{{#each colors}}
<paper-item>{{.}}</paper-item>
{{/each}}
</paper-menu>
</paper-dropdown-menu>
Than you should be able to set it to display nothing as selected by calling
document.getElementById('colorTag').contentElement.selected = 0;
I hope it works for you, it is not tested completely as I don't use Meteor and I use special IDs. I have set the invisible item to have the ID -1, so it does not mess with my other IDs.
So in my case it looks like this :
<paper-dropdown-menu id="carSelector"
label="[[label]]" attr-for-selected="car-id"
selected="{{selectedId}}" always-float-label
>
<paper-menu attr-for-selected="car-id"
selected="{{selectedId}}" class="dropdown-content">
<paper-item car-id="-1" style="display:none"></paper-item>
<template is="dom-repeat" items="[[cars]]" as="c">
<paper-item car-id$="[[c.Id]]">
<paper-item-body>
[[c.Plate]]
</paper-item-body>
</paper-item>
</template>
</paper-menu>
</paper-dropdown-menu>
And the corresponding call :
this.selectedId=-1;

You must add a selected attribute to the paper-drop-down first children (In this case the paper-menu)
<paper-dropdown-menu label="List's Color Tag" id="colorTag">
<paper-menu class="dropdown-content" selected="{{selectedItem}}">
{{#each colors}}
<paper-item>{{.}}</paper-item>
{{/each}}
</paper-menu>
</paper-dropdown-menu>
Then, when you want to reset it, just assign the selectedItem value to null
this.selectedItem = null

Related

Adding a css class in a dynamically created handlebars template

I have a JSON object that I am looping through to dynamically create x amount of ULs then LIs. I need to create two {{#each}} to create the content. However when I add a CSS class to my handlebars template it does not come through onto the UL as it does in the second {{#each}} - how do I stop this? Here is the template:
<div class="{{panel-container__Css-class}} {{panel-menu__Css-class}}" data-component="panel">
{{#each sections}}
<ul id="{{id}}" class="{{panel-menu__Css-class}}">
{{#each list}}
<li>{{title}}</li>
{{/each}}
</ul>
{{/each}}
</div>
Here is what i am passing in:
<nav data-component="navigation">
{{> nav-dropdown menu-button__Css-class="menu-button" menu-button__Css-class-nav="panel" target-id="panel-nav" }}
{{> nav-dropdown menu-button__Css-class="region-button" menu-button__Css-class-nav="region" target-id="panel-region" menu-button__copy=panel.copy}}
{{!--var links = [{"title": "Test","url": "/"}];--}}
{{> panel panel-menu__Css-class="navigation__menu-styles" panel-container__Css-class="navigation__menu-container" sections=navigation.sections links=navigation.sections.list }}
</nav>
I think what you are looking for is the Handlebars path that will allow you to obtain the value of panel-menu__Css-class from within {{#each sections}}. You need to understand that when you are within {{#each sections}}, your this context is the currently iterated element of the sections array. You must step up a level to the parent context which has the panel-menu__Css-class property you are trying to access:
<ul id="{{id}}" class="{{../panel-menu__Css-class}}">

Data available ("this") from a template event handler

projects.html
{{#if projects}}
{{#each projects}}
<div class="project-item">
<div class="project-name">
{{name}}
</div>
<div class="project-settings">
<span class="rename">Rename</span>
<span class="edit">Edit</span>
<span class="delete">
<!-- Here -->
</span>
</div>
</div>
{{/each}}
{{/if}}
projects.js
Template.Projects.events({
"click .project-item .delete": function (e, template) {
e.preventDefault();
debugger
// "this" refers to the specific project
}
});
In an event handler, I noticed "this" conveniently refers to a specific object inside the template where the event is related to. For example, in this case, the delete button is inside each projects block, and the handler for the delete button has this = some project. This is convenient, but I'd like to know the scopes and rules more completely. Can someone explain in briefly and point me to the right document?
This is a data context sensitive feature. Basically, there is a lexical scope in spacebars helpers. Have a look at this: http://devblog.me/no-data-context.html
The original pull request is here: https://github.com/meteor/meteor/pull/3560

How to IF NOT inside of {{ #each }} template

How can I render this Meteor Blaze Template ? I would like to use the negative of the IF, but I don't find anywhere how to use it.
<ul>
{{#each pages}}
{{#if (--NOT--) isCover }}
<li> some content {{value}} </li>
{{/if}}
{{/each}}
</ul>
Previous research not found solution
https://github.com/meteor/meteor/wiki/Using-Blaze
Check for equality in Spacebars?
Note: if I use only the if statement is working without problem, also I could do and else but I would like to have it only with the if(!isCover) solution
You need to use the {{#unless}} block helper.
http://blazejs.org/
{{#unless isCover}}
<li> some content {{value}} </li>
{{/unless}}
Faced same issue, we created a Utility kind of method to invert the boolean values.
"invertBoolean" : function (inputValueBoolean) {
return !inputValueBoolean;
}
which can be used as below
{{#if invertBoolean isCover }}

Meteor js - how to hook into the 'rendered' event of a recursive template?

I've got a situation where I'm rendering a Handlebars partial recursively based on a Mongodb tree structure, something like this :
<template name='menu'>
<ul class='menu'>
{{#each topLevelChildren}}
{{>menu-item}}
{{/each}}
</ul>
</template>
<template name='menu-item'>
<li>{{name}}
{{#if listChildren.count}}
<ul>
{{#each listChildren}}
{{>menu-item}}
{{/each}}
</ul>
{{/if}}
</li>
</template>
where the mongodb docs look like this :
{ _id : ObjectId("525eb7245359090f41b65106"),
name : 'Foo',
children : [ ObjectId("525eb60c5359090f41b65104"), ObjectId("525eb6ca5359090f41b65105") ]
}
and listChildren just returns a cursor containing the full docs for each element in the children array of the parent.
I want to do a bit of jquery makeup on the rendered tree, but I can't seem to hook into the 'rendered' event for the entire tree, something like
Template.menu-completed.rendered = function(){
// console.log('done!');
}
Trying this
Template.menu.rendered = function(){
console.log($('menu li'));
}
Not only doesn't this return the right results (brackets filled with commas), it also freezes web inspector (but not the app...).
Any help would be much appreciated !
This is an interesting problem :)
In the current version of Meteor (0.7.x) the rendered callback is called once when the template is first rendered, and then again once any partial inside the template is re-rendered. (This behavior will change when Meteor 0.8 - the shark branch or "Meteor UI" - lands.)
I've never tried doing things recursively, but it's going to be very hard to tell which callback you get is actually for the parent. One thing you might want to try is to start the recursive rendering in a template called menu-parent or something. That way, when the rendered callback is called for the first time (and as long as your data is loaded), you know the whole tree is rendered.
However, I suspect there might be a better way to do this. Generally, you should not be using jQuery to modify classes and attributes on DOM elements, as you'll confuse yourself as to what Meteor is doing and what jQuery is doing. Can you elaborate on what you are trying to achieve with the following, and I'll update my answer?
I need to find a specific anchor tag within the fully rendered template and add a class to it... and then add a class to each of its parents
Petrov, your code actually works for me, with just some minor modification to the jquery part. But perhaps I'm misunderstanding. Here is what I did:
Created a brand new project.
Added your template in the .html with minor change: <li><span class="name">{{name}}</span>
Created a new collection List.
Template.menu.topLevelChildren = function() { return List.find(); };
Then I added this handler:
Template.menu.rendered = function(e){
$('.name').each(function(i, e) {
console.log(e);
});
}
Now, upon render, for instance when new data is inserted into the List collection, I get a printout on the console like this:
<span class=​"name">​second​</span>​
<span class=​"name">​second2​</span>​
<span class=​"name">​second21​</span>​
<span class=​"name">​second22​</span>​
<span class=​"name">​third​</span>​
<span class=​"name">​third2​</span>​
<span class=​"name">​third21​</span>​
<span class=​"name">​third22​</span>​
<span class=​"name">​third​</span>​
<span class=​"name">​third2​</span>​
<span class=​"name">​third21​</span>​
<span class=​"name">​third22​</span>​
This is just a flat list of the tree elements I had added (where second2 is nested in second, and second2x is nested in second2, etc.). So from what I understand you could just take the selection coming back from jquery and find the tag you are looking for and change its class, as you wanted. Please let me know if I misunderstood something.
Complete code below.
test.html:
<head>
<title>test</title>
</head>
<body>
{{> menu }}
</body>
<template name='menu'>
<ul class='menu'>
{{#each topLevelChildren}}
{{>menu-item}}
{{/each}}
</ul>
</template>
<template name='menu-item'>
<li><span class="name">{{name}}</span>
<ul>
{{#each children}}
{{>menu-item}}
{{/each}}
</ul>
</li>
</template>
test.js:
List = new Meteor.Collection("List");
if (Meteor.isClient) {
Template.menu.topLevelChildren = function() {
return List.find();
};
Template.menu.rendered = function(e){
$('.name').each(function(i, e) {
console.log(e);
});
}
}
if (Meteor.isServer) {
Meteor.startup(function () {
// code to run on server at startup
});
}

in Meteor.template.rendered how to make a call after everything is rendered (after the {{#each}} loop finishes)

Hi I have this template
<template name="users">
{{#each user}}
<li id="{{_id}}">
<input type="checkbox" checked />
<span><select name="colorpicker">
{{#each color}}
<option value="{{mColorCode}}" {{selected ../mColor mColorCode}}>{{mColorName}}</option>
{{/each}}
</select>
</span>
<img width="40" src="data:image/png;base64,{{mImage}}" />
<span class="name">{{mUsername}}</span>
<p><span class="description">{{mDescription}}</span></p>
</li>
{{/each}}
</template>
What i want to do is after the template is rendered, i want to convert the dropdown to a colorpicker. I'm using a jquery plugin
Template.users.rendered = function(){
$('select[name="colorpicker"]').simplecolorpicker({picker: true});
}
The problem is sometimes its not working, (Sometimes the call is being made before the dom being ready.)
I want to call this plugin after everything is rendered. and not for each user added, how can i do this ?
Thanks
I've found Meteor to be a little funny with how often it renders templates, and jQuery functions can end up building up.
I've taken to adding console.log("users rendered"); to understand how many times and when the render callback is triggered.
One thing I've had some success with is wrapping that template inside another, and then tying the callback to the outside template. Something like this:
<template name="container">
{{> users}}
</template>
<template name="users">
{{#each user}}
<li id="{{_id}}">
<input type="checkbox" checked />
<span><select name="colorpicker">
{{#each color}}
<option value="{{mColorCode}}" {{selected ../mColor mColorCode}}>{{mColorName}}</option>
{{/each}}
</select>
</span>
<img width="40" src="data:image/png;base64,{{mImage}}" />
<span class="name">{{mUsername}}</span>
<p><span class="description">{{mDescription}}</span></p>
</li>
{{/each}}
</template>
And this just add the callback to the container
Template.container.rendered = function(){
$('select[name="colorpicker"]').simplecolorpicker({picker: true});
console.log("rendered");
}
Not totally sure why it works, but it has for me, hopefully someone can illuminate us both.
This is the solution that I used, it's also a hack if someone has a better solution please post it.
What i did was i put the rendered template in the callback of the subscribe of my collection.
So my code was something like this :
Meteor.subscribe('trackedUser',function(){
Template.users.rendered = function(){
......
}
}
I see this is a pretty old post, but since I had a problem and I think I've found a better way, here it is. The containing template will technically be rendered even while the contents are rendering. In my case I was trying to initialize a materialize modal. To make it work It had to do the following.
template.html
<div class="row" id="eventResults">
{{#each eventResults}}
{{> eventResult}}
{{/each}}
</div>
<template name="eventResult">
<div class="modal event" id="{{id}}">
<div class="modal-content">
...
and template.js
Template.eventResult.onRendered(function(){
this.$('.modal-trigger').leanModal();
By calling the code on the onRendered of the child element and using this.$('...'), the code doesn't get called multiple times for each element, just once each.

Resources