why won't my ng-options set a default value? - angularjs

I have an angular controller as written below;
controllers.controller('editCodeReviewCtrl', ($scope, $rootScope, $modalInstance, User, reviewRequestId, reviewRequestDetail, reviewRequestValue, reviewRequestTitle) ->
console.log "reviewRequestvalue", reviewRequestValue
$scope.reviewRequest = {}
$scope.reviewRequest.id = reviewRequestId
$scope.reviewRequest.detail = reviewRequestDetail
$scope.reviewRequest.value = '25.0'
$scope.reviewRequest.title = reviewRequestTitle
$scope.values = [
{value: '10.0'},
{value: '25.0'},
{value: '50.0'} ]
)
And my view template looks like the below;
<select ng-model="reviewRequest.value" ng-options="ele.value for ele in values" name="value" required class="friendly-margin pull-right">
</select>
I would expect that my drop down would have default value set, in the example case here it should be set to '25.0' but I'm not observing that behavior in the browser.
notice the html that is being output
<select ng-model="reviewRequest.value" ng-options="ele.value for ele in values" name="value" required="" class="friendly-margin pull-right ng-pristine ng-valid ng-valid-required ng-touched">
<option value="?" selected="selected" label=""></option>
<option value="0" label="10.0">10.0</option>
<option value="1" label="25.0">25.0</option>
<option value="2" label="50.0">50.0</option>
</select>
What direction to take this debugging?
i've looked at this post as well, how to use ng-option to set default value of select element which appears consistent with how I've written my own code.

As the documentation explains, when you use an expression such as
label for value in array
what is displayed in the select box is label, and what is bound to the ngModel is value. So, in your expression:
ng-model="reviewRequest.value" ng-options="ele.value for ele in values"
ele is one of the objects in the array of values. And if you want the object {value: '25.0'} to be the one selected in the select box, your ngModel should be a reference to this object (not an equal copy!):
So your controller should set reviewRequest.value to $scope.values[1].
Or, if you want the ngModel to contain the string 25.0and not the object containing this value, the expression should be
ng-options="ele.value as ele.value for ele in values"

In controller $scope.reviewRequest.value = $scope.values[1];

Related

ng-model of `<select>` not selecting when model is an object

