ng-model isn't updating when selecting an option - angularjs

I have a form with with option list
<form class="column-form">
<select id="classSelection" ng-change="classOptionChange()" ng-model="selectedClass" maxHeight="120">
<option selected value="">{{classOptions}}</option>
</select>
</form>
Sample class options is here
[{"id":"classR","text":" Color - Red"},{"id":"classG","text":"Color - Green"}, {"id":"classY","text":"Color - Yellow"}]
My directive is simple as I'm just trying to print out the value of my selected option. However, it's always null.
(function() {
appModule.directive('classDefault', [ '$translate', '$timeout', '$window', classService, function($translate, $timeout, $window, $document, classService) {
return {
restrict : 'E',
scope : {
.......
}
link : function(scope, element) {
scope.classOptionChange() = function() {
console.log(scope.selectedClass);
Any suggestions?
UPDATE - Thanks for all the suggestions below. Apparently, we are using this widget that supposed to render the option lists and then bind to the select tag but it is currently broken.

You need to bind the array to the select tag. One option to do so is to use the NgOptions directive.
Here's an working example
angular.module("app",[]).controller("ctrl", function($scope){
$scope.items = [{"id":"classR","text":" Color - Red"},{"id":"classG","text":"Color - Green"}, {"id":"classY","text":"Color - Yellow"}];
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.10/angular.min.js"></script>
<div ng-app="app" ng-controller="ctrl">
<select ng-change="classOptionChange()"
ng-model="selectedClass"
maxHeight="120"
ng-options="item as item.text for item in items">
</select>
<h3>{{selectedClass}}</h3>
</div>

It seems like you are not properly rendering all options that have been passed down to your directive. Ideally you should loop over the classOptions collection using ng-repeat/ng-options directive and render the select tag filled option's. And then specify ng-value-"opt" on each of your option element. That will basically help you assign whole option object to selectedClass ng-model.
Template
<form class="column-form">
<select id="classSelection"
ng-change="classOptionChange()" ng-model="selectedClass"
maxHeight="120">
<option selected value="">Select option</option>
<option ng-value="opt" ng-repeat="opt in classOptions">{{opt.text}}</option>
</select>
</form>
Demo Plunker

Related

Angular Select Tags

I am creating a select tag in angular. According to many sites I have read and some posts on here, it says when using the select tag to not use "ng-repeat" on the option tag but use "ng-options" on the select tag so that is how I set it up. My question is, I want a specific option tag selected by default, how do i set the selected attribute using this method?
<select class="form-control" ng-model="selected_group" ng-change="new_group($event)" ng-options="group as (group.group_name | decodeuri) for group in groups"></select>
Choosing a default is easy: set selected_group equal to a particular group in your controller.
The basic idea is that you have a collection and the selected option is to be stored in your ng-model. To designate a selection from the start, you need to put something in ng-model. That would have to be in your controller.
You could add an <option> tag:
<select class="form-control" ng-model="selected_group" ng-change="new_group(selected_group)" ng-options="group as (group.group_name | decodeuri) for group in groups">
<option value="">Please Select an Option</option>
</select>
Here I have created small working demo
<div ng-app="myApp" ng-controller="myCtrl">
<select class="form-control" ng-model="option.group" ng-options="group as (group.name | myfilter) for group in groups">
</select>
</div>
var app = angular.module('myApp', []);
app.filter('myfilter', function() {
return function(v) {
return v == 'test3' ? 'filtered test3' : v;
};
});
app.controller('myCtrl', function($scope) {
$scope.groups = [{id:1,name:'test1', phone:'1234567890'},
{id:2,name:'test2', phone:'1234567890'},
{id:3,name:'test3', phone:'1234567890'}
];
$scope.option={
group: $scope.groups[1]
}
});

AngularJS. When select have ng-model attribute, ng-selected not working

I'm trying to set ng-selected in my option element, selected attribute is set to true, but option not selected, When I remove ng-model from select all become working.
The question: How to make option selected, when I'm using the model?
Here is my plunker (selected not working here)
My code:
var app = angular.module("plunker", []);
app.controller("TestController", ["$scope", function($scope) {
$scope.test = 1;
$scope.array = [
{"id": 1, "name": "first"},
{"id": 2, "name": "second"},
{"id": 3, "name": "third"}
];
}]);
My template:
<body ng-controller="TestController">
Selected item must be {{ array[test-1].name }}
<select ng-model="myModel">
<option value="">Choose item..</option>
<option ng-repeat="item in array"
ng-value="item.id"
ng-selected="item.id == test">
{{ item.name }} ({{item.id == test}})
</option>
</select>
</body>
Thanks a lot for any help!
Don't use ngSelected with ngRepeat. Go with ngOptions:
<body ng-controller="TestController">
Selected item must be {{ array[test-1].name }}
<select ng-model="myModel" ng-options="item.id as item.name for item in array">
<option value="">Choose item..</option>
</select>
</body>
Don't use ngSelected with ngModel
From the Docs:
Note: ngSelected does not interact with the <select> and ngModel directives, it only sets the selected attribute on the element. If you are using ngModel on the select, you should not use ngSelected on the options, as ngModel will set the select value and selected options.
— AngularJS ng-selected API Reference
See additional Docs:
Using ng-repeat to generate select options
Using select with ng-options and setting a default value
See Stackoverflow:
Using ng-repeat to generate select options (with Demo)

ng-model not selecting values from dropdown list which are generated by ng-repeat

I am using ng-repeat to generate multiple drop down. But after storing the values it is not selecting the dropdown values as previously selected. In this example it should automatically display teacher1, teacher3 and teacher5 as selected values.
<div ng-app="myApp" ng-controller="MyCtrl">
<div ng-repeat="(i,teacherList) in Trip.teachers track by $index">
{{Trip.teachers[$index].id}}
<select m-required="true" ng-model="Trip.teachers[$index].id" class="teacher form-control" >
<option value="">Select Teacher</option>
<option ng-repeat="teacher in teachers" value="{{teacher.id}}">{{teacher.name}}</option>
</select>
</div>
<button ng-click="addTeacher();">Add Teacher</button>
<button ng-click="removeTeacher();" style="display:none;" class="removeTeacher">Remove</button>
</div>
and my angular code as below:
var myApp = angular.module('myApp', []);
myApp.controller('MyCtrl', function ($scope) {
$scope.Trip={
teachers : [
{"name":"teacher1","id":"1"},
{"name":"teacher3","id":"3"},
{"name":"teacher5","id":"5"}
]
};
$scope.teachers=[
{id:"1","name":"teacher1"},
{id:"2","name":"teacher2"},
{id:"3","name":"teacher3"},
{id:"4","name":"teacher4"},
{id:"5","name":"teacher5"},
{id:"6","name":"teacher6"}
];
$scope.addTeacher=function(){
$scope.Trip.teachers.push({"name":"","id":""});
document.getElementsByClassName("removeTeacher")[0].style.display="block";
}
$scope.removeTeacher=function(){
$scope.Trip.teachers.pop();
if($scope.Trip.teachers.length==1){
document.getElementsByClassName("removeTeacher")[0].style.display="none";
}
}
})
Here is the link to JSFiddle:
http://jsfiddle.net/dipgupta1986/10z7mda2/10/
It seems that you want to show the default value pre-selected, you can use ng-options and ng-model for setting the default value, by rewriting select as below :
<select m-required="true" ng-model="Trip.teachers[$index]"
ng-options="option.name for option in teachers track by option.id" >
Demo
ng-Options Documentation

Angular - ng-change not firing upon select change

Please see this relevant jsFiddle
Within the code I am trying to fire a method when a different option is selected to alert the user. However no event is being trigged
HTML:
<div ng-controller = "MyCtrl">
<p>Term</p>
<select id = "term" ng-change="test()">
<option value="5">5</option>
<option value="10">10</option>
<option value="15">15</option>
</select>
</div>
JS:
var app = angular.module('HelloApp', []);
app.controller('MyCtrl',['$scope','$element', function($scope, $element) {
$scope.test = function () {
alert ("changed!");
}
}]);
You have some issues.
Firstly: <div ng-controller = "MyCtrl"> - you have spaces in between.
Secondly, you're not declaring your app with ng-app. This is because you set your fiddle as jquery, and not Angular. If you had set it as angular you wouldn't need this in the fiddle
This is your fiddle setup
This is an Angular fiddle setup
Thirdly, to use select with AngularJS, you need to have an ng-model on the select tag. In this case i just used bob
<div ng-app="HelloApp"> <!-- declare your angular app. typically would go on body or html -->
<div ng-controller="MyCtrl">
<p>Term</p>
<select ng-model="bob" ng-change="test()">
<option value="5">5</option>
<option value="10">10</option>
<option value="15">15</option>
</select>
</div>
</div>
var app = angular.module('HelloApp', []);
app.controller('MyCtrl',['$scope','$element', function($scope, $element) {
console.log('ctrl working');
$scope.test = function () {
alert ("changed!");
}
}]);
Here is a working fiddle
http://jsfiddle.net/ctbLparv/
Also, if your intention is to just set a property based on the selection, you don't need to use ng-change. You can rely on the two-way binding.
So for example, this fiddle: http://jsfiddle.net/ps8jnyL8/
No select is being called. We also default the selected term to 10 when it first loads.
<div ng-app="HelloApp">
<div ng-controller="MyCtrl">
<p>Term</p>
<select ng-init="selectedTerm = '10'" ng-model="selectedTerm">
<option value="5">5</option>
<option value="10">10</option>
<option value="15">15</option>
</select>
<p>Selected Term: {{selectedTerm}}</p>
</div>
</div>
Here is the working JSFiddle:
https://jsfiddle.net/G8S32/1162/
The main change was adding this line:
ng-model="items"
which doesn't do anything except update the model and cause the event to fire.
Check out the documentation for ng-change:
https://docs.angularjs.org/api/ng/directive/ngChange
Particularly this line:
The ngChange expression is only evaluated when a change in the input
value causes a new value to be committed to the model.

Angular ui-sref on dropdown not working

I have an angular app with routing. I have a dropdown select defined as follows:
<select class="form-control" id="transactiontype" ng-model="tt">
<option><a ui-sref="cash">Cash</a></option>
<option><a ui-sref="cheque">Cheque</a></option>
<option><a ui-sref="debitcard">Debit</a></option>
<option><a ui-sref="creditcard">Credit</a></option>
</select>
When i select one of the dropdowns, somehow it is not loading the view i am referencing. Where am i going wrong? I also tried this:
<option ui-sref="creditcard">Credit</option>
I'm pretty sure it's because the a tags won't work inside the select - option tags.
As per this SO question: using href link inside option tag
Try writing a function that will redirect the page and trigger it based on the select change or maybe your model change, whatever it best for your program.
something like:
<select class="form-control" id="transactiontype" ng-model="tt" ng-change="locationChangeFunction()">
...
</select>
Your controller might look like:
angular.module('myApp')
.controller('myController', ['$scope', '$state', function ($scope, $state){
$scope.locationChangeFunction = function(){
$state.go($scope.tt);
}
}]);
EDIT
Use a combination of both solutions (credit to Hieu TB):
<select class="form-control" id="transactiontype" ng-model="tt" ng-options="opt.value as opt.label for opt in options" ng-change="locationChangeFunction()"></select>
ng-change will wait for the model change, which will change the DOM, which will trigger the change, now you're not running a resource consuming $watch function
consider using ng-options instead:
myApp.controller('MainController', ['$scope', '$state', function($scope, $state) {
$scope.options = [
{ label: 'Cash', value: 'cash' },
{ label: 'Cheque', value: 'cheque' },
{ label: 'Debit', value: 'debit' },
{ label: 'Credit', value: 'credit' }
];
$scope.$watch('tt', function(value) {
if(value) {
$state.go(value);
}
});
}]);
HTML:
<div ng-controller="MainController">
<select class="form-control" id="transactiontype" ng-model="tt" ng-options="opt.value as opt.label for opt in options">
</select>
</div>
EDIT: Agree with what #Likwid_T said, I think ng-change is the best choice to detect the change in select tag. I just forgot about it at that moment. So please refer to his answer too. Good day.
My solution ended up just using a generic href, but using the old ng-router declaration with a '#/' prefix. For example: instead of using...
<select class="form-control" id="transactiontype" ng-model="tt">
<option><a ui-sref="cash">Cash</a></option>
<option><a ui-sref="cheque">Cheque</a></option>
<option><a ui-sref="debitcard">Debit</a></option>
<option><a ui-sref="creditcard">Credit</a></option>
</select>
Try using href with '#/' prefix like so...
<select class="form-control" id="transactiontype" ng-model="tt">
<option>Cash</option>
<option>Cheque</option>
<option>Debit</option>
<option>Credit</option>
</select>

Resources