Rivetsjs iteration - by using an integer instead of collection - rivets.js

According to rivetsjs docs, we can render content by iterating over a object (array) by,
<ul>
<li rv-each-todo="list.todos">
<input type="checkbox" rv-checked="todo.done">
<span>{ todo.summary }</span>
</li>
<ul>
but is there a way where I can iterate by using a single integer to indicate number of times the iteration to take place?
I mean something like this,
<li rv-each="list.num_of_todos">
...
where num_of_todos is an integer to indicate number of iterations to take place.

There is no "proper" way of doing it. However, you can easily mimic this using a formatter that returns an array as shown below:
var list = {
name: 'to do list',
noOfToDos: 5
};
rivets.formatters.makearray = function(value) {
var result = [];
while (value--) {
result.push(0)
};
return result;
}
rivets.bind($("ul"), { // bind rivets
list: list
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/rivets/0.7.1/rivets.bundled.min.js"></script>
<ul>
<li rv-each-item="list.noOfToDos | makearray">Test</li>
<ul>

Related

nightwatch select current element's inner div

i'm new to nightwatch and was wondering if there's any good way to select the inner element of a current element and then get the text? Assuming i have the following..and i'm trying to retrieve the text inside (a) tags of each (li).
so i would like to get 'text to retrieve' and 'text to retrieve 2'.
...
<div class="mywrapperhere">
<ul>
<li>
<a>.....
<div>text to retrieve</div>
</a>
</li>
<li>
<a>.....
<div>text to retrieve 2</div>
</a>
</li>
<li>...
...
</div>
I'm thinking along these lines..
module.exports = {
'Demo test 1' : function (browser) {
....
//some sort of selector then gets from the anchor list
...'.mywrapperhere li a') : {
..
//for each element of the anchor..
{
//is there anyway to get it through something like
element.('div').innerHTML eg..
//or am i forced to use browser.execute( ...getElementsByTag method
//to achieve this?
}
}
browser.end();
}
};
Looking at the nightwatch api, i couldn't find anything allows me to do that. I'm particularly looking at the 'Element State' examples that doesn't seem to have a way for me to select the current element state's child element :
http://nightwatchjs.org/api/elementIdAttribute.html
The reason why i had to loop through the anchor tag level is because i'll need to retrieve a few more data besides the one from div tag, thanks!
You can use elementIdElement and elementIdText to get text from a child element. First you can get all the li elements by using .elements(). Then you use elementIdElement to get a child element. Then you can use elementIdText to get the text of this child element. Here is an example that will allow you to get the text of both list items in your snippet and log the values to the console.
browser.elements('css selector', 'li', function(listItems) {
listItems.value.forEach(function(listItem) {
browser.elementIdElement(listItem.ELEMENT, 'css selector', 'a', function(anchor) {
browser.elementIdText(anchor.ELEMENT, function(text) {
console.log(text.value);
});
});
}, browser); //have to pass in browser for scoping
});

Autoclosing unclosed tags in template

Hi i'm tring to create such template
<script type='text/mustache' id='user-template'>
<ul>
{{#each users}}
<li>{{name}}</li>
{{#startHidden #index 2}}</ul><ul style = "display:none;">{{/startHidden}}
{{#endHidden #index 2}}</ul>show all{{/endHidden}}
{{/each}}
</ul>
</script>
So the idea is to close the upper <ul> after second user in list open new hidden <ul> and put all rest users here. But instead i got closed <ul> and final html looks like:
<ul>
<li>name1</li>
<li>name2</li>
<ul style="display:none;"></ul>
<li>name3</li>
<li>name4</li>
show all
</ul>
This is my js
var data = [{name: "name1"},{name: "name2"},{name: "name3"},{name: "name4"}];
var users = new can.List(data);
var frag = can.view("user-template",{users:users},{
'startHidden' : function(currentIndex, usersToShow, options){
if (currentIndex() === usersToShow-1) {
return options.fn(this);
}
},
'endHidden' : function(currentIndex, usersToShow, options){
var length = options.scope.attr('users').length;
if ((length>usersToShow)&&(currentIndex() === length-1)) {
return options.fn(this);
}
}
});
Is there any way to prevent auto closing tags, or may i'm just doing it wrong completely?
This is not possible. can.view.live.html can only remove or add elements in sequence. A workaround would be to just add a "hidden" class on an LI if it shouldn't be visible.

using foundation 5 joyride with tabs

Is there a way to switch tabs with foundation 5 Joyride?
I have foundation tabs on the page and want Joyride to point elements on different tabs.
Like mentioned in the comment from Steven, you could use the callback either in the pre or post step callback function you activate the tab you need.
post_step_callback : function (){}, // A method to call after each step
pre_step_callback : function (){} // A method to call before each step
Hope this helps...
Here's what worked for me. I looked around and couldn't find anything useful, so wrote this. The hardest part was figuring out how to get the id of the target anchor. This was found buried in the 'this' object available to the callback.
$(this.$target)[0].id;
The 'content' class is used by foundation to identify the content to display when a tab is clicked. So traversing up the .parents tree finding the enclosing elements gives you the content tab(s) holding your link. And then of course you have to add an id to the <a> element of the tab you want to click. If you name it the same as your content div, with '-a' appended, you should be good to go.
html:
<dl class="tabs radius" data-tab id="my_tabs">
<dd class="active">Tab 1</dd>
<dd class="active">Tab 2</dd>
</dl>
<div class="tabs-content">
<div class="content" id="tab1">
<article id="joyride_stop1">...</article>
</div>
<div class="content" id="tab2">
<article id="joyride_stop2">...</article>
</div>
</div>
js:
$(document).ready(function() {
$(document).foundation('joyride', 'start', {
pre_step_callback: function(i, tip) {
var target = $(this.$target)[0].id;
if($('#' + target).parents('.content').length > 0) {
$('#' + target).parents('.content').each(function() {
var id = $(this).attr('id');
if($('#' + id).is(':visible') == false) {
$('#' + id + '-a').click();
}
});
}
}
});
});
This will work on any page, whether it contains tabs or not, so it can be universally included across a site.

overzealous filter on nested ng-repeat

I have a series of ng-repeated ul/li sets, and I want to make one set of li's visible when a link at the ul level is clicked.
My code is based around the answer found here: https://stackoverflow.com/a/12431211 which suggests that model mutation is the right way to do this.
The filter seems to be more zealous than anticipated, and I end up with nothing.
How can I achieve this functionality?
div ng-controller="DeviceController">
<ul ng-repeat="category in devices">
<a ng-click="setCategory(category)">{{category.name}}</a>
<li ng-repeat="device in selected.devices | filter: isSelected(category)">
{{device.name}}
</li>
</ul>
</div>
function DeviceController($scope) {
$scope.devices = [
{name: 'Desktop',
devices: [{id:1, name:'Olivia'},
{id:2, name:'Cayenne'}]
},
{name: 'Laptop',
devices: [{id:3, name:'Probook'},
{id:4, name:'Asus G750'}]
},
{name: 'Tablet',
devices: [{id:5, name:'Transformer Prime'},
{id:4, name:'Galaxy Note 10.1'}]
}
];
$scope.setCategory = function(category) {
$scope.selected = category
}
$scope.isSelected = function(category) {
return $scope.selected === category;
}
}
fiddle is here: http://jsfiddle.net/3rV6w/6/
I can't figure out why that isSelected() function works well as a condition on the active class (in the referenced answer) but doesn't perform equally as a filter. Scope perhaps? various console.log's suggest that it should work, but..
I've ended up discarding the filter, and using ng-hide instead.
<ul ng-repeat="category in devices">
<a ng-click="setCategory(category)">{{category.name}}</a>
<li ng-repeat="device in selected.devices" ng-hide="!isSelected(category)">
{{device.name}}
</li>
</ul>
What I think was happening is that the ng-filter was comparing 'device' with the true/false returned by isSelected(category). This will never match, so no results made it past the filter.

Why does my cycle slideshow hide all the slides?

The jQuery plugin cycle looks for elements of class slideshow. I want to add this class to a <ul> element to make a slideshow out of its <li>s. But when I add the slideshow class to the <ul> element, all <li> disappear and I get no slideshow whatsoever.
The HTML looks like this:
<ul>
<li>
<h3 class="expander">...</h3>
<div class="content">
<p>...</p>
<h4>...</h4>
<ul class="slideshow">
<li>...</li>
<li>...</li>
</ul>
</div>
</li>
...
</ul>
As you see, the slideshow <ul> is included in another list. This parent list consists of headers which reveal the content of each list item on click. I am hiding all the .contents programmatically when the DOM is ready. Then, I add a click listener to the .expanders so they can show the hidden .contents.
It is inside these .contentss that I have .slideshows which use the cycle plugin to cycle through their list items.
The other weird thing about all this is that the slideshow's worked perfectly before I transformed my headers into toggles for their associated content. Indeed, when I added the toggle functionality to the headers, the slides are no longer visible. But then if I take away the slideshow class, they are visible again. Of course, they no longer have slideshow functionnality...
Here is the javascript for all this:
$(document).ready(function()
{
var expanders = $('.expander');
expanders.each(function()
{
$('.content', $(this).parent()).toggle();
$(this).click(function()
{
$('.content', $(this).parent()).toggle("blind", {"easing":"easeInOutCirc"}, "normal");
});
});
$('.slideshow').each(function() {
var parent = $(this).parent();
$(this).cycle(
{
fx: 'scrollHorz',
easing: 'easeInOutCirc',
timeout: 0,
nowrap: 1
});
});
});
Any idea what could be causing this problem?
Apparently, I needed to move the cycle code above the toggle code, like this:
$(document).ready(function()
{
$('.slideshow').each(function() {
var parent = $(this).parent();
$(this).cycle(
{
fx: 'scrollHorz',
easing: 'easeInOutCirc',
timeout: 0,
nowrap: 1
});
});
var expanders = $('.expander');
expanders.each(function()
{
$('.content', $(this).parent()).toggle();
$(this).click(function()
{
$('.content', $(this).parent()).toggle("blind", {"easing":"easeInOutCirc"}, "normal");
});
});
});
I don't know why this works though, so better answers would be appreciated.

Resources