overzealous filter on nested ng-repeat - angularjs-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.

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

Rivetsjs iteration - by using an integer instead of collection

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>

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.

List with ajax-loading details in AngularJS

For a list of items I want to show details after item click. Details will be loaded with ajax request.
I have something similar to this: http://jsfiddle.net/asmKj/
How to modify this to work with details loaded dynamically?
For sure I have to prepare function in my controller like this:
$scope.getDetails = function (name) {
return $scope.details = myService.getDetails(name).then(function (details) {
return $scope.details = details;
});
}
But how to bind this data to details div?
I would rather change with something like this:
HTML
<ul class="procedures" ng-app ng-controller="sample">
<li ng-repeat="procedure in procedures">
<h4>{{procedure.definition}}</h4>
<div class="procedure-details" ng-show="procedures.isVisible">
<p>Number of patient discharges: {{procedure.discharged}}</p>
</div>
</li>
</ul>
JS
$scope.procedures = [
{
definition: 'Procedure 1',
discharged: 23
},
{
definition: 'Procedure 2',
discharged: 2
},
{
definition: 'Procedure 3',
discharged: 356
}
];
$scope.getDetails = function ($index) {
$http.get('your-url').success(
// use the data retrieved
procedures[$index].isVisible = !procedures[$index].isVisible;
);
}
There are basically two options.
Put everything in your procedure objects as separate properties (when the details are loaded) -- then you can just use procedure.showDetails in ng-repeat.
Use $index to get index from your procedures -- then you can use it to access any arbitrary collection from your scope in ng-repeat.
(may update my answer, when you provide more info about structure of your data; and if still needed)

Ember.js: How do I access a specific item in a CollectionView?

First off I want to say that I really like ember.js. I have tried both Knockout and Angular but found them a bit to obtrusive and everything had to be done their way. I feel like ember allows me a bit more freedom to structure things how you see fit. With that said I have a couple of questions.
1. I would like to do something like the following which obviously doesn't work:
<h3>{{ content.name }}</h3>
Instead I would have to create a binding:
<a {{ bindAttr href="url" }}><h3>{{ content.name }}</h3></a>
How do i create the url path in the view? I could easily create a computed property called url on the model but that feels horrible and not very MVC. Do I have to create a new view for the element or register a helper which feels a bit cumbersome?
Here's the complete code:
App = Ember.Application.create();
var sampleData = [ Ember.Object.create({ id: '123456789', name: 'John' }), Ember.Object.create({ id: '987654321', name: 'Anne' }) ]
App.itemController = Ember.ArrayController.create({
content: sampleData,
removeItem: function(item) {
this.content.removeObject(item);
}
});
App.ItemListView = Ember.View.extend({
itemDetailView: Ember.CollectionView.extend({
contentBinding: 'App.itemController',
itemViewClass: Ember.View.extend({
tagName: 'li',
url: '' // HOW TO GET '/item/123456789'
deleteButton: Ember.Button.extend({
click: function(event) {
var item = this.get('content');
App.itemController.removeItem(item);
}
})
})
})
});
<script type="text/x-handlebars">
{{#view App.ItemListView}}
<ul id="item-list">
{{#collection itemDetailView}}
<div class="item">
<a {{ bindAttr href="url" }}><h3>{{ content.name }}</h3></a>
{{#view deleteButton class="btn" contentBinding="content"}}Delete{{/view}}
</div>
{{/collection}}
</ul>
{{/view}}
</script>
2. I feel that the view "owns" the controller and not the other way around. Shouldn't the view be unaware of which controller it is hooked up to so you can reuse the view? I'm thinking about these to lines in the view:
contentBinding: 'App.itemController',
and
App.itemController.removeItem(item);
How do you structure this?
3. I realize everything is a work in progress and quite new with the name change and all but the documentation is quite unclear. The examples use the old namespace SC and there are lot of things missing on emberjs.com compared to the Sproutcore 2.0 guides, for example collections, arraycontrollers. I read somewhere here that collections will be phased out. Is that true and should I use #each instead?
Thanks for your help and for an awesome framework!
1.) If you want to use <a href="...">, you will need a computed property. It could be on your model or on a view. Another technique would be to use Ember.Button: {{#view Ember.Button tagName="a" target="..." action="..."}}...{{/view}}
2.) Typically you'll want to declare your controller binding in the template, rather than in the view. For example: {{#view App.ItemListView contentBinding="App.itemController"}}
3.) The #collection helper will likely be deprecated, so you should probably use an #each instead.

Resources