How to set ng model value to form fields? ng model value not reflecting on my form
I have a $scope.obj, this obj from server when i try to apply in my form like
ng-model="obj.name", its not reflecting in <select> field. How to solve this issue?
<select class="form-control" ng-model="empEdit.qualification"
ng-options="qualification as qualification.qualificationName
for qualification in qualifications"
name="qualification">
<option value="" selected disabled hidden>
Choose your qualification
</option>
</select>
Controller:
$scope.empEdit = {
"name":"SomeName",
"id": 2,
qualification: {"id":1,"qualification_name: "BS"}
};
The ng-model directive compares object references not object contents. Use a primitive property for the ng-model value:
<select class="form-control" ng-model="empEdit.qualById"
ng-options="q.id as q.qualificationName for q in qualifications"
name="selQual1">
<option value="" disabled>
Choose your qualification
</option>
</select>
$scope.empEdit = {"name":"SomeName", "id": 2, qualById: 1};
For more information, see
why does Javascript comparison not work with objects?
AngularJS ng-options Directive API Reference - select as

Default for ng-select not working

I have a form using a select. I'm trying to set a default value, which I want to disable, so the dropdown will show "-- select state --" as the first option and will force the user to make a selection.
My problem is it's not working and the select always starts out blank.
Here is my code:
<select ng-model="contactEditCtrl.addressData.state" style="width: 50%;">
<option ng-disabled="$index === 1" ng-selected="true">--Select State--</option>
<option value="{{state.abbreviation}}" ng-repeat="state in contactEditCtrl.states">{{state.name}}</option>
</select>
Check this one with default <option> and ng-options:
<select ng-model="contactEditCtrl.addressData.state"
ng-options="state.name as state.name for state in contactEditCtrl.states" >
<option value="" ng-disabled="true">-- select state --</option>
</select>
Demo fiddle
It will be converted to:
<select ng-model="addressData.state" style="width: 50%;"
ng-options="state.name as state.name for state in states" class="ng-valid ng-dirty">
<option value="" ng-disabled="true" class="" disabled="disabled">-- select state --</option>
<option value="0">CCCCC</option>
<option value="1">QQQQQQ</option>
</select>
The empty option is generated when a value referenced by ng-model doesn't exist in a set of options passed to ng-options. This happens to prevent accidental model selection: AngularJS can see that the initial model is either undefined or not in the set of options and don't want to decide model value on its own.
In short: the empty option means that no valid model is selected (by valid I mean: from the set of options). You need to select a valid model value to get rid of this empty option.
Taken from here
So I'd suggest writing it like this.
var app = angular.module('myApp', []);
// Register MyController object to this app
app.controller('MyController', function MyController($scope) {
this.addressData = {state: "--Select State--"};
this.states = [{abbreviation: 'a', name:'ant'}, {abbreviation: 'b', name:'asd'}, {abbreviation: 'b', name:'asd2'}]
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.22/angular.min.js"></script>
<div ng-app='myApp' ng-controller='MyController as contactEditCtrl'>
<select ng-model="contactEditCtrl.addressData.state" style="width: 50%;">
<option value="--Select State--">--Select State--</option>
<option ng-value="state.abbreviation" ng-repeat="state in contactEditCtrl.states">{{state.name}}</option>
</select>
</div>

Propagate a Select with angularJS and read the option

I have a problem to read the information selected that is propagate in a select.
<div ng-show="deviceDetail != null" ng-model="example" >
<select >
<option value="NONE">Select</option>
<option ng-repeat="option in deviceDetail" ng-change="selectOption()">{{option}}</option>
</select>
<br/>
The value of the selection is: {{example}}
</div>
this is the HTML code and in the {{example}} I want to see the information that the user selected.
this is the part of the js releted:
$scope.selectOption = function() {
$scope.example = option.productName;
};
How I can fix it?
Thanks a million!
Set your example scope variable directly in <select> instead calling ng-change event and assigning into that function.
You can directly set option.name to example model with the use of ng-options too.
Here You have applied ng-model directive to div tag.
<div> is not input element so apply ng-model to <select> element here.
I would suggest to use ng-options directive for filling the selection list in <select>. ng-repeat is also fine.
Here you are binging ng-change event so in the function if requires then you can pass the object on which event is triggering so you can use that object or perform any operation on that.
Below is the modified template.
<div ng-show="deviceDetail != null">
<select >
<option value="NONE">Select</option>
<option ng-model="example" ng-options="option in deviceDetail" ng-change="selectOption(option)">{{option}}</option>
</select>
<br/>
The value of the selection is: {{example}}
</div>
You should to pass current option:
<select >
<option value="NONE">Select</option>
<option ng-repeat="option in deviceDetail" ng-change="selectOption(option )">{{option}}</option>
</select>
$scope.selectOption = function(option) {
$scope.example = option; // is there property .productName?;
};
Try this:
<div ng-show="deviceDetail != null">
<select >
<option value="NONE">Select</option>
<option ng-model="option" ng-options="option in deviceDetail" ng-change="selectOption(option)">
{{option}}</option>
</select>
<br/>
The value of the selection is: {{example}}
Js:
$scope.selectOption = function(option) {
$scope.example = option;
};
You should use ng-options
The value of the selection is: {{example}}

Can I use ng-model setter-getter option to transform the value of a variable in the model?

I have the following situation in angularjs:
<select ng-model="value">
<option ng-repeat="type in types">{{type.description}}</option>
<select>
The controller looks like:
$scope.value = null;
$scope.types=[{description: "asdf", id:"a"}, {description: "basdf", id:"b"}];
I want to set $scope.value, not with the value of type.description, but with the value of its corresponding id: type.id. But I still want to show the description in the dropdown select.
Can I accomplish this using the getterSetter option of ng-model? I have looked the documentation and it does not clarify much.
You don't need getterSetter to do that. All you need is ng-options:
<select ng-model="value" ng-options="type.id as type.description for type in types">
</select>

How to set the value attribute for select options?

Source JSON data is:
[
{"name":"Alabama","code":"AL"},
{"name":"Alaska","code":"AK"},
{"name":"American Samoa","code":"AS"},
...
]
I try
ng-options="i.code as i.name for i in regions"
but am getting:
<option value="?" selected="selected"></option>
<option value="0">Alabama</option>
<option value="1">Alaska</option>
<option value="2">American Samoa</option>
while I am expecting to get:
<option value="AL">Alabama</option>
<option value="AK">Alaska</option>
<option value="AS">American Samoa</option>
So, how to get value attributes and get rid of "?" item?
By the way, if I set the $scope.regions to a static JSON instead of AJAX request's result, the empty item disappears.
What you first tried should work, but the HTML is not what we would expect. I added an option to handle the initial "no item selected" case:
<select ng-options="region.code as region.name for region in regions" ng-model="region">
<option style="display:none" value="">select a region</option>
</select>
<br>selected: {{region}}
The above generates this HTML:
<select ng-options="..." ng-model="region" class="...">
<option style="display:none" value class>select a region</option>
<option value="0">Alabama</option>
<option value="1">Alaska</option>
<option value="2">American Samoa</option>
</select>
Fiddle
Even though Angular uses numeric integers for the value, the model (i.e., $scope.region) will be set to AL, AK, or AS, as desired. (The numeric value is used by Angular to lookup the correct array entry when an option is selected from the list.)
This may be confusing when first learning how Angular implements its "select" directive.
You can't really do this unless you build them yourself in an ng-repeat.
<select ng-model="foo">
<option ng-repeat="item in items" value="{{item.code}}">{{item.name}}</option>
</select>
BUT... it's probably not worth it. It's better to leave it function as designed and let Angular handle the inner workings. Angular uses the index this way so you can actually use an entire object as a value. So you can use a drop down binding to select a whole value rather than just a string, which is pretty awesome:
<select ng-model="foo" ng-options="item as item.name for item in items"></select>
{{foo | json}}
If you use the track by option, the value attribute is correctly written, e.g.:
<div ng-init="a = [{label: 'one', value: 15}, {label: 'two', value: 20}]">
<select ng-model="foo" ng-options="x for x in a track by x.value"/>
</div>
produces:
<select>
<option value="" selected="selected"></option>
<option value="15">one</option>
<option value="20">two</option>
</select>
If the model specified for the drop down does not exist then angular will generate an empty options element. So you will have to explicitly specify the model on the select like this:
<select ng-model="regions[index]" ng-options="....">
Refer to the following as it has been answered before:
Why does AngularJS include an empty option in select? and this fiddle
Update: Try this instead:
<select ng-model="regions[index].code" ng-options="i.code as i.name for i in regions">
</select>
or
<select ng-model="regions[2]" ng-options="r.name for r in regions">
</select>
Note that there is no empty options element in the select.
You could modify you model to look like this:
$scope.options = {
"AL" : "Alabama",
"AK" : "Alaska",
"AS" : "American Samoa"
};
Then use
<select ng-options="k as v for (k,v) in options"></select>
It appears it's not possible to actually use the "value" of a select in any meaningful way as a normal HTML form element and also hook it up to Angular in the approved way with ng-options. As a compromise, I ended up having to put a hidden input alongside my select and have it track the same model as my select, like this (all very much simplified from real production code for brevity):
HTML:
<select ng-model="profile" ng-options="o.id as o.name for o in profiles" name="something_i_dont_care_about">
</select>
<input name="profile_id" type="text" style="margin-left:-10000px;" ng-model="profile"/>
Javascript:
App.controller('ConnectCtrl',function ConnectCtrl($scope) {
$scope.profiles = [{id:'xyz', name:'a profile'},{id:'abc', name:'another profile'}];
$scope.profile = -1;
}
Then, in my server-side code I just looked for params[:profile_id] (this happened to be a Rails app, but the same principle applies anywhere). Because the hidden input tracks the same model as the select, they stay in sync automagically (no additional javascript necessary). This is the cool part of Angular. It almost makes up for what it does to the value attribute as a side effect.
Interestingly, I found this technique only worked with input tags that were not hidden (which is why I had to use the margin-left:-10000px; trick to move the input off the page). These two variations did not work:
<input name="profile_id" type="text" style="display:none;" ng-model="profile"/>
and
<input name="profile_id" type="hidden" ng-model="profile"/>
I feel like that must mean I'm missing something. It seems too weird for it to be a problem with Angular.
you can use
state.name for state in states track by state.code
Where states in the JSON array, state is the variable name for each object in the array.
Hope this helps
Try it as below:
var scope = $(this).scope();
alert(JSON.stringify(scope.model.options[$('#selOptions').val()].value));

Resources