I am new to AngularJS, and am thus confused as how to bind checkboxes or multi-select dropdowns to a separate list.
<body ng-controller="FooListCtrl">
<span ng-repeat="foolist in foos">
<select ng-model="selected" ng-options="foo for foo in foolist" multiple="">
</select>
</span>
</body>
'use strict';
function FooListCtrl($scope) {
$scope.foos = {"Bar": [ "foo", "bar"]};
$scope.selected = [];
}
FooListCtrl.$inject = ['$scope'];
Run the code: http://jsfiddle.net/gBcN2/
If I got right what you want:
You don't have ng-app definition.
On jsFiddle for snippets of AngularJS put No wrap - in <head> load mode, if you are using AngularJS as external resource.
Model selected has it's own "range", because you use ng-repeat. To see what I mean, here is fixed version of your code:
http://jsfiddle.net/gBcN2/2/
First {{selected}} works fine, but second is "outside" of ng-repeat scope.
PS:
You don't have to use ng-repeat if you want to use it like you wrote in your example: quick fiddle of how I'd do it.
Edit:
For checkboxes it's something like that - http://jsfiddle.net/qQg8u/2/
Related
I am trying to get the value from sessionStorage and map it to my ng-model, but
when i do that in my ng-init its not working.
The problem is in my actual code i am inside a ng-repeat so my sessionStorage becomes like below:
sessionStorage.getItem(item.itemId)
HTMl Code:
<div ng-app="">
<div ng-controller="MyCtrl">
Not Working <input ng-init = 'name = sessionStorage.getItem("SavedString")' type="text" ng-model="name" >
Working <input type="text" ng-model="name1" >
</div>
</div>
Controller:
function MyCtrl($scope) {
sessionStorage.setItem("SavedString","I'm a value saved with SessionStorage");
//RETRIEVE VALUE
$scope.name = "test"
$scope.name1 = sessionStorage.getItem("SavedString");
$scope.hi = 'Hello World';
}
Fiddle:
http://jsfiddle.net/393revrn/
i too tried in your way but i didn't find a the requirements to achieve this ......so i tried with making a function call with in init and appended session data to that model then i can see the proper output by making ng-init ='some()' here is the working plunker
UPDATE
From some source i found that HTML cannot understand session variables directly.
The sessionStorage, when accessed from the ng-init directive, is not understood by Angular; it will be parsed and interpreted as if it were a $scope function (which, I assume, is not).
So, in order for your example to work, you should do something like this in your controller:
$scope.sessionStorage = sessionStorage;
jsfiddle
Hi.
I have a problem with my application. I have to write several selects by using ng-repeat and each of these selects must be filled with the same data.
The problem is, when the one is changed, others selects are changes to the same value - why?.
I suppose that the problem is in the ng-model - maybe I don't understand how the "hierarchy" of the ng-model works.
If the name of the ng-model is only "option" - it doesn't work!
If the name of the ng-model is "something.option" - it also doesn't
work!
If the name of the ng-model is "something.else.option" - it does work
but all selects are filled!
HTML:
<div ng-controller="MyCtrl">
<div ng-if="models" ng-repeat="m in models">
<br><label>{{m.model}} ({{m.no}})</label><br>
<select ng-model="models.m.opModel" ng-options="opt.value as opt.text for opt in options" ng-change="foo()"></select>
</div>
</div>
JS:
var myApp = angular.module('myApp',[]);
function MyCtrl($scope) {
$scope.models = [
{'no':'A', 'model':'alpha'},
{'no':'B', 'model':'beta'},
{'no':'C', 'model':'gamma'}
];
$scope.options = [
{'value':1, 'text':'one'},
{'value':2, 'text':'two'},
{'value':3, 'text':'three'}
];
$scope.foo = function(){
alert($scope.models.m.opModel);
}
}
What am I doing wrong?
Thanks a lot.
You've created a scope object called "m" which is the current child of the "models" list. So for each dropdown, you're going to have a different "m" scope object. This is what you need to bind to in your ng-model so that the dropdown is bound to its unique parent in the "models" list.
Change <select ng-model="models.m.opModel"> to <select ng-model="m.opModel" to fix the problem.
To access the value with the foo() function, you'll need to use this updated function:
$scope.foo = function(index){
alert($scope.models[index].opModel)
}
And update the <select> like this:
<select ng-model="m.opModel" ng-options="opt.value as opt.text for opt in options" ng-change="foo($index)"></select>
You're creating an ng-model called "opModel" in the ng-repeat which means you'll have three new opModels under $scope.models. This is an array you can access later using an index value to specify which of the $scope.models[].opModel you want to access.
Notice that I've changed the ng-change code to send the current $index which is basically an ng-repeat counter. So your foo() function will receive either a 0, 1 or 2 which lets us access the specific ngModel that we need to access.
You are binding to the single object models. Inside an ng-repeat the repeated is available "in scope". You probably want to change this code to:
<div ng-controller="MyCtrl">
<div ng-if="models" ng-repeat="m in models">
<br><label>{{m.model}} ({{m.no}})</label><br>
<select ng-model="m.opModel" ng-options="opt.value as opt.text for opt in options" ng-change="foo()"></select>
</div>
</div>
Look at the ng-model="m.opModel", that is what I've changed. You are now updating the value of the single item, and not inserting a new object into an array which is then reused by all the ng-repeat items (which is why all the values would update at the same time).
Here is my code:
<body ng-app="app">
<div ng-controller="TestController">
<input type="checkbox" checked ng-repeat="num in array track by $index" ng-model="array[$index]" />
</div>
<script type="text/javascript">
var app = angular.module('app', []);
app.controller('TestController', function ($scope) {
$scope.array = [1, 2, 3, 4];
});
</script>
I especially add checked attribute to each <input> tag, for the checkbox could checked by default. But the result is none of the four checkbox is checked. Why?
I know if I add ng-checked="num" attribute could make the checked work, But I still wondering why the natural checked arrtibute doesn't work.
From angular docs
By default, ngModel watches the model by reference, not value.
When you say array[$index] it gives integer value which is you model name And its wrong
Please do it in this way
<div ng-controller="TestController">
<input type="checkbox" checked ng-repeat="num in array track by $index" ng-model="array[$index].checked" title="{{array[$index].val}}" />
</div>
<script type="text/javascript">
var app = angular.module('app', []);
app.controller('TestController', function ($scope) {
$scope.array = [{val:1,checked:true},{val:2,checked:false},{val:3,checked:true},{val:4,checked:true},{val:5,checked:false}];
});
</script>
ng-model="array[$index]" sets the dom checked property to false
As far as why checked doesn't work: when angular binds to the checkbox using either ng-checked or ng-model, it sets the checked attribute so that the checkbox looks correct in the browser - it doesn't care what the checked attribute is when it first binds.
You shouldn't combine checked with ng-model. Same applies for ng-checked with ng-model. Both modify the checkbox checked state which leads to unpredictable behavior.
If you want your checkbox to be checked by default do it via the ng-model directive.
The structure you are using seems a little bit weird. You checkboxes aren't checked because angular can't match the value.
By default using ng-model on a checkbox will yield true and false in the ng-model value when the user interacts with it. You can change that by using ng-true-value and ng-false-value. Check angular documentation.
If you add let's say ng-true-value="2" to your checkboxes then the second one will be initially selected because it starts with the value 2.
I have a multi-value selector, which I am trying to write an E2E test for. Using select(name).option works fine, but when I try to use select(name).options to select multiple values it doesn't work.
I tried to put together some code together to demonstrate, but can't get it working.
HTML:
<html lang="en">
<head>
<title>End2end Test Runner</title>
<script src="http://code.angularjs.org/1.0.1/angular-scenario-1.0.1.js"
ng-autotest>
</script>
</head>
<body ng-app="MyApp">
<div ng-controller="MyAppCtrl">
{{model.exampleValue}}
<select id="a_selector"
ng-model="model.selectedItems"
ng-options="item.name for item in model.items"
multiple="multiple">
</select>
</div>
</body>
Javascript:
var app = angular.module('MyApp', ['ngResource'])
app.controller('MyAppCtrl', function($scope) {
$scope.model = {};
$scope.model.exampleValue="an example value";
$scope.model.items = [{"name": "Product1"}, {"name": "Product2"}];
});
app.config(['$routeProvider', function ($routeProvider, $scope) {
$routeProvider.when('/', {controller:MyAppCtrl});
}]);
describe('my app', function() {
it('should display the home page', function() {
browser().navigateTo('/');
// this should work (when I can fix this code!)
select("model.selectedItems").option("Product1");
expect(element("#a_selector option:selected").count()).toEqual(1)
// this doesn't, nothing is selected
select("model.selectedItems").options("Product1", "Product2");
expect(element("#a_selector option:selected").count()).toEqual(2)
});
});
The line
select("model.selectedItems").option("Product1");
fails with error message:
Selector select[ng\:model="model.selectedItems"] did not match any elements.
I'd appreciate it if someone can (1) help me identify why the above code isn't working at all, and (2) help me understand why select(name).options isn't working. (I know there are other techniques I could use to achieve the same thing, but the real select in the production code also has an ng-change attribute which does not fire when I try the workarounds).
Thanks,
Graeme Ludwig.
I am still trying to figure out why the select(name).option() is not working but I could get your example working by the following modifications:
Include angular.js before angular-scenario.js
Take out ngResource dependency - you don't need it here
Put <span>{{model.selectedItems}}</span> after your <select> tag to see what you have chosen.
I will update once I figure out the second part.
Shouldn't select("model.selectedItems").option("Product1"); be select("#a_selector").option("Product1"); instead?
I have a display controller and a management controller. Inside my display controller, I have a dropdown selector with the list of items that have been selected.
I can get the display area dropdown to update the list, adding items as they are added in the management controller, but I cannot figure out how to select the newest item in the dropdown.
<div ng-controller="MyDisplayCtrl">
<select ng-model="item" ng-options="i.name for i in items">
</select>
</div>
I have made a jsfiddle to illustrate my situation. Ultimately, though, my question is how to bind that ng-model="item" to a data source updated by a service.
http://jsfiddle.net/whtevn/mUhPW/2/
Well, it looks like I've found a pretty satisfactory answer to this.
I exposed the storage object itself through the controller
function MyDisplayCtrl($scope, ItemStore) {
$scope.items = ItemStore.items;
$scope.item = ItemStore.currentItem;
// expose the itemstore service to the dom
$scope.store = ItemStore
$scope.getItem = function(){
return(ItemStore.currentItem);
}
}
and then address the currentItem directly
<div ng-controller="MyDisplayCtrl">
<select ng-model="store.currentItem" ng-options="i.name for i in items">
</select>
</div>
http://jsfiddle.net/whtevn/Cp2RJ/3/
Try using ng-options:
<div ng-controller="MyDisplayCtrl">
<select ng-options="i.name for i in items"></select>
</div>
See: http://docs.angularjs.org/api/ng.directive:select