I have the issue with Angular.js v1.3.11 and ng-options directive. The problem is next. I have a model value I know ahead but data for binding of options comes in AJAX request later and Angular.js produces that as two selected options: with my value and first one.
Html
<body ng-controller="MainCtrl">
<select ng-model="selectedYear" ng-options="o.year as o.year for o in options"></select>
</body>
Javascript
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope, $timeout) {
$scope.selectedYear = 2013;
$scope.options = [];
$timeout(function() {
$scope.options = [{year: 2012}, {year: 2013}, {year: 2014}];
});
});
Output
<select ng-model="selectedYear" ng-options="o.year as o.year for o in options" class="ng-pristine ng-valid ng-touched">
<option value="0" selected="selected" label="2012">2012</option>
<option value="1" selected="selected" label="2013">2013</option>
<option value="2" label="2014">2014</option>
</select>
Plunker
http://plnkr.co/edit/gFZ8Z7T5DhDPvk4G9tEU?p=preview
If you use "track by" then you can leave the $scope.selectedYear outside the $timeout callback function. You shouldn't really worry about the selected attribute. Change your code to include "track by o.year" and remove the "select as" part:
<select ng-model="selectedYear" ng-options="o.year for o in options track by o.year"></select>
Also in your controller you can set the predefined selectedYear like below to the object.
$scope.selectedYear = {year: 2013};
Here is a working plnkr:
http://plnkr.co/edit/UMfEIWlBwBnyj9wQ1FEx?p=preview
I have been experiencing this same issue. I used your plunker and updated the bits to 1.4 RC2. Be careful because this is a Release Candidate and is a pre-release.
Here is the working plunker http://plnkr.co/edit/UVL3dxYy0PNRcXuXG5y0?p=preview
<script data-require="angular.js#1.3.x" src="https://code.angularjs.org/1.4.0-rc.2/angular.js" data-semver="1.4.0-rc.2"></script>
This is a confirmed bug in 1.3 that no longer exists in 1.4. More information can be found here.
Related
I'm generating <option>'s with ng-options using a flat array. The problem I'm having is selecting the default option element I already have defined. Seems to be a very simple task and there's tons and tons of similar questions using objects or array of objects, but everything I have found and tried for my situation does not work.
<div ng-app="MyApp">
<div ng-controller="MyCtrl">
<select ng-options="opt as opt for opt in testOpt" data-ng-model="resultOpt">
<option value="">Choose Category</option>
</select>
</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.7.8/angular.min.js"></script>
angular.module('MyApp', []).controller('MyCtrl', ['$scope', function ($scope) {
$scope.testOpt = [
'ID',
'Name',
'Email',
'Address'
];
$scope.resultOpt = '';
}]);
What I'm trying to do is select the "Choose Category" option by default. As plenty of others have already suggested in other questions, I have tried to use $scope.resultOpt = '' in my controller and even tried ng-init="resultOpt = ''", but does that not work at all. This works great for an array of objects, or objects but not with simple arrays. I also do not want to go outside of the AngularJS framework, I don't like mixing and matching vanilla and AngularJS code, things become messy.
I found an existing jsFiddle that is working for AngularJS 1.4.8, but at least for AngularJS 1.7.8, this is not working when used with a flat array. Not sure if it was functionality that was removed in later versions, or it's simply a bug.
Full example:
https://jsfiddle.net/v4uesg02/4/
How can I select the "Choose Category" option by default using a flat array without going outside of AngularJS framework?
How to select the hard-coded null option with ng-options and ng-model
To select the single hard-coded <option>, assign null to the model:
angular.module('MyApp', []).controller('MyCtrl', ['$scope', function ($scope) {
$scope.testOpt = [
'ID',
'Name',
'Email',
'Address'
];
̶$̶s̶c̶o̶p̶e̶.̶r̶e̶s̶u̶l̶t̶O̶p̶t̶ ̶=̶ ̶'̶'̶;̶
$scope.resultOpt = null;
}]);
From the Docs:
Optionally, a single hard-coded <option> element, with the value set to an empty string, can be nested into the <select> element. This element will then represent the null or "not selected" option.
For more information, see
AngularJS <select> Directive API Reference
The DEMO
angular.module('MyApp', [])
.controller('MyCtrl', ['$scope', function ($scope) {
$scope.testOpt = [
'ID',
'Name',
'Email',
'Address'
];
$scope.resultOpt = null;
}]);
<script src="//unpkg.com/angular/angular.js"></script>
<body ng-app="MyApp" ng-controller="MyCtrl">
<select ng-options="opt as opt for opt in testOpt"
data-ng-model="resultOpt">
<option value="">Choose Category</option>
</select>
<br><br>
<button ng-click="resultOpt=null">Reset</button>
</body>
One thing i would like to add to #georgeawg's answer is to put disabled as an attribute to the option so that it is not reselect-able in the future
<option value="" disabled>Choose Category</option>
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
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)
I have been trying to create a dropdown for my Ionic app where a user can select different times too book an appointment. I set it up so that the hour selected will be a value. However, so far, I have been unable to get it to work. When I try to data bind or view the value in the console nothing appears.
Here is a snippet of what I have so far:
<select>
<option ng-model="bookingInfo.hour" type="time" value="08:00"> 8:00am</option>
<option ng-model="bookingInfo.hour" type="time" value="09:00"> 9:00am</option>
</select>
</label>
I would appreciate being pointed in the right direction.
Thank you.
In order to show the list of booking timings, you can create an array inside your controller and use ng-repeat to iterate over them.
then, your <select> would have an ng-model to bind the selected value.
Here's a working example!
angular.module("app", [])
.controller("myCtrl", function($scope) {
$scope.bookingInfo = [
{"hour": "8:00AM"},
{"hour": "9:00AM"},
{"hour": "10:00AM"},
{"hour": "11:00AM"}
]
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="app" ng-controller="myCtrl">
<select ng-model="selectedBooking" name="bookingInfo">
<option value="" disabled selected>Select your booking time</option>
<option value="{{info.hour}}" ng-repeat="info in bookingInfo" type="time">{{info.hour}}</option>
</select>
<div style="margin-top:20px">Selected time: {{selectedBooking ? selectedBooking : 'none'}}</div>
</body>
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.