Using ng-options with ng-changed in select form input - angularjs

I'm trying to create a select widget using Angular's ng-options. I have this so far:
<select id="id_question" name="question" ng-model="post.Question"
ng-options="question.id as question.title for question in questions"
ng-change="updateFields(post.Question)" required>
</select>
I need an object passed through as a parameter to the 'updateFields' method. However, due to the ng-options using the 'id', this is not possible.
How do I retain using id as the value in the select widget but also have the ability to pass the 'question' object as a parameter in ng-change?

There is no way to pass complete object to your function if you are using ng-options. Instead what you can do is set your ng-model to some other property and use that property to assign value to your post.Question variable.
<select name="question" ng-model="selectedValue"
ng-options="question as question.title for question in questions"
ng-change="updateFields(selectedValue)" required>
</select>
in JS
$scope.updateFields = function(question) {
$scope.id = $scope.selectedvalue.id;
console.log(question);
}
Please have a look at plunker

When ever you use ng-model for a select element you need not pass the selected object as a event parameter in ng-change.
Have a look at the below code
$scope.updateFields=function(){
console.log($scope.selectedQuestion);
}
Your HTML must be as
<select name="question" ng-model="selectedQuestion"
ng-options="question as question.title for question in questions"
ng-change="updateFields()" required>
LIVE DEMO
Assumed json
$scope.questions=[
{title:'A',id:1},
{title:'Abcdef',id:4}];

Related

How to display a property of an object in select list in angular

I am binding state object from states list but I want to initialize that field with object.name, how can I do it in angular js
Add more details to get the correct answer...although heres some info which you might be looking
--> you can initialise any model with ng-init directive eg. ng-init="object.namekey"
--> for drop down list
<select ng-model="statesObject" ng-options="y.name for (x, y) in states">
</select>
--> and by the way you can get any object's name in javascript with myObj.constructor.name
Updated answer according to your comment
<select ng-model="States[0]" ng-options="state as state.stateName for state in States" name="State" required>
<option value="">Select State</option> </select>
$scope.States = [{stateName:'State1'},{stateName:'State1'},{stateName:'State3'},{stateName:'State4'}];
ng-model will do the trick....you just have to give the reference of the object from States array which you are using in ng-select
Plunker : http://plnkr.co/edit/rlArYYM8ygDB2IM8kG6M?p=preview

Select not updating when model is updated in AngularJS

When I update the model, a select box is not getting updated to the value in the model. The select has all the valid options, however, the value from the model is not being selected. In the code below, the value in the model is "FACEBOOK". The mapping to the model is correct because value from the select box saves correctly. The issue is occurring when I load the model on page display.
Here is the html:
<select
class="form-control"
required
ng-model="channel.channeltype"
ng-options="obj.name for obj in contactchannels track by obj.id">
</select>
The generated html is:
<select ng-options="obj.name for obj in contactchannels track by obj.id">
<option selected="?" value="selected"></option>
<option label="Facebook" value="FACEBOOK">Facebook</option>
<option label="Skype" value="SKYPE">Skype</option>
<option label="Instagram" value="INSTAGRAM">Instagram</option>
</select>
thanks in advance,
Use ng-selected instead of selected. You can make it true and false.
And also show how you are doing in JS file with scope.
If it doesn't work like this, then give ng-change="some_func()" and define that function in JS, $scope.some_func = function() {}

ng-options Default Value from JSON

