AngularJS + Bootstrap + Filter - angularjs

I'm trying to filter an user list. I'm using a custom Bootstrap version and want to display a 4 columns table.
So far, I've the following code:
<div ng-repeat="user in users | filter:searchValue | orderBy: 'username'">
<span ng-switch on="$index % 4">
<span ng-switch-when="0">
<div class="row-fluid">
<div class="span3" ng-if="users[$index+0]">
<user-item ng-model="users[$index+0]" on-click="showUser(userId)"></user-item>
</div>
<div class="span3" ng-if="users[$index+1]">
<user-item ng-model="users[$index+1]" on-click="showUser(userId)"></user-item>
</div>
<div class="span3" ng-if="users[$index+2]">
<user-item ng-model="users[$index+2]" on-click="showUser(userId)"></user-item>
</div>
<div class="span3" ng-if="users[$index+3]">
<user-item ng-model="users[$index+3]" on-click="showUser(userId)"></user-item>
</div>
</div>
</span>
</span>
</div>
So far, it works perfectly when there is no filter set.
When I set a searchValue, the $index cannot display the correct value (It will always start from 0 to the lengh of the filtered array).
My question is: Is there a way to correctly display the results in a 4-cols table and to filter the result ?

I don't think you need to add conditions in order to create a 4 column table using bootstrap css, simply use ng-repeat in a col-* element or using your custom span class (which I assume is created using bootstrap's mixins to create rows and columns).
DEMO
HTML
<input ng-model="searchValue.username" />
<div class="row-fluid">
<!-- simply change col-xs-3 to span3 -->
<div class="col-xs-3" ng-repeat="user in users | filter:searchValue | orderBy: 'username'">
{{user.username}}
<user-item ng-model="user" on-click="showUser(user.id)"></user-item>
</div>
</div>
If the markup above does not work in your case because of the custom bootstrap that you're using, then you are probably better off with a filter that partitions your current array into sections of subarrays that represents a row-column relationship, answered by m59 in this SO Answer.

Next time try to give a shot to ngTasty table http://zizzamia.com/ng-tasty/directive/table it's based to bootstrap css table :)

Related

How to access key value in angular js using ng-repeat?

I am trying to show the value from my json files using ng-repeat in angular js but I am unable to do that.
This is my code which I am trying:
<div ng-repeat = "x in myWelcome.definition">
{{x.attributes[0].children[0].node_id}}
<hr>
</div>
I have tried this and it is working:
<!-- first attributes start -->
<div ng-repeat = "x in myWelcome.definition.attributes">
{{x.rm_attribute_name}}<hr>
<div ng-repeat="a in x.children">
<div ng-if ="a.attributes">
a: {{a.attributes[0].rm_attribute_name}}
<div ng-if= "a.attributes[0].children">
chld
</div>
</div>
</div>
</div>
<!-- second attributes end -->
I am trying to understand how this line is working {{a.attributes[0].rm_attribute_name}} why it is not working like this {{a.attributes1.rm_attribute_name}} this is confusing. How it is shwoing all the results when I am using 0 and index.
And my json file is here in the plunker:
Plunker link of json and code
So how can I iterate here using ng-repeat here this code:
{{myWelcome.definition.attributes[0]}}
is working how can I show this in my view using ng-repeat I need to show all the attributes and child using ng-repeat.
ng-repeat can be used in the following way:
<div ng-repeat = "(key,value) in myWelcome.definition.attributes">
Key:{{key}} and value :{{value}}
<hr>
</div>
OR you can Try this:
<div ng-repeat = "x in myWelcome.definition.attributes">
<div ng-repeat="a in x.children">
a:{{a.node_id}}
</div>
</div>
Edited Plunker
I can see you are trying to implement ng-if and ng-repeat for your json file. You need to understand how ng-repeat works you can always check the index of you array using {{$index}}. So for your kind of problem I think this is the solution you should try.
<!-- first attributes start -->
<div ng-repeat = "x in myWelcome.definition.attributes">
{{x.rm_attribute_name}}<hr>
<div ng-repeat="a in x.children">
{{$index}}
<div ng-if ="a.attributes">
<div ng-repeat="b in a.attributes">
<hr>
{{b.children.length}}
<div ng-if="b.children.length > 1">
If the array is more than 1 please do the magic here
</div>
</div>
<div ng-if= "a.attributes[0].children">
chld
</div>
</div>
</div>
</div>
<!-- second attributes end -->
You can always see the indexes using {{$index}} and you should always use .length to check if it has more than 1 value. This way you can achieve what you want and you should also learn something about arrays in javascript and what is the differnece between dot and bracket. Please read this http://www.dev-archive.net/articles/js-dot-notation/. I think you should learn the basics of javascript.

AngularJS data-ng-hide puts blank spaces

It looks as though data-ng-hide works as expected except that it puts a space where the value would be shown. Is there a way to surpress that space so the values which should be shown are shifted to the right. For instance my loop has three people in it, but on the third person will be shown. The name for that person is to the far right rather than the first column on the left. I can't use data-ng-if as it removes values from the array.
This is the code:
<div class="row">
<label class="col-md-3" style="text-align: center">Checked Out to:</label>
<div class="col-md-8" ng-repeat="rows in chunkedData">
<div class="col-xs-4" ng-repeat="route in rows">
<span data-ng-hide="!route.checkedOut">{{route.user.firstName}} {{route.user.lastName}}</span>
</div>
</div>
</div>
This is the normal behavior: You're repeating a <div> that has the class "col-xs-4".
The ng-hide is inside it, meaning that for each route in rows, you'll display a column with or without text in it.
Try this instead :
<div class="col-xs-4" ng-repeat="route in rows | filter:{checkedOut:true}">
{{route.user.firstName}} {{route.user.lastName}}
</div>
AngularJS's documentation on ngRepeat and filters could also help you to better understand filters.

ng-repeat filter and repeat by heading

Trying to separate a group of filters that come back from a search that I am doing in my angular app. When I do the search i receive back the json and it is grouped by heading. Can I only repeat the items in that particular group and separate them that way? The reason is that each group will be in a unique UI module. So some of the list will be returned and displayed in a slider and some will be in radios.
Here is the:
<div heading="{{filter.name}}"
ng-repeat="filter in inventory.filters | filterOptions | orderBy:'name'"
is-open="true" show-attrs>
<h3>{{filter.name | uppercase}}</h3>
<div ng-repeat="option in filter.options">
<span ng-click="selectedFilter(filter, option.option, option.id)">
<a>{{option.option}}{{option.count>0 ? "("+option.count +")": ""}}</a>
</span>
<br/>
</div>
</div>
So ultimately I would like to be able to target the filter.name.color and when it is this particular group have it display in this particular type of UI.
Any suggestions or links to readings is appreciated.
So based on your posted answer it looks like what you want to do is only show filters that have a particular name. If so, ngFilter should be able to take care of this like so:
| filter:{name: 'blah'}
(or {name: something} if the value is in a variable called something)
Full HTML:
<div heading="{{filter.name}}"
ng-repeat="filter in inventory.filters | filterOptions | orderBy:'name' | filter:{name:'blah'}"
is-open="true" show-attrs>
<h3>{{filter.name | uppercase}}</h3>
<div ng-repeat="option in filter.options">
<span ng-click="selectedFilter(filter, option.option, option.id)"><a>{{option.option}}{{option.count>0 ? "("+option.count +")": ""}}</a></span>
<br/>
</div>
<!--Then I just repeat each ng-if that I want to be available -->
</div>
If you want to filter based on filter.name.color, you can use | filter:{name.color: 'blue'}, but if having that dot in the object notation doesn't sit quite right with you, an alternate option is to use a custom filter function:
| filter:hasColor.bind(null, 'blue')
Then in your controller:
$scope.hasColor = function (color, filter) {
return filter.name && filter.name.color === color;
};
Ok, so what I tried was this and it seemed to get me some control over what I am showing and where:
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div heading="{{filter.name}}"
ng-repeat="filter in inventory.filters | filterOptions | orderBy:'name'"
is-open="true" show-attrs>
<div ng-if="filter.name=='blah'" >
<h3>{{filter.name | uppercase}}</h3>
<div ng-repeat="option in filter.options">
<span ng-click="selectedFilter(filter, option.option, option.id)"><a>{{option.option}}{{option.count>0 ? "("+option.count +")": ""}}</a></span>
<br/>
</div>
</div>
<!--Then I just repeat each ng-if that I want to be available -->
</div>
So basically after the ng-repeat call within that div I am calling and nf-if and targeting the specific filter heading name/id to get only what I need to do.

Dynamic ng-model name for UI sortable

I have two nested ng-repeat to list dishes of different categories, and I'm using UI Sortable to be able to sort those lists. The ng-model name for the latter is dynamic (matches the value of the category listed) and I simply don't know how to set that name and make it work.
I used $eval() to set that dynamic name in the ng-repeat and works fine, but tried the same for the model and it doesn't work. Any ideas? Thank you!
"categories" object:
All categories have items, for example first one "breakfast" (matching the "value" of the category) will look like this:
What I've tried:
<div ng-repeat="cat in categories">
<div class="row">
<div class="category-title">{{cat.name}}</div>
</div>
<div ui-sortable ng-model="cat.value">
<!-- <div ui-sortable ng-model="$eval(cat.value)"> -->
<div class="row" ng-repeat="(key,dish) in $eval(cat.value)">
<div class="dish-title">{{dish.name}}</div>
</div>
</div>
</div>
The following should work:
<div ui-sortable ng-model="this[cat.value]">
<div class="row" ng-repeat="(key,dish) in this[cat.value]">
<div class="dish-title">{{dish.name}}</div>
</div>
</div>

Angular UI-Bootstrap 0.7.0 Collapse

I'm using the collapse feature of UI-Bootstrap (http://angular-ui.github.io/bootstrap/#/collapse) but when I use the collapse/toggle it loses the data and just returns "true".
Here is a Plunker to show my issue, http://plnkr.co/edit/e689Wureay8AMZQ9IIno?p=preview
A snippet from the code:
<div ng-repeat="name in names | filter:radioModel:true">
<span ng-model="namesList" ng-click="name = !name">Toggle collapse {{name.firstName}}</span>
<hr>
<div ng-show="name">
<div class="well well-large">{{name}} -</div>
</div>
That is because you are overwriting name in the ng-click here: ng-click="name = !name". That will make name true or false, depending on how many times ng-click was invoked.
What you want is to toggle a property on the model to collapse/uncollapse the following detail:
<div ng-repeat="name in names | filter:radioModel:true" >
<!-- change the property name.collapsed -->
<span ng-model="namesList" ng-click="name.collapsed = !name.collapsed">Toggle collapse {{name.firstName}}</span>
<hr>
<!-- use ng-hide to "collapse" -->
<div ng-hide="!!name.collapsed">
<div class="well well-large">{{name}} -</div>
</div>
</div>
Working demo: http://plnkr.co/edit/at7ceCYDXwWWlqUlKnkQ?p=preview

Resources