Select a dynamic item in a list with AngularJS - angularjs

I have a <select> element with an ng-model=sendTime element to select a time from the list. This list contains only a limited number of standard times, but as a last item it always contains an option for the sendTime in the model:
<select ng-model="sendTime" style="">
<option value="now">now</option>
<option value="08:00">08:00</option>
<option value="17:00">17:00</option>
<option value="{{sendTime}}">{{sendTime}}</option>
</select>
The last item is just to ensure that a custom time (which is not editable in this view) will appear in the selection box. The problem is that Angular doesn't do this correctly. It adds the final element to the list, but it doesn't select it. It only ever selects one of the default times.
How can I fix this?

Change the last option to <option ng-value="sendTime">{{sendTime}}</option>. The behavior will be abit weird though. When you select an other option the value of the last option will change to the selected option. If you don't want this behavior you could do something like this:
<select ng-model="sendTime" style="" ng-init="default=sendTime">
<option value="now">now</option>
<option value="08:00">08:00</option>
<option value="17:00">17:00</option>
<option ng-value="default">{{default}}</option>
</select>
See: http://plnkr.co/edit/YhEgbDSxkE6nYy0FaRVF?p=preview

Related

select box with ngModel is not populating the selected value

I am having a JSON reponse data which is an array representing country code and description
{"codeDescList":[{"desc":"Aruba"}],"codeValueCode":"ABW"},
{"codeDescList":[{"desc":"Afghanistan"}],"codeValueCode":"AFG"},
{"codeDescList":[{"desc":"Angola"}],"codeValueCode":"AGO"},
{"codeDescList":[{"desc":"Anguilla"}],"codeValueCode":"AIA"},
{"codeDescList":[{"desc":"Åland Islands"}],"codeValueCode":"ALA"},
{"codeDescList":[{"desc":"Albania"}],"codeValueCode":"ALB"}
I stored the above array in angularJS scope object as follows
$scope.codeValueData = response.data;
I created select box for countries
<div class="form-group">
<select ng-model="profileBizObj.preferredAddress.countryCode" ng-options="codeValue.codeDescList[0].desc for codeValue in codeValueData track by codeValue.codeValueCode">
</select>
</div>
The select box is created correctly like below
<option value="ABW">Aruba</option>
<option value="AFG">Afghanistan</option>
<option value="AGO">Angola</option>
<option value="AIA">Anguilla</option>
<option value="ALA">Åland Islands</option>
<option value="ALB">Albania</option>
The problem with my code is if profileBizObj.preferredAddress.countryCode is referring to the value "AGO" the select box is not showing the the country "Angola". The select box is showing blank.
I am new to angularJS. Please help to resolve this issue. Thank you
What you try to do can be achieved more easily with an ng-repeat. Try this:
<select ng-model="profileBizObj.preferredAddress.countryCode">
<option ng-repeat="item in codeValueData" value="{{item.codeValueCode}}">
{{item.codeDescList[0].desc}}
</option>
</select>
Here is a working fiddle: http://jsfiddle.net/5s0b0jnz/
Writing below select statement worked for me
<select ng-model="profileBizObj.preferredAddress.countryCode" ng-options="codeValue.codeValueCode as codeValue.codeDescList[0].desc for codeValue in codeValueData">
The select box is populated as
<option value="0">Aruba</option>
<option value="1">Afghanistan</option>
<option value="2">Angola</option>
<option value="3">Anguilla</option>
<option value="4">Åland Islands</option>
<option value="5">Albania</option>
and Selectiong Angola is storing as "AGO" in the model "profileBizObj.preferredAddress.countryCode" which exactly I needed.
Thank You all for the help
Your ng-options is ng-options="codeValue.codeDescList[0].desc for codeValue in codeValueData track by codeValue.codeValueCode">, it means, use the codeValue will be bound to model , and the ...desc as the displayed value. So when your model value is AGO, it can not be referred to some object in codeValueData.
You should set your option value like AGO with this:
ng-options="codeValue.codeValueCode as codeValue.codeDescList[0].desc for codeValue in codeValueData track by codeValue.codeValueCode">
Then the codeValueCode will be applied to your model. And in reverse, for some model value like AGO, the related option will be selected.