I have been toying around with a modal form, the form works great to submit data, but now I need the form to edit data. So I want to populate the form from a callback from the server. The structure of the form is as follows:
HTML:
<div class="form-group modalContent">
<label for="manufacturer">MANUFACTURER</label>
<select class="form-control" id="manufacturersList"
ng-model="form.manufacturers" required
ng-options="man.manufacturer for man in manufacturers | orderBy:'manufacturer'"></select>
</div>
AngularJS:
$scope.form = {
//The value will be the value from the callback
"manufacturers": "Acer"
}
EDIT: CALL BACK
{"status":{"error":"none","code":200,"description":"none","message":"success"},"manufacturers":[{"manID":"2",
"manufacturer":"Acer"},{"manID":"3","manufacturer":"Honeywell"},{"manID":"11","manufacturer":"HP"},{"manID":"9","manufacturer":"Juniper"},{"manID":"1","manufacturer":"Lenovo"},{"manID":"6","manufacturer":"Logitech"},{"manID":"8","manufacturer":"Netgear"},{"manID":"7","manufacturer":"Other"},{"manID":"10","manufacturer":"StarTech"},{"manID":"5","manufacturer":"Viewsonic"},{"manID":"4","manufacturer":"Zebra"}]}
Shouldn't this populate the value in the <SELECT>?
ng-model points to the variable that holds the selected value.
And according to the syntax you used in ng-options you should place manufactures in $scope directly.
<select class="form-control" id="manufacturersList"
ng-model="selectedManufacturer" required
ng-options="man for man in manufacturers | orderBy:'manufacturer'">
</select>
$scope.manufacturers = ["Acer", 'HP', 'Toshiba', 'Lenovo', 'ASUS'];
Example in Plunker
Hope this helps

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 do I get the ng-model of a select tag to get the initially-selected option?

