angular ng-model is not working as expected - angularjs

Template:
<select id="siteOptions" ng-model="siteVal" ng-change="siteChange()">
<option ng-repeat = "site in sites" ng-selected="{{site == selectedSite}}" value="site">{{site}}</option>
</select>
Controller:
$scope.siteChange = function(){
console.log(" $scope.siteVal--> "+ $scope.siteVal);
}
I could able to populate values in dropdown properly, but when I try to select value in dropdown I could see "$scope.siteVal--> undefined".
Even when I select the dropdown value multiple time ng-change is triggering only once.

Remove .value attribute from your html markup and your code would work fine!
<select id="siteOptions" ng-model="siteVal" ng-change="siteChange()">
<option ng-repeat = "site in sites" ng-selected="{{site == selectedSite}}">{{site}}</option>
</select>
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 option
Here is the plunker which demonstrates the same

Related

How to make dropdown as selected in edit mode in angularjs

This is my page when I click on Edit the dropdown is not selected with value in the dropdown list ... Image
In edit mode i got like this ... Image
Dropdown shown with values... Image
I need like this ... Image
Here is my angular code:
<select class="form-control form-control-sm form-control-Cutom-height" id="dropdown" style="height: 38px;" ng-model="suppliment.PurchaseTypeId">
<option ng-repeat="Supple in PTSupplement" ng-selected="{{ Supple.PurchaseTypeId == suppliment.PurchaseTypeId }}" value="{{Supple.PurchaseTypeId}}" >
{{Supple.PurchaseType}}
</option>
</select>
Please help me :)
It appears as if when you display the dropdown, the your value is not be populated as the selected value properly. When using <select> in AngularJS, you can specify the ng-options attribute and use that to generate all of the <option> fields for you without doing the ng-repeat that you're doing.
From the AngularJS docs regarding the use of ngSelected:
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.
Instead use the following:
<select
class="form-control form-control-sm form-control-Cutom-height"
id="dropdown"
style="height: 38px;"
ng-model="suppliment.PurchaseTypeId"
ng-options="Supple.PurchaseTypeId as Supple.PurchaseType for Supple in PTSupplement">
</select>

ngSelected does not update ngModel [AngularJS]

Below I have the following select list. The ngSelected does correctly select the value in the expression, but the model for the select does not update accordingly. I can select the "High" Value, and when the ngSelected triggers, the empty value is displayed but the model stays as "High".
Anybody know how to programmatically set ngModel after ngSelected is triggered? The expression in ngSelected comes from a directive on a div, so I cannot attach an ngChange on it.
<select class="form-control" name="alertLevel-{{$index}}" ng-model="template.service.readings[$index].repeatBreachAlert.repetitiveAlertLevel" title="Please select an alert level">
<option ng-selected="template.service.firstLevelMessage.below.messages | messagesLength.length === 0" value=""></option>
<option value="Valid">Valid</option>
<option value="High">High Alert</option>
<option value="Low">Low Alert</option>
</select>
This is taken from angular official site.
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.
That being said. You should initialize your model in your controller and remove the ng-selected directive.
Something like this would work:
function initializeModel() {
for (let i; i < whatEverMyIterationLooksFor; i++) { // I suppose you are using ng-repeat in template so here you should iterate through the relevant scope.
const shouldBeEmpty = template.service.firstLevelMessage.below.messages || messagesLength.length === 0; // You also had a typo here with the OR operator.
if (shouldBeEmpty) {
template.service.readings[i].repeatBreachAlert.repetitiveAlertLevel = null;
};
}
}
Used this to set the model in the view which solves this answer:
<span class="ng-hide">
{{((template.service.firstLevelMessage.above.messages | messagesLength).length === 0 && template.service.readings[$index].repeatBreachAlert.repetitiveAlertLevel !== 'Valid' ? template.service.readings[$index].repeatBreachAlert.repetitiveAlertLevel = '' : '' }}
</span>

Setting value in select dropdown which is populating by ng-repeat

I have an array as below:
hunting_lands = {"1":{"name":"forest and rivers"},"2":{"name":"safari"},"3":{"name":"sea"},"4":{"name":"Mountains"}}
I have a select dropdown where I use above json:
<select id="favourite_hunting_land">
<option value ="[[key]]" ng-repeat="(key, value) in hunting_lands">[[value.name]]</option>
</select>
Now I want to show a value selected for example sea:
For this what I tried:
I set hunting land dropdown menu ng-model = fav_hunting_land
$scope.$watch('fav_hunting_land', function() {
$scope.fav_hunting_land = 3;
});
But Then I had other onchange functions which is not working and neither does select dropdown works i.e I am unable to change values.
It worked and show 3 value selected.
All want is to show selected value in select dropdown which populates using ng-repeat.
Update
I am using [[]] for expressions using interpolate.
Use this instead in the HTML
<select id="favourite_hunting_land" ng-model="selectedItem">
<option value ="{{item.name}}" ng-repeat="item in hunting_lands">{{item.name}}</option>
</select> <br>
Value selected is {{selectedItem}}
Use expression
<select id="favourite_hunting_land">
<option value ="key" ng-repeat="(key, value) in hunting_lands">{{value.name}}</option>
</select>
EDIT:
You can set the inital value with ng-init
<select ng-init="selected='3'" ng-model="selected " ng-options="c.key as c.value for c in hunting_lands"></select>
DEMO

Set value of multiple dropdowns

I am trying to set the value of many select elements when a user presses a button.
I have tried the jQuery way:
vm.passAllInspections = function ($event) {
$(".tbl-inspections option[value=pass]").attr("selected", "selected");
console.log($event);
}
This works but does not update ng-model or even make it fire. I looked at this post which gives details on the input element. I could not get the trigger event to happen?
$('button').click(function(){
var input = $('input');
input.val('xxx');
input.trigger('input');
});
So then I tried to use the $compile directive $compile(vm)($scope); that doesn't work as I wasn't sure if it had to be the exact ng-model property?
Then I was looking at useing ng-click="vm.eicr.inspections='pass'" but wasn't sure how to apply it to every ng-model property.
How can I press a button and add pass to a list of dropdowns and fire the ng-model so the properties are all set.
You have your listbox:
<select data-ng-model="myValue">
<option value="1">value 1 </option>
<option value="2">value 2 </option>
<option value="3">value 3 </option>
</select>
You have a button:
<button data-ng-click="setListboxToValue('2')" value="Click me!"/>
When you click the button, you trigger this function:
$scope.setListboxToValue = function(value) {
$scope.myValue = value;
}
This will set your listbox to the value you want.
Full example code: jsFiddle

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