Ng select model selection gets overriden by html5 selected

Ok so I have a select
<select id="minutes-to-dropdown"
required=""
ng-model="AddEventPopupStore.ToMinutes"
name="minutes-to-dropdown"
ng-change="AddEventPopupStore.UpdateTimeFromPopup()"
ng-options="num as num for num in [0,15,30,45]"
class="popup-subdropdown">
<option disabled="" value="">min</option>
</select>
and it's used for a popup which is toggled via ng-show (not sure how this affects destructing/recreating scope)
What happens is that the selected property does not update properly when the selection changes from both clicks and model. After a few updates I get
<select id="minutes-to-dropdown"
required=""
ng-model="AddEventPopupStore.ToMinutes"
name="minutes-to-dropdown"
ng-change="AddEventPopupStore.UpdateTimeFromPopup()"
ng-options="num as num for num in [0,15,30,45]"
class="popup-subdropdown">
<option disabled="" value="" selected="selected">min</option>
<option label="0" value="number:0" selected="selected">0</option>
<option label="15" value="number:15" selected="selected">15</option>
<option label="30" value="number:30" selected="selected">30</option>
<option label="45" value="number:45" selected="selected">45</option>
</select>
and while the model changes when I pick another value, if I close the popup and reopen it the the model and the selection don't match because the last selected value is shown instead of the actual selected from model.
How do I force updating of the selection to the actual selection from model? I suppose I might have to force removing of all the selecteds and reapply it to the new one.

Angular selection display default value for a null ng-model value

The select list below is display empty row instead of the default value "--Weight--" when product.weightUnitMeasureCode is null.
<select ng-model="product.weightUnitMeasureCode">
<option value="">-- Weight --</option>
<option ng-repeat="unitMeasure in unitMeasures |filter:unitMeasure.isSize='false'" value="{{unitMeasure.unitMeasureCode}}">{{unitMeasure.name}}</option>
</select>
Is there a way to make the list display the default option when product.weightUnitMeasureCode is null? I've tried changing the value of the default option to the following but it didn't work.
value="null"
value=null
Looks like you are in wrong direction as far as angular version of select has been concerned.
Try:-
<select ng-model="product.weightUnitMeasureCode"
ng-options="unitMeasure.code as unitMeasure.name for unitMeasure in unitMeasures | filter:unitMeasure.isSize==false">
<option value="">-- Weight --</option>
</select>
I am not sure if you have a field called code in your data model, but you can adjust based on your model.
if you want to filter out ones with unitMeasure.isSize on a static list then you should just filter them at the controller itself and bind only the required list.

AngularJS select creates option with value "? object:null ?" and doesn't use empty default option when bound to null

