Ractive Numeric For Loop Possible? - ractivejs

I've been looking at the docs, and can't seem to find a way to do the following:
<script>
var maxStars = 5 ;
</script>
<script id="starryNight" type="text/ractive">
<ul class="starRating">
{{#for i=0 until {{maxStars}} }}
<li class="star"></li>
{{/for}}
</ul>
</script>
The idea being to store numerically, how many stars an item has been given, e.g. in a shopping cart. Then draw the correct
number of stars for that item.
If anyone can point me in the right direction, it would be much appreciated.

The issue is converting the number into an iterable value.
You could go with the pedestrian:
<ul class="starRating">
{{#each Array(maxStars) }}
<li class="star"></li>
{{/each}}
</ul>
Or go for something a bit more exciting by encapsulating the max stars in the iterable itself:
<ul class="starRating">
{{#each '★★★★★'.split('') }}
<li class="star"></li>
{{/each}}
</ul>

Related

Passing spacebar data context from parent template to child

I am having a silly trouble with nested templates. I want to create a dropdown menu with 4 main categories and about 2-3 subcategories for each main category.
<template name="Warehouselist">
<li class="dropdown">
<a class="dropdown-toggle" data-toggle="dropdown" href="#"> {{warehouse}} <span class="caret"></span></a>
<ul class="dropdown-menu">
{{#each Forms}}
{{>Form}} //Pass {{warehouse}} here
{{/each}}
</ul>
</li>
</template>
<template name="Form">
<li id="EWPacking">{{FormName}}</li>
</template>
The problem is that I don't know how to pass the {{warehouse}} data to the child template's helper in order so I can do something like this.
Template.bonus.helpers({
Userform: function(){
return UserForms.find({});
},
warehouse: function(){
return Warehouse.find({});
},
});
Template.Warehouselist.helpers({
Forms: function(Warehouse){
return Forms.find({Warehousename:Warehouse});
}
});
The point is that the helper of the child template has to return different data, depending on what is the Category of the parent element.
Use parent data context in the child template 'Form':
<template name="Warehouselist">
<li class="dropdown">
<a class="dropdown-toggle" data-toggle="dropdown" href="#">{{warehouse}}<span class="caret"></span>
</a>
<ul class="dropdown-menu">
{{#each Forms}}
{{>Form}}
{{/each}}
</ul>
</li>
</template>
<template name="Form">
<li id="EWPacking">
{{FormName}} - {{../warehouse}}</li>
</template>
And change your javascript for the Warehouselist template helper. Get the warehouse from the data context with Template.currentData() and pass it in the Forms.find().
Like this:
Template.Warehouselist.helpers({
Forms: function(){
var warehouse = Template.currentData().warehouse;
console.log('warehouse:', warehouse);
return Forms.find({Warehousename: warehouse});
}
});
If you want to pass warehouse to the child template like you asked use:
(BUT: this is not needed if you follow the solution above!)
{{#each Forms}}
{{>Form warehouse=warehouse}}
{{/each}}

Meteor's Blaze keeps re-using first list element's attributes

Using Meteor 1.2.02
I create a list with a helper:
<ul>
{{#each movie}}
<li id="{{_id}}">{{name}}</li>
{{/each}}
</ul>
The result:
<li id="1">Interstellar</i>
<li id="2">The Martian</i>
Then I hide Interstellar:
$("#1").hide();
Result:
<li id="1" style="display:none">Interstellar</li>
<li id="2">The Martian</li>
Then I remove Interstellar from the collection Movies.remove({name: "Interstellar"}) and this is what I end up with after Blaze reactively updates the DOM:
<li id="2" style="display:none">The Martian</li>
Does anyone know why now "The Martian" is inside the list element with display:none that belonged to Interstellar? I thought Blaze would have removed that first <li> elements and all its attributes. Thank you.

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 }}

How to do recursive templates in Meteor?

rather a theoretical question - how can I render recursive templates in Meteor? For example, displaying a comment on comment with unlimited number of comment sub-levels so that HTML would be diplayed as the following?
<section>
some text
<section>
nested text
<section>
further nested text and sections
.....
</section>
</section>
</section>
In my case I pass to the "tree" template a mongoDB document and this document can have unlimited number of sub-content levels. My example below doesn't work the way I want.
<template name="tree">
<div class="wrapper" style="border:1px solid red">
<ul>
{{#each getStructure}}
<li>
{{#each content}}
<ul>
<li>
<a class="item">{{text}}</a>
<!-- TODO: this stuff needs to be recursive.
{{#if sub_content}}
<ul>
{{#each sub_content}}
<li>
<a class="item">{{text}}</a>
{{#if sub_content}}
....
{{/if}}
</li>
{{/each}}
</ul>
{{/if}}
</li>
</ul>
{{/each}}
</li>
{{/each}}
</ul>
</div>
</template>
A simplified example of recirsuve, say you had a post sample template of:
<template name="post">
{{post_text}}
{{#each comments}}
{{>comment}}
{{/each}}
</template>
and a post helper of:
Template.post.helpers({
comments: function() {
return CommentCollection.find({post_id: this._id, parent_id: {$exists: 0}});
}
});
I would create a template for the comment layout and provide a helper in that for sub-comments, depending on your data structure something like the following:
<template name="comment">
{{comment_text}}
{{#each sub_comment}}
{{> comment}}
{{/each}}
</template>
and then the helper along the lines of:
Template.comment.helpers({
sub_comments: function() {
return CommentCollection.find({parent_id: this._id});
}
});
This would recursively produce the comments template for each sub-comment then roll back up the tree to the next #each and then print that comment and all of its sub-comments etc.

Indentation of li items in ng-repeat

I am using ng-repeat to show list items with some text. And I want every single item to be indented 10-20px to the right from the previous one. I don't have much experience with css.
<li ng-repeat="todo in todos"
ng-class="{'selectedToDo': (todo.id == selectedToDo)}">
{{todo.toDoText}}
</li>
Here is a jsFiddle with my code.
Thanks in advance!
you may use ng-style to solve your problem:
<li ng-repeat="todo in todos"
ng-class="{'selectedToDo': (todo.id == selectedToDo)}"
ng-style="{'margin-left': 10*$index+'px'}">
{{todo.toDoText}}
</li>
$index is a varibale that will be set by ng-repeat. You may use this to calculate your style.
Change your template with following::
<div ng-controller="MyCtrl">
<ul>
<li ng-repeat="todo in todos"
ng-class="{'selectedToDo': (todo.id == selectedToDo)}" style="text-indent: {{$index * 10}}px">
{{todo.toDoText}}
</li>
</ul>
</div>

Resources