I'm pretty new to Angular, so I may be going about this all wrong...
I have a <select> similar to the following:
<select ng-model="mySelectedValue">
<option value="">--</option>
<option ng-repeat="myValue in someDynamicArrayOfValues" value="{{myValue}}" ng-selected="myFunctionForDeterminingWhetherValueIsSelected(myValue)">{{myValue}}</option>
</select>
This mostly works... The dropdown initially renders with the correct option selected, and if I change the selected option, then mySelectedValue will get the new selection. However, mySelectedValue does NOT get the initially-selected option. mySelectedValue is blank until I change the value in the dropdown.
I looked at ng-init, but that seems to get evaluated before someDynamicArrayOfValues is set...
Is there a way I can get mySelectedValue to receive the value in the initially-selected <option>?
UPDATE:
I forgot to mention that I had also tried using ng-options, but haven't had any luck getting that to work in conjunction with determining which option was selected.
I've tried this:
<div ng-show="someDynamicArrayOfValues">
<select ng-model="mySelectedValue" ng-options="arrayValue for arrayValue in someDynamicArrayOfValues" ng-selected="myFunctionForDeterminingWhetherValueIsSelected(arrayValue)">
<option value="">--</option>
</select>
</div>
and this:
<div ng-show="someDynamicArrayOfValues">
<select ng-model="mySelectedValue" ng-options="arrayValue for arrayValue in someDynamicArrayOfValues" ng-init="myFunctionForSettingSelectedValue()">
<option value="">--</option>
</select>
</div>
but neither of those work because the select is built (and ng-init and ng-selected both get evaluated) before someDynamicArrayOfValues has been set and, therefore, before the <select> is even visible. When using <option ng-repeat="...">, the <select> doesn't get built/initialized until after someDynamicArrayOfValues is set, which is why I had been going that direction.
Is there a way to get the ng-options technique to work while, at the same time, having the select dependent on someDynamicArrayOfValues (if ng-options is the better way to go)?
UPDATE 2:
Here's a Plunker (modified from ababashka's answer) that is a little closer to what I'm ultimately trying to achieve: http://plnkr.co/edit/Kj4xalhI28i5IU0hGBLL?p=preview. It's not quite there yet... I'd like it to have each of the 3 dropdowns set with the closest-matching dynamic value once someDynamicArrayOfValues is set.
I think that it will be good it you will use ng-options attribute of select tag. It's an angular directive which creates options according to Array of options. You can take a look at select documentation
If you use your code - your function myFunctionForDeterminingWhetherValueIsSelected works twice for every option at initialization and once for every option item when you select some another option.
Demo with your code: http://plnkr.co/edit/0IVNLHiw3jpz4zMKcB0P?p=preview
Demo for select you could see at description of select directive.
Update
At first, to see when value is changed - you need to use ng-change attribute of select tag, like this:
<select ng-model="mySelectedValue"
ng-options="myValue for myValue in someDynamicArrayOfValues"
ng-change="myFunctionForDeterminingWhetherValueIsSelected()">
<option value="">--</option>
</select>
Then, i don't know how does myFunctionForSettingSelectedValue look like, but there are 2 variants:
This function returns some value - then you need to use ng-init next way.
Controller:
$scope.someInitFunc = function () {
return 'One';
};
HTML:
<select ng-model="mySelectedValue"
ng-options="myValue for myValue in someDynamicArrayOfValues"
ng-change="myFunctionForDeterminingWhetherValueIsSelected()"
ng-init="mySelectedValue = someInitFunc()">
<option value="">--</option>
</select>
You set value of mySelectedValue in this function - then you do this.
Controller:
$scope.someInitFunc = function () {
$scope.mySelectedValue = 'One';
};
HTML:
<select ng-model="mySelectedValue"
ng-options="myValue for myValue in someDynamicArrayOfValues"
ng-change="myFunctionForDeterminingWhetherValueIsSelected()"
ng-init="someInitFunc()">
<option value="">--</option>
</select>
I have created an example which implements the first version of using ng-init. When new value is selected - it's printed to console.
Also, i moved options to the options.json file. So options are initialized just after ajax request was finished. Everything works great.
Demo: http://plnkr.co/edit/pzjxxTnboKJXJYBGcgNb?p=preview
Update 2
Hello again. I think you don't need to have any ng-init according to your requirements. You can just initiate values of your model when http request is finished. Also i don't understand why do you need ng-change function in this case.
Here is modified code you need from your plunk where values of ng-models are initiated after options are loaded.
JavaScript:
.controller('MainCtrl', function($scope, $http) {
$scope.someStaticArrayOfValues = ['One', 'Two', 'Three'];
$scope.mySelectedValues = {};
$http.get('options.json').then(
function (response) {
$scope.someDynamicArrayOfValues = response.data;
for (var i = 0; i < $scope.someStaticArrayOfValues.length; ++i) {
$scope.someDynamicArrayOfValues.some(function (value) {
if (value.substring(0, $scope.someStaticArrayOfValues[i].length) === $scope.someStaticArrayOfValues[i]) {
$scope.mySelectedValues[$scope.someStaticArrayOfValues[i]] = value;
return true;
}
});
}
},
function (response) {
console.log('ERROR!');
}
);
});
HTML:
<body ng-controller="MainCtrl">
<p>Hello {{name}}!</p>
<div ng-show="someDynamicArrayOfValues">
<ul>
<li ng-repeat="staticValue in someStaticArrayOfValues">
{{staticValue}} -
<select ng-model="mySelectedValues[staticValue]"
ng-options="myValue for myValue in someDynamicArrayOfValues">
<option value="">--</option>
</select>
<h2>{{mySelectedValues[staticValue]}}</h2>
</li>
</ul>
</div>
</body>
Demo: http://plnkr.co/edit/9Q1MH0esGE1SIJa0m2NV?p=preview
Here is a modified plunker that works as intended: http://plnkr.co/edit/Y8OSvmrG3u0XjnCU3ah5?p=preview.
The main change was using ng-if in place of ng-show. This forces angular to recompile/link the html whenever it is rendered:
<div ng-if="someDynamicArrayOfValues">
...
</div>
Also ng-change, from the original plunker, shouldn't be necessary, and there were a couple of typos fixed.
It works a whole lot better when you use ng-options on your select element instead of nesting option with ng-repeat.
https://docs.angularjs.org/api/ng/directive/select
Then you are capable of setting the ng-model with ng-init.
You can try to set the initial value of mySelectedValue in your Controller like so:
$scope.mySelectedValue = '';
I have created example for your problem in plnkr.
Visit: plnkr.co/edit/rKyjijGWSL1IKy51b8Tv?p=preview
You are going about it the reverse way. ng-model reflects the state of the <select> and is two-way bound.
You just need to set your mySelectedValue to what you want <select> to select first, and no other tricks are required.
So, in the controller, do something like the following:
$scope.mySelectedValue = someDynamicArrayOfValues[0];
And remove the ng-selected and the <option ng-repeat...> from <select>:
<select ng-model="mySelectedValue"
ng-options="value for value in someDynamicArrayOfValues">
<option value="">--</option>
</select>

Resources