Here's what the code looks like
<select ng-model="nullableInt">
<option></option>
<option value="0">First option</option>
<option value="1">First option</option>
<option value="2">First option</option>
</select>
When nullableInt is null the generated html is
<select ng-model="nullableInt">
<option></option>
<option value="? object:null ?"></option>
<option value="0">First option</option>
<option value="1">First option</option>
<option value="2">First option</option>
</select>
Reproduced in the plunkr here: http://plnkr.co/edit/05pBEMJppmkrn3nFgYdk?p=info
It's worth mentioning that I'm trying to avoid using ng-options, it seems like a bit of overkill to create an endpoint for AngularJS to consume some data that really will not change very often, if ever.
Update 3/29/2017:
As Jorge Rodrigues dos Santos stated, this should be handled in a different way for newer versions of angular. Below is taken from the current documentation for angular 1.6.3
Optionally, a single hard-coded element, with the value set
to an empty string, can be nested into the element. This
element will then represent the null or "not selected" option. See
example below for demonstration.
https://docs.angularjs.org/api/ng/directive/select
Angular is creating a new option to represent the null value. It didn't find one of the options you provided in the HTML.
To bind to null, set the value="null" on the first option
<option value="null"></option>
http://plnkr.co/edit/kzPVu4hiMcP6wA6crGYt?p=preview
The accepted answer didn't work for me because my property could be blank, null, or undefined. If you are using version 1.3+ then you can use a getterSetter to coerce the value to blank.
I was dealing with string values. You'll have to handle 0 or other valid falsy values in the function as well.
$scope.nullableIntCoerced = function(n) {
return arguments.length ? ($scope.nullableInt = n) : ($scope.nullableInt || "");
}
<select ng-model="nullableIntCoerced" ng-model-options="{getterSetter:true}">
<option value=""></option>
...
https://code.angularjs.org/1.3.20/docs/api/ng/directive/ngModel
For more recent versions of Angularjs use <option value=""> - </option> for the null value
Below solution solved the problem for me.
The problem here is when ng-model is used, it adds a default option with value "?" and without using ng-model, one can not use ng-change to get the current selection. I have actually created an onChangeSelection() within which we can set the defaultSelected property of the like below
$scope.onChangeSelection = function(id) {
document.getElementById(id)[0].defaultSelected = true;
$scope.selected = $('#'+id).val();
}
<select id="mySelect" ng-model="nullableInt" ng-options="option.value as option.text for option in arrayContents track by option.value" ng-change="{{onChangeSelection(id)}}" required>
<option value="" ng-if="false"></option>
</select>
This would exclude the default option from the options list and also make the first value as defaultSelected.

angular Protractor e2e tests and select value?

I'm having problems to get currently selected value of the select element. In some cases I can use:
element(by.css('#some-select')).$('[selected]').getText();
And it works just fine. But as I figured out it works only because selected attribute is present on option element. If I select option with javascript by setting select's value this way it's not possible to get element by selected attribute.
What is the proper way to get selected option or it's text because I can't find answer anywhere.
Thank you.
Ok, so right now I feel stupid and a little enraged at the same time.
It turns out that there is a simple way to get the option that is selected by simply calling:
element(by.selectedOption('model-name'));
Documentation here
I feel like this is a wrong way to do because instead of reusing element locator cache that I have defined (select element) I need to use new locator "selectedOption". It feels bad because naturally I would like to simply call something like element(by.css('#some-select')).getSelected();
But maybe there is a way that I could not just find?
So I just ran into this, and I couldn't find any answer that I really liked..
My Answer
First, I recommend changing the ng-options by adding track by statement.
for example:
<select ng-options="l.id as ('filters.languages.' + l.id | translate) for l in limitedLanguages track by l.id" ng-model="filterLanguage">
</select>
This will add the id on the option element so instead of getting
<select ng-options="l.id as ('filters.languages.' + l.id | translate) for l in languages" ng-model="filterLanguage" class="ng-pristine ng-valid ng-touched">
<option value="0">All</option>
<option value="1" selected="selected">English</option>
<option value="2">Hebrew</option>
<option value="3">Russian</option>
<option value="4">Arabic</option>
<option value="5">Other</option>
</select>
you get
<select ng-options="l.id as ('filters.languages.' + l.id | translate) for l in languages track by l.id" ng-model="filterLanguage" class="ng-valid ng-dirty ng-valid-parse ng-touched">
<option value="all" selected="selected">All</option>
<option value="english">English</option>
<option value="hebrew">Hebrew</option>
<option value="russian">Russian</option>
<option value="arabic">Arabic</option>
<option value="other">Other</option>
</select>
note that without the track by the value is simply the index (0,1,..) and with the track by the value is more readable/meaningful (all,english,...)
then you can use getAttribute on value to get the value as mentioned in other answers.

Resources