I have a loop "ng-repeat" inside of
<select ng-model="something"></select>
so that each option in a list is rendered as an
<option>
inside of select block. My aim is to make "something" (which is a ng-model attached to select) to be equal to a selected object inside of the list. At this moment when I do "value="{{option}}" as a parameter of option, I have a JSON object as a String. But what I need is to get an object as an object. The code looks like this:
<select ng-model="something">
<option ng-repeat="option in list" value="{{option}}">{{option.name}}</option>
</select>
The thing I want is easily done by using ng-options, but I need to add additional "style" parameters depending on option.anotherField to each
<option>
You can use ng-value instead of value, which gives you the object you want:
<select ng-model="something">
<option ng-repeat="option in list" ng-value="option">{{option.name}}</option>
</select>
What about approach via temp proxy and it's relation with something variable with the help of ng-change($scope.setModel) directive:
(function(angular) {
'use strict';
angular.module('app', [])
.controller('ExampleController', ['$scope', function($scope) {
$scope.list = [{name:'Tom',age:23},{name:'Max',age:33},{name:'Sam',age:43}];
$scope.something = $scope.list[0];
$scope.temp = $scope.something.name;
$scope.setModel = function(){
for(var item of $scope.list)
if(item.name == $scope.temp){
$scope.something = item;
break;
}
}
}]);
})(window.angular);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app='app' ng-controller="ExampleController">
<select ng-change='setModel()' ng-model='temp'>
<option ng-repeat='option in list track by option.name' ng-attr-title='{{option.age}}'>{{option.name}}</option>
</select>
<div>something: {{something | json}}</div>
</div>
i used ng-option or ng-repeat and change value of array but not bind new values
<select multiple="true" ng-model="staticField.text">
<option ng-repeat="t in Activitydata track by $index ">{{t}}</option>
</select>
and i change it to ng-option and does work
that's angular js code
$scope.Activitydata = [];
$scope.ActivityFound = function (from) {
for (var h = 0; h < allRequestDetails.procurationCustomers.length; h++) {
activitynote = allRequestDetails.procurationCustomers[h].notes;
actList = activitynote.split('|');
for (i = 0; i < actList.length; i++) {
//alert(1);
console.log('element : ' + actList[i]);
$scope.Activitydata.push(actList[i]);
}
$scope.Activitydata.removeDuplicates();
$scope.Activitydata.unique();
$scope.Activitydata.remove("");
};
....
....
If you are using ng-repeat the you should provide what value to bind as..
<select multiple="true" ng-model="staticField.text">
<option ng-repeat="t in Activitydata track by $index" value={{t}}>{{t}}</option>
So in this case the value of t gets bind to the ng-model..If you are using ng-options then you should use as..
<select multiple="true" ng-model="staticField.text" ng-options="t.code as t.name for t in Activitydata track by $index ">
<option value="">Select</option>
I am assuming here that ActivityData contains name and code as property....
The View Part
<div class="col-sm-8" data-ng-init="init_enable_disable()">
<select class="form-control" style="margin-top: 5px;" data-ng-model="schedule.scheduleType" data-ng-change="enable_disableDiv(schedule.scheduleType);">
<option ng-selected="{{type == defaultSelectedType}}" data-ng-repeat="type in schduleType">{{type}}
</option>
</select>
</div>
ng-repeat model
$scope.schduleType = ['Recurring', 'One time'];
I am updating the ng-model at the later time but it does not reflect in view
if (editRecord.freq_type === 1)
{
alert("one time");
$scope.schedule.scheduleType = 'One time';
}
what is going wrong please suggest me.
When you use ng-model and assigned value from controller no need to no need to use ng-selected in DOM. and better to initialize from controller.
Can try it
in your controller:
$scope.schduleType = ['Recurring', 'One time'];
$scope.schedule = {};
$scope.schedule.scheduleType = $scope.schduleType[0]; // initial select
$scope.enable_disableDiv = function(){
console.log($scope.schedule.scheduleType);
}
in HTML:
<select class="form-control" data-ng-model="schedule.scheduleType" data-ng-change="enable_disableDiv(schedule.scheduleType)">
<option ng-repeat="type in schduleType" value="{{type}}">{{type}}</option>
</select>
N.B: If you want to change option value from your controller then you should use $scope.schduleType instead of someValue for referencing because of when assign value from controller then not refer the schduleType . like want change based on condition then use like:
if(editRecord.freq_type === 1) {
$scope.schedule.scheduleType = $scope.schduleType[1];// not "one Time"
}
you could try
`$scope.$applyAsync(function(){
$scope.schedule.scheduleType = 'One time';
})`
I'm trying to use ng-repeat and ng-model in order to populate an array. The number of required elements in the array comes from a select element`.
The relevant part of my controller:
app.controller('AddMsgCtrl', function($scope){
$scope.range = function(n){
var array = [];
for(var i = 0 ; i < n ; i++)
array.push(i);
return array;
};
$scope.images = ['1.gif', '2.gif', '3.gif', '4.gif', 'any.gif'];
$scope.msg = { 'images': [] }
And the relevant part of my html:
Number of images:
<select class="browser-default" ng-model="numOfImages" ng-init="numOfImages=0">
<option ng-repeat="number in range(6)" value="{{number}}">{{number}}</option>
</select>
<div>
<div ng-repeat="n in range(numOfImages) track by $index">
<select class="browser-default" ng-model= ???>
<option ng-repeat="image in images" value="{{image}}">{{image}}</option>
</select>
</div>
</div>
Right now the user can select the number of images they wish to input and the same amount of select elements shows up. I'm just not sure how to use ng-model to add the chosen elements to the $scope.msgs.images array.
EDIT: I was closer than I thought. This seems to work correctly:
<select class="browser-default" ng-model="msg.images[$index]">
<option ng-repeat="image in images" value="{{image}}">{{image}}</option>
</select>
use msg.images[$index]
Plnkr Demo
HTML
Number of images:
<select class="browser-default" ng-model="numOfImages" ng-init="numOfImages=0" ng-options="number for number in range(6)" ng-change="updateImages()">
</select>
<div>
<div ng-repeat="n in range(numOfImages) track by $index">
<select class="browser-default" ng-model="msg.images[$index]" ng-options="image for image in images">
</select>
</div>
</div>
Msg : {{msg}}
Controller
$scope.range = function(n){
var array = [];
for(var i = 0 ; i < n ; i++)
array.push(i);
return array;
};
$scope.images = ['1.gif', '2.gif', '3.gif', '4.gif', 'any.gif'];
$scope.msg = { 'images': [] };
$scope.updateImages = function() {
// alert($scope.numOfImages);
$scope.msg.images.splice($scope.numOfImages, $scope.msg.images.length);
}
Extra function is added which will execute on selecting the number of images. Once you select a number and if you want to reduce the number, the array size also should be decreased if you want. For that I added.
I've created the following example so you can see exactly what is happening: http://jsfiddle.net/8t2Ln/101/
The same thing happens if I use ng-options. I have a different reason for doing it this way, but for the simplification of the example left that part out.
As you can see it has by default two options. I'm displaying the selected value of the ng-model next to the select so you can see what it is. When you use the top piece to add a third option it sets the value to the value of that new option as is evidenced by the displayed ng-model value next to the select, but the select itself doesn't change to show the correct value selected.
Below is the sample code at the link:
var testApp = angular.module('testApp', ['ngRoute']);
testApp.controller('Ctrl', function ($scope) {
$scope.newInput = '';
$scope.inputDevice = [
{
value: '1',
label: 'input1'
},
{
value: '2',
label: 'input2'
}
];
$scope.selectedDevice = '';
$scope.addType = function () {
var newElem = {
label: $scope.newInput,
value: '3'
};
$scope.inputDevice.push(newElem);
$scope.selectedDevice = newElem.value;
};
});
And here is the html:
<div ng-app="testApp">
<div ng-controller="Ctrl">
<p>
<input type="text" ng-model="newInput" />
<br />
<button ng-click="addType()">Add Type</button>
</p>
<select ng-model="selectedDevice">
<option></option>
<option ng-repeat="i in inputDevice" value="{{ i.value }}">{{ i.label }} - {{ i.value }}</option>
</select>
{{ selectedDevice }}</div>
</div>
This is exactly why you should not use ngRepeat to render select options. You should use ngOptions instead:
<select ng-model="selectedDevice"
ng-options="i.value as (i.label + '-' + i.value) for i in inputDevice">
<option></option>
</select>
In general, avoid using ngRepeat for rendering select options. There are at least two good reasons. ngRepeat creates separate child scope per iteration, which is not needed in case of option tag. Another important caveat is that with ngRepeat you can only bind select to primitives like strings, but you won't be able to write object to ngModel with it.
Here is a demo below.
angular.module('demo', []).controller('DemoController', function($scope) {
$scope.newInput = '';
$scope.inputDevice = [
{value: '1', label: 'input1'},
{value: '2', label: 'input2'}
];
$scope.selectedDevice = '';
$scope.addType = function() {
var newElem = {
label: $scope.newInput,
value: Number($scope.inputDevice[$scope.inputDevice.length - 1].value) + 1
};
$scope.inputDevice.push(newElem);
$scope.selectedDevice = newElem.value;
$scope.newInput = '';
};
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.8/angular.min.js"></script>
<div ng-app="demo" ng-controller="DemoController">
<form ng-submit="addType()">
<input type="text" ng-model="newInput" />
<button type="submit">Add Type</button>
</form>
<select ng-model="selectedDevice" ng-options="i.value as (i.label + ' - ' + i.value) for i in inputDevice">
<option>Select</option>
</select>
{{ selectedDevice }}
</div>
The problem is that, since you're not using ng-options the browser had not finished rendering at the point when you set the new selectedDevice. If you're set on on using ng-options you can use this workaround. Use $timeout to wrap your $scope.selectedDevice = newElem.value; to ensure it runs after the browser has finished rendering the changes with ng-repeat.
I also added code to increment the next value on successive adds because hardcoding it to '3' meant that the third option would continually be selected even when more are added.
var testApp = angular.module('testApp', ['ngRoute']);
testApp.controller('Ctrl', function($scope, $timeout) {
$scope.newInput = '';
$scope.inputDevice = [{
value: '1',
label: 'input1'
}, {
value: '2',
label: 'input2'
}];
$scope.selectedDevice = '';
$scope.addType = function() {
var last = Number($scope.inputDevice[$scope.inputDevice.length - 1].value) + 1;
var newElem = {
label: $scope.newInput,
value: last.toString()
};
$scope.inputDevice.push(newElem);
$timeout(function() {
$scope.selectedDevice = newElem.value;
}, 0);
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.10/angular-route.js"></script>
<div ng-app="testApp">
<div ng-controller="Ctrl">
<p>
<input type="text" ng-model="newInput" />
<br />
<button ng-click="addType()">Add Type</button>
</p>
<select ng-model="selectedDevice">
<option></option>
<option ng-repeat="i in inputDevice" value="{{ i.value }}" ng-selelected="{{ selectedDevice == i.value }}">{{ i.label }} - {{ i.value }}</option>
</select>
{{ selectedDevice }}
</div>
</div>
I had a similar problem and the reason was that my key was a number, but when trying to set another value I was sending a string. The workaround in this case is to force to set the model value to the same type as the key.
eg:
<select ng-model="model" ng-options="option.{{ key }} as option.{{ label }} for option in options">
<option value="">{{ emptyLabel }}</option>
</select>
if (scope.options.length > 0) {
scope.keyType = typeof(scope.options[0][scope.key]);
}
...
if (scope.keyType == 'number') {
scope.model = parseInt(newVal, 10);
} else {
scope.model = newVal;
}
I had the same issue of select not updating when ng-model is updated. I was retrieving the value for ng-model from a function which extracted the object from the array based on a key,value pair.
In doing this, the returned object had the hashkey property $$hashKey: "object:115"
The problem occurred when I created a copy of the object using angular.copy which stripped off this 'hashkey' property and hence would not get selected.
After I reorganized the code, to get ng-model value after angular.copy, the issue was resolved
ConstructorReviewers: function (oItem) {
this.PERSON_ID = oItem.PERSON_ID;
this.CHAIR_PERSON = oItem.CHAIR_PERSON;
/* // Commented this part and added it to EditItem function
this.oDepartment = CommonFactory.FindItemInArray(vm.oCommittee.arrDepartments, 'NAME', this.DEPARTMENT, 'item');
*/
this.EditItem = function () {
vm.EditItemOriginal = this;
angular.copy(this, vm.EditItem); // After this update the ng-model into vm.EditItem.oTitle object
vm.EditItem.oTitle = CommonFactory.FindItemInArray(vm.oCommittee.arrTitles, 'TITLE', vm.EditItem.TITLE, 'item');
vm.Popup.ShowPopup(true, 'new_edit', Constants.Mentoring.Popup.Edit);
}
}
I had the same problem. What solved it for me is converting the number to a string. Example:
$scope.selectedDevice = "" + newElem.value;