More than finding a way to resolve this, I am now interested in understanding why this is not working.
Let's say I have this array in angular:
$scope.movieThemes = [ 'Fiction', 'Drama'];
And another array with with movies like:
$scope.movies=[{theme:'Drama', movie:'One million dollar baby'}, {theme:'Drama', movie:'Green mille'},{theme:'Fiction', movie:'Avatar'}, {theme:'Fiction', movie:'The Hobbit'}]
I have an ngRepeat with my themes
<div ng-repeat= "t in movieThemes">
And a nested datalist filtering the themes:
ng-repeat="m in movies|filter:{theme:t}
Where t is from the parent repeater like:
<datalist id="movieList">
<option ng-repeat="m in movies|filter:{theme:t}" value="{{m.movie}} - {{t}}"></option>
</datalist>
OK as you can confirm on my fiddle this is not working:
Online Demo
But the question is why not?
Worth to mentioned without a data list it works fine:
Without Data List Demo
Try like this. i change your filter function syntax and also add select tag to dataList.
Edit:
Your problem cuase for datalist id. i.e your datalist ids in ne-repeat are same. i change datalist ids by adding $index to it. now it work correctly.
var myApp = angular.module('myApp',[]);
myApp.controller('MyCtrl', ["$scope",function MyCtrl($scope) {
$scope.movieThemes = [ 'Fiction', 'Drama'];
$scope.movies=[
{theme:'Drama', movie:'One million dollar baby'},
{theme:'Drama', movie:'Green mille'},
{theme:'Fiction', movie:'Avatar'},
{theme:'Fiction', movie:'The Hobbit'}
];
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="MyCtrl">
<div ng-repeat= "t in movieThemes">
<input type="text" ng-model="t" />
{{t}} - {{$index}} <input type="text" placeholder="Users" list="movieList{{$index}}">
<datalist id="movieList{{$index}}">
<select>
<option ng-repeat="m in movies|filter:{theme:t}" value="{{m.movie}} - {{t}}"></option>
</select>
</datalist>
</div>
</div>
You can use groupBy filter. This way you don't need wot worry about themes array. You can write your own/use angular filters module.(https://github.com/a8m/angular-filter)
<ul>
<li ng-repeat="(key, value) in movies| groupBy: 'theme'">
Group name: {{ key }}
<ul>
<li ng-repeat="m in value">
player: {{ m.movie}}
</li>
</ul>
</li>
</ul>
BTW I like angular filters modules
Related
I am new to angular and I'm confused over this thing. I'm trying to populate a select box based on object inside an array. I want selectbox by using ng-repeat for that array... but initially i need to show only one selectbox after clicking add() next selectbox has to come. for ref:[initially one selectbox has to come]
HTML
<div class="col-lg-12" id="variant1" style="margin-top:10px" ng-repeat="variant in variants">
<div class="col-lg-4" style="text-align:right;padding-top:2px;padding-right: 20px" >
<label for="variant1name">Variant Name</label>
</div>
<div class="col-lg-6" >
<div >
<select class="form-control" ng-model="filterFormInputs.apps" ng-options="app.Application for app in variants" >
<option value="" disabled selected>Select an Application</option>
</select>
<label ng-repeat="checkbox in filterFormInputs.apps.details">
<input class="ecomtexttype1" type="checkbox" ng-model="checkbox.checked"> {{checkbox.name}}
</label>
</div>
</div>
</div>
Controller:
$scope.variants =
[
{"Application": "Color", "details":[{"name":"red"},{"name":"blue"},{"name":"black"}]},
{"Application": "Color", "details":[{"name":"red"},{"name":"blue"},{"name":"black"}]},
{"Application": "Color", "details":[{"name":"red"},{"name":"blue"},{"name":"black"}]}
]
I think that you can just have your add() function update the array... if things are configured correctly the new row should render due to the binding on the array.
As mentioned in comments you did not provide enough source code, so here is the assumed pseudo-code:
in html you might have
<button ng-click="$scope.add()">Add</button>
so in the controller
$scope.variants = [
// array of whatever you are displaying
{"foo":"bar1"},
{"foo":"bar2"}
];
$scope.add = function() {
variants.push({"foo":"bar_new"});
}
Have you considered using a Directive for this? That may work better, depending on your situation. Look into this: https://docs.angularjs.org/guide/directive
I have a nested Objects in JSON, and I need to populate the checkbox based on what comes in (dynamic) from JSON file, meaning, I wouldn't know in advance the name of the fields, or how many elements there could be. Here is a sample, but there could be more child and each child could have more or less item in it.
{
"Parent":{
"Child" :
{
"Child_01" : {
"description_01":false,
"description_02":false,
"description_03":false,
"description_04":false,
"description_05":false
},
"Child_02" :
{
"something_01":false,
"something_02":false,
"something_03":false,
"something_04": false
},
"Child_03" :
{
"things_01":false,
"things_02":false,
"things_03":false,
"things_04":false,
"things_05":false
}
}
}
}
Now, I need to populate a drop down from it, (child_01, child_02, child_03....) and when user choose one of them, I need to display checkboxes of all its properties. And of course be able to keep track of the chosen one.
Here is what I have.
$scope.children = response.data.parent.child;
$scope.childrenList = [];
angular.forEach($scope.children, function(value1, key1){
$scope.childrenList.push(key1);
});
and html:
<div ng-repeat="(key, data) in children">
<input ng-model="childrenListModel" type="checkbox" name="{{child}}" value="{{child}}">{{child}}</input>
</div>
Nothing works the way I intend to. Any help would be appreciated.
You probably need several nested ng-repeats. Have a look at this working plunker: http://plnkr.co/edit/K92JI7UlW9h6gh8SPeU5?p=preview
<div ng-repeat="child in children.Parent.Child">
<div ng-repeat="options in child">
<div ng-repeat="option in options">
<div ng-repeat="(key, val) in option">
<label for="{{key}}">
{{key}}
<input name="{{key}}" type="checkbox" ng-model="option[key]" />
</label>
</div>
</div>
<hr />
</div>
</div>
I'm trying to show the values of a specific JSON in the right Order. My JSON looks like :
{
"A":[{"id":"21","name":"Andrea"},{"id":"22","name":"Apple"}],
"B":[{"id":"21","name":"Baby"},{"id":"22","name":"Bali"}],
"C":[{"id":"21","name":"Candle"},{"id":"22","name":"Canada"}],
}
How to show values with ng-repeat :
<div ng-repeat="item in items">
</div>
like :
A
Andrea
Apple
B
Baby
Bali
C
Candle
Canada
Please check working example: http://plnkr.co/edit/lqoQvmXnimWYzqVU0wkg?p=preview
HTML
<div ng-repeat="(key, values) in items">
{{key}}
<div ng-repeat="item in values">
{{item.name}}
</div>
</div>
you can iterate over the object with:
<div ng-repeat="(key, value) in jsonData">
{{key}}
<div ng-repeat="item in value">
<div>{{item.name}}</div>
</div>
</div>
edit: I see the other guys added jsfiddle so enjoy :)
If your data be like this :
$scope.items={
"A":[{"id":"21","name":"Andrea"},{"id":"22","name":"Apple"}],
"B":[{"id":"21","name":"Baby"},{"id":"22","name":"Bali"}],
"C":[{"id":"21","name":"Candle"},{"id":"22","name":"Canada"}],
}
Consider item as map and iterate for (key,value) in map and the value will be associated List. And again iterate for the list in values as -
<div ng-repeat="(key,value) in items">
{{key}}
<div ng-repeat="item in value">
{{item.name}}
</div>
</div>
Try this plunker.
You print key of your json too so you should use '(key,value)' in ng-repeat to get value of key too.
code:
<div ng-repeat="(key,value) in data">
{{key}}
<div ng-repeat="item in value">
{{item}}
</div>
</div>
I am pretty new to angular. I am trying to add a filter parameter to my controller that will filter a search by every letter in a word, in order of letter. So imagine my data contained the following words: horses, oranges, terminator, Motorola, floral, orthopedic. When I searched for "or" in my search engine, all words would appear in the result because they all contain "or." Instead, I'd want a filter that filters my data in strict order of letter so I would only get "oranges" and "orthopedic"
This is my current filter in my controller:
$scope.activateFilter = function(textBoxValue) {
$scope.$apply(function() {
if ( textBoxValue=="") {
$scope.pages = FacebookPage.userPages;
} else {
$scope.pages=$filter('filter')($scope.pages,{name:textBoxValue});
}
});
};
This is the HTML for the filtering in case it helps:
<div id="searchEngineController" ng-controller="SearchEngineController">
<ul class="rig">
<li ng-repeat="page in pages">
<a ng-click="pageClick($index)">
<img src= "{{page.image}}" class="img-responsive img-circle" height="140" width="240">
<p style="font-size:25px; text-align:center">{{page.name}}<p>
</a>
</li>
</ul>
</div>
And my JS function:
pagesSearchBar.pageValueDidChange = function(value) {
angular.element(document.getElementById('searchEngineController')).scope().activateFilter(value);
};
Thanks!
You are re-inventing the wheel. Checkout angular build-in filter for ng-repeat
https://docs.angularjs.org/api/ng/directive/ngRepeat
<li ng-repeat="page in pages | filter:x">
Reading your code more thoroughly I think you have some misunderstanding of angular logic there as well. For example, you don't need extra function to detect search change and then getting the scope from dom. You could simply do:
<input type="text" name="search" ng-change="activateFilter(this.value)">
Something like that
UPDATE
So If I understand correctly now, you will want to display only one result for a filter. You could achieve that by somehow combining the filter with limitTo (no time to fiddle around now)
Or even as a temporary solution use css:
.list.filtered .class-of-item {display:none;}
.list.filtered .class-of-item:first-child {display:block;}
UPDATE 2
Ok, now I understand, so you want to use strict filtering in the way that only items starting with the search phrase show up. Angular is ready for that too, check below snippet
angular.module('filterApp',[]);
angular.module('filterApp').controller('MainCtrl',['$scope',function($scope){
$scope.items = ['Orange','Orangutan','Words','Orchid'];
$scope.customComparator = function(actual, expected){
return (actual.toLowerCase().indexOf(expected.toLowerCase()) === 0);
}
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="filterApp">
<div ng-controller="MainCtrl">
<ul>
<li ng-repeat="item in items | filter:'or':customComparator">{{item}}</li>
</ul>
</div>
</div>
Comparator reference: https://docs.angularjs.org/api/ng/filter/filter
Use something like below :
<input type="search" data-ng-model="searchName">
<li ng-repeat="list in lists | filter:searchName">{{list}}</li>
This filter is already provided by angular.js which itself is very powerful and quite robust.
I have made this plnkr which has lot more features. You might find this helpful.
There a filter in AngularJS named 'filter' that can make your life a lot easier in lesser code.
You can fine tune it to perform search on all fields in the object or you can restrict the search on some specific fields.
Copy pasting example from the link mentioned above:-
<div ng-init="friends = [{name:'John', phone:'555-1276'},
{name:'Mary', phone:'800-BIG-MARY'},
{name:'Mike', phone:'555-4321'},
{name:'Adam', phone:'555-5678'},
{name:'Julie', phone:'555-8765'},
{name:'Juliette', phone:'555-5678'}]"></div>
<label>Search: <input ng-model="searchText"></label>
<table id="searchTextResults">
<tr><th>Name</th><th>Phone</th></tr>
<tr ng-repeat="friend in friends | filter:searchText">
<td>{{friend.name}}</td>
<td>{{friend.phone}}</td>
</tr>
</table>
<hr>
<label>Any: <input ng-model="search.$"></label> <br>
<label>Name only <input ng-model="search.name"></label><br>
<label>Phone only <input ng-model="search.phone"></label><br>
<label>Equality <input type="checkbox" ng-model="strict"></label><br>
<table id="searchObjResults">
<tr><th>Name</th><th>Phone</th></tr>
<tr ng-repeat="friendObj in friends | filter:search:strict">
<td>{{friendObj.name}}</td>
<td>{{friendObj.phone}}</td>
</tr>
</table>
$scope.pages=$filter('filter')($scope.pages,{name:textBoxValue},true);
This above line will change it
$scope.pages = $filter('filter')($scope.pages,function(index, value){
return value === textBoxValue;
},true);
According to this jsbin i have an input and a select option and a list of movies. i want when user type something in input and then select an option in select, Angular filter the list of movies.
<div ng-controller="myController">
<input type="text" ng-model="search"/>
<select>
<option ng-repeat="item in dropdown" value="{{item}}">{{item}}</option>
</select>
<br/>
<ul>
<li ng-repeat="movie in movies">
Name: <strong>{{movie.name}}</strong> |
director: <strong>{{movie.director}}</strong> |
actor: <strong>{{movie.actor}}</strong>
</li>
</ul>
and my controller is something like this :
var myApp = angular.module('myApp',[]);
myApp.controller('myController',function myController($scope){
$scope.dropdown = ['name','director','actor'];
$scope.movies = [
{name:'test',director:'test di',actor:'test ac'},
{name:'test2',director:'test2 di',actor:'test2 ac'},
{name:'test3',director:'test3 di',actor:'test3 ac'},
{name:'test4',director:'test4 di',actor:'test4 ac'}
];
});
Your need a filter object in the ng-repeat for the movielist. Docs are here: http://docs.angularjs.org/api/ng/filter/filter.
<li ng-repeat="movie in movies | filter:filterObj">
Since the object ist dynamic i can only think of generating it on change of the input/select.
$scope.changeFilter = function () {
$scope.filterObj = {};
$scope.filterObj[$scope.item] = $scope.search;
};
Your jsbin is useless unless one can see and edit the code. Here is a working fiddle