In my application i have array of colors and i want to create a list of colors with checkbox.
var app = angular.module('app',[]);
app.controller('mainCtrl',function($scope){
$scope.colors = ['red','blue','green','yellow'];
});
so i create an ng-repeat to create a list :
<body ng-controller="mainCtrl">
<ul>
<li ng-repeat="c in colors">
<input type="checkbox" ng ng-true-value="{{c}}" ng-false-value=""/> {{c}}
</li>
</ul>
</body>
now i need to bind ng-model of each checkbox to something like f.tags.red or f.tags.blue so i change the code to something like this :
<li ng-repeat="c in colors">
<input type="checkbox" ng-model="f.col.{{c}}" ng-true-value="{{c}}" ng-false-value=""/> {{c}}
</li>
but this make my app broken.so ho to fix this for ng-model and ng-true-value also i create this jsbin .
thanks
There were a few things going wrong here. In general, inside properties of Angular that takes expressions (check the docs), you should not use {{x}}, but rather just x itself. So, you'r ng-model should not be f.col.{{c}} but rather f.col.blue and f.col.red etc. Now, in javascript, doing a.b and a['b'] is identical, so in this case, since c is a string, the correct model is f.col[c]. The same goes for the true-value, it should also simply be c.
Lastly, to get the example working, you need to actually create the objects maintaining your model (in this case $scope.f.col. Working example can be seen here: http://jsbin.com/citupepa/1/edit
Here is working demo for selection of colors:
jsbin
<ul>
<li ng-repeat="c in colors">
<input type="checkbox" ng-model="f.col[c]" ng-true-value="true" ng-false-value="false"/> {{c}}
</li>
Selected Colors: {{f.col}}
Related
I'm trying to show the name of the variable in my website written with AngularJS.
for example:
Backend code:
$scope.Bundles = {
Bundle1:["Sensor1","Sensor2"],
Bundle2:["Sensor1","Sensor2","Sensor3"],
Bundle3:["Sensor1","Sensor2","Sensor3","Sensor4"]
}
Frontend code:
<label ng-repeat="name in Bundles">
<div> *Want to show "Bundle#" (name), instead of it's value (the sensors)* </div>
</label>
Some notes:
From google searches, I always find people asking how to show the value of the variable, {{name}}, I know that, haven't found anything like the question im asking here
I need it because later in the code I will need to do a ng-repeat with "sensor in name" to show the sensors separately, so I really need a concrete solution and not a dirty one with another array holding the names.
Thank you.
You can access both the key and value using:
<label ng-repeat="(key, value) in Bundles">
<div> *Want to show {{ key }}, instead of it's value {{ value }} (the sensors)* </div>
</label>
You can use the tuple returned by the ng-repeat as stated in the docs https://docs.angularjs.org/api/ng/directive/ngRepeat
<label ng-repeat="(key,value) in Bundles">
You can use javascipt Object.keys(arr) to get all the keys and then iterate to the keys using ng-repeat.
$scope.BundleNumbers = Object.keys($scope.Bundles)
$scope.BundleNumbers will have ["Bundle1", "Bundle2", "Bundle3"]
<label ng-repeat="name in BundleNumbers">
{{name}}
</label>
The other and efficient/angular way to do is :
<label ng-repeat="(key,value) in Bundles">{{key}} </label>
Reference links:
Angular JS ng Repeat
JavaScript Object keys
I have this code
http://plnkr.co/edit/aycnNVoD96UMbsC7rFmg?p=preview
<div data-ng-app="" data-ng-init="names=['One']">
<input type="text" ng-model="names[0]">
<p>Looping with ng-repeat:</p>
<ul>
<li data-ng-repeat="name in names">
<input type="text" ng-model="name"> {{ name }}
</li>
</ul>
</div>
When i change value of name[0] in the first input box it changes values of the second input box.
But when i change value of name[0] in the second input box it does not change value of the first input box. Why?
It works if you bind your second input to : names[$index]
<input type="text" ng-model="names[$index]"> {{ name }}
This is due to ng-repeat creating a child scope, so the reference to name inside the ng-repeat is different to that original one in the names array, see here:
New AngularJS developers often do not realize that ng-repeat,
ng-switch, ng-view and ng-include all create new child scopes, so the
problem often shows up when these directives are involved. (See this
example for a quick illustration of the problem.)
Regarding as to why this happens, when you bind the input to name in names inside the ng-repeat, you are creating a new property on the new child scope created by the ng-repeat called name, and thus the ng-model of the textbox created by the ng-repeat is referencing a different name to that of the actual 0th element of the names array. As others have pointed out, if you use names[$index] you are implicitly referencing the 0th element of the names array, thus NOT creating a new name property on the child scope created by the ng-repeat. An angular best practice is not to have ng-models bound to primitives, rather objects, Sandy has mentioned in his answer if you bind to an object you will overcome this, and the 2 other posters have answered this by using $index to refer to the 0th element of the names array. This is one of the nucances of scope inheritance in angular.
A couple more handy links:
Here and here.
Just wanted to give my bit on this. Somewhat related to your problem as I see.
<body>
<div data-ng-app="" data-ng-init="names=[{value:'One'}, {value:'Two'}]">
<p>Looping with ng-repeat:</p>
<ul>
<li data-ng-repeat="name in names">
<input type="text" ng-model="name.value"> {{ name }}
</li>
</ul>
</div>
</body>
Instead of binding the array item directly to the control, I would prefer to create an object of the array and then bind value of each item. This way we can avoid reference problems.
A working prototype jsfiddle
Hope it helps.
You need to provide $index in your ng-model.
<li data-ng-repeat="name in names">
<input type="text" ng-model="names[$index]"> {{ name }}
</li>
You are binding ng-model="names[0]". So it means that you are binding value on first index of names array.
So when we write ng-model="names[$index]" in ng-repeat it means that all values will be bound accordingly into array. $index is an iterator offset of the repeated element.
names[0] = 'One'
names[1] = 'Two'
and so on!
I am following the tutorial on Lynda.com for AngularJS essential training.
Part of my index file looks like:
<div class="container" ng-controller="AppCtrl">
<h1>AngulAir</h1>
<ul class="nav nav-pills">
<li role="presentation" ng-class="destinationsActive">Destinations</li>
<li role="presentation" ng-class="flightsActive">Flights</li>
<li role="presentation" ng-class="reservationsActive">Reservations</li>
</ul>
<div ng-view>
</div>
<p>{{ flightsActive }}</p>
</div>
Now when I click on any link it should fire the setActive function defined in the AppCtrl which looks like this:
$scope.setActive = function (type) {
$scope.destinationsActive = '';
$scope.flightsActive = '';
$scope.reservationsActive = '';
$scope[type + 'Active'] = 'active';
};
Now the problem is very simple. The function should take the type for example 'destinations' and append 'Active' to it and set the scope variable 'destinationsActive' to active which in turn should be reflected in the ng-class directive of the li tags and the link should be active.
I have tried to insert alert('hello'); after setting it active which fires up. Now this means that the function is indeed being called. But when I do alert($scope.destinationsActive); it gives me a blank alert whereas it should give me active as the value.
I am not following with the exercise files and I feel that maybe because the tutorial is relatively older, there might be changes in the framework. I have already encountered such problems with the tutorial. Anyway, what is it that I am doing wrong?
In your ng-click directives you are passing the argument as a variable, not a string.
ng-click="setActive(destinations)"
Will pass in the value of the $scope.destinations, which is undefined. Try passing in a string i.e.:
ng-click="setActive('destinations')"
Note the single quotes
You need to put parenthesis around the parameters in your html javascript function call.
Destinations
Here is a working example: JSFiddle
I would recommend you to think of the model binding in more semantic way. For example use a checkbox instead of link and set the checkbox value as ng-model to a scope variable instead.
<input type="checkbox" ng-model="destinations">
<input type="checkbox" ng-model="flights">
<input type="checkbox" ng-model="reservations">
and thereafter use the model to reflect the rest of the changes (this is the answer to the original question, you have to specify a classname and a condition in brackets:
<li ng-class="{ destinationsActive: destinations }">
Pass argument as string in ng-click.
working code : http://jsfiddle.net/Virbhadrasinh/cLsLfkjm/
I am trying to print the count of elements filtered through a condition in AngularJS.
I am using ng-repeat to loop over collection and filter it to get counts and it works fine when there is value in it. However, when the filter returns empty result, Angular doesn't render the element and hence, I can't get it to display 0 count.
http://plnkr.co/edit/KNVwf2Yckxf1Qcyzcmea?p=preview
<div ng-repeat="i in iArr|filter:i.name='tim'">{{i.vals.length}}</div>
Does anyone have a clue to make it work in simple fashion.
Edit:
The question How to show a message when filter returns nothing in ng-repeat - AngularJS has a reply which actually solved my question but I don't know how. I am wondering if there is a very simple way to do it.
From that answer:
<select ng-model="shade" ng-options="shade for shade in shades"></select><br>
<ul>
<li ng-repeat="c in filteredColors = (colors | filter:shade)">{{c.name}}</li>
</ul>
<div ng-show="!filteredColors.length">No colors available</div>
The key is in c in filteredColors = (colors | filter:shade). The array result of the filter expression colors | filter:shade is being set to filteredColors, which then becomes available on the $scope object. Because of this, it can be used elsewhere in that controller scope. This is why it can be checked for its length to see if there are no colors.
Here is a working plnkr with solution and some extra
http://plnkr.co/edit/eOmHhR1VWjfYzHYqiEY1?p=preview
<body ng-controller="MainCtrl">
<label><input type="text" ng-model="search.vals">vals</label>
<label><input type="text" ng-model="search.name">name</label>
<div ng-repeat="i in filteredArr = (iArr | filter:search)">{{i.vals}} | {{i.name}}</div>
<div ng-if="!filteredArr.length">0</div>
</body>
I have a problem when binding ng-models with ng-repeat in a input tag type checkbox.
I will first attach my code and then explain more in detail.
app/main.html:
<div ng-repeat="feature in features">
<input type="checkbox" ng-model="features[$index].name">{{features[$index].name}}
</div>
<br></br>
<div class="highlighter">
<span ng-class="{emo:Emotions}">Manually</span> <span ng-class="{feel:Feelings}">create</span> the <span ng-class="{emo:Emotions}">entire</span>
</div>
main.js
angular.module('webClientApp')
.controller('MainCtrl', function ($scope,$http) {
[...other variables...]
$scope.features = [{'name':'Emotions'},{'name':'Feelings'}];
[...other parts of code]
});
Let's also assume that in the main.css file there are references to the classes .emo' and.feel' respectively to highlight the target word when the user ticks the box relative to the feature.
Now, the application works correctly when I listed all the inputs one by one like the following:
<input type="checkbox" ng-model="Emotions">Emotions
<input type="checkbox" ng-model="Feelings">Feelings
but I wanted to wrap it into an ng-repeat and list the features in the controller scope, since the features I will considered will be more. When I try the code above when I tick on the box the name changes to `true'.
I have read a lot about how to bind models to an ng-repeat inside a input tag but none of the solutions apply to my case.
Can someone please help me?
I changed thigs up quite a bit from your original model but... I did get something to behave similar to what you are looking for.
HTML
<div ng-app="webClientApp">
<div ng-controller="MainCtrl">
<div ng-repeat="(feature,enabled) in features">
<input type="checkbox" ng-model="features[feature]">{{feature}}</input>
</div>
<div class="highlighter">
<span ng-class="{emo:features.Emotions}">Manually</span> <span ng-class="{feel:features.Feelings}">create</span> the <span ng-class="{emo:features.Emotions}">entire</span>
</div>
{{features}}<br>
{{features.Emotions}}<br>
{{features.Feelings}}
</div>
JS
var app = angular.module('webClientApp', []);
app.controller('MainCtrl', function($scope, $http) {
$scope.features = {Emotions: true, Feelings: true};
});
Here's the fiddle: http://jsfiddle.net/rodhartzell/8YrxQ/
Hope this helps.
(i should add this as a comment, but I don't have enough rep. yet)
There is an issue on github which concerns your issue: https://github.com/angular/angular.js/issues/1404 and the comment of caitp shows some workarounds: https://github.com/angular/angular.js/issues/1404#issuecomment-30859987
You could (also) define a new javascript object in your controller and map the elements to that.
In controller: $scope.awnsers = {};
In template: ng-model="awnsers[feature.name]"
I hope this helps
You must use ng-checked instead of ng-model.
Check out this jsfiddle
http://jsfiddle.net/fizerkhan/z5z9s/24/
ngModel and ngChecked are not meant to be used together.
ngChecked is expecting an expression, so by saying ng-checked="master". If the expression is truthy, then special attribute "checked" will be set on the element
You should be able to just use ngModel, tied to a boolean property on your model. If you want something else, then you either need to use ngTrueValue and ngFalseValue (which only support strings right now), or write your own directive.