Angular expression for ngoptions on concatenated array - angularjs

I have an array from the backend that contains an array of objects that are options for a select box, let's say for countryselection:
$scope.countries = [
{ name: 'foo', code: 'ba' },
{ name: 'bar', code: 'br' },
{ name: 'biz', code: 'bb' }
];
This array is raw and reusable, and may update at any time through different functions that may change this array.
However, I want the selectbox to be prepended with a different option that is initially selected and implementation specific (so will not add this to the countries array to not pollute it for other consumers of the values):
$scope.defaultCountry = [
{ name: 'Select a country', code: '' }
];
Then I want this to work:
<select name="countryCode" model="model.country"
ng-options="option.code as option.name for option in defaultCountry + countries">
</select>
where the defaultCountry + countries would be a concat of the 2 arrays. However, this concat does not work.
I know I can call a function to return the concatenated value, but if not required I would rather not:
$scope.getCountries = function () {
return $scope.defaultCountry.concat($scope.countries);
};
<select name="countryCode" model="model.country"
ng-options="option.code as option.name for option in getCountries()">
</select>
Is there an out of the box solution to be able to use both 2 arrays at once for ng-options?

Use concat in ng-options
<select name="countryCode" ng-model="model.country"
ng-options="option.code as option.name for option in defaultCountry.concat(countries)">
</select>

This should do :
<select name="countryCode" model="model.country"
ng-options="option.code as option.name for option in countries">
<option value="">-- Select a country --</option>
</select>

You can concat before ng-option :
<select name="countryCode" model="model.country" ng-init="allCountries=defaultCountry.concat(countries)"
ng-options="option.code as option.name for option in allCountries">
<option value="">-- Select a country --</option>
</select>

Related

How to display selected name in <p> from a Select dropdown and send selected id to controller in AngularJS?

I have the following select input in my html which is populated using ng-options. I want to show the selected NAME down below in whereas I want to send the selected ID back to the controller. I get the required id from ng-model="user.category". How can I show the selected name? I also show the names in options.
<select ng-model="user.category" ng-options="category.id as category.name for category in categories" class="form-control" class="select" required>
<option value="{{category.name}}">Select a Category</option>
</select>
<p>Available On : {{user.retailerBranchId}}</p>
<select ng-model="user.category" ng-options="category for category in categories" class="form-control" class="select" required>
<option value="{{category.name}}">Select a Category</option>
</select>
<p>Available On : {{user.category.id}}</p>
If you make retailerBranchId a method you can do it with something like lodash' _.find() (or even native find). You have user.category updating according to your selection, which you say has the id in it, which you can use:
function retailerBranchId() {
return _.get(_.find(this.categories, { id: user.category }), 'name', '');
}
This also fails gracefully; if it can't find any name, or any item that matches the id, it'll return an empty string.
Edit: You would call it in a similar fashion like so:
<p>Available on: {{ user.retailerBranchId() }}</p>
Although really, it's better to use it like this:
<p data-ng-bind="'Available on: ' + user.retailerBranchId()"></p>
Can you try like a below method,
Controller to get selected Category Name:
$scope.getSelectedCategoryDetail=function(selectedCat){
angular.forEach($scope.categories, function(cat){
if(selectedCat===cat.id){
$scope.user.name=cat.name;
}
});
};
Template to have ng-change event:
<select ng-model="user.category" ng-options="category.id as category.name for category in categories" class="form-control" class="select" required>
<option value="{{category.name}}" ng-change="getSelectedCategoryDetail(user.category)">Select a Category</option>
</select>
<p>Category Id : {{user.category}}</p>
<p>Category Name : {{user.name}}</p>

ng-model is number, select box option values are strings

I have the following code
<select ng-disabled="currentQuestion.id" ng-change="loadTopics()" class="detail-subject-select browser-default" ng-model="currentQuestion.SubjectId">
<option disabled="disabled" value="any">Choose a Subject</option>
<option value="1">K8-English</option>
<option value="2">K8-Math</option>
</select>
The issue is that value 1 and 2 are strings. I need them to be numbers. Everything works fine when I select one on my page, but I need the select box to initialize with the value of (currentQuestion.SubjectId which is a number) when the page loads.
How can I get around this?
Standard HTML attributes (like "value") always mean strings. Unfortunately, You can only achieve this with ng-options:
Support for select models with non-string values is available via
ngOptions.
https://docs.angularjs.org/api/ng/directive/ngValue
It may seem a bit dirty, but with more options You actually save some typing:
<select
ng-disabled="currentQuestion.id"
ng-change="loadTopics()"
class="detail-subject-select browser-default"
ng-model="currentQuestion.SubjectId"
ng-options="value as key for (key, value) in {
'K8-English': 1,
'K8-Math': 2
}"
>
<option
disabled="disabled"
value=""
>Choose a Subject</option>
</select>
One way is to define your options as an array of objects in your controller like this:
$scope.options = [{
value: 1,
name: 'K8-English'
}, {
value: 2,
name: 'K8-Math'
}];
And implement this in your HTML using ng-options like this:
<select ng-disabled="currentQuestion.id"
ng-change="loadTopics()"
class="detail-subject-select browser-default"
ng-model="currentQuestion.SubjectId"
ng-options="option.value as option.name for option in options">
<option disabled="disabled" value="any">Choose a Subject</option>
</select>

How to use angular to populate the select drop down list from an object withing an object.

I have the following JSON Object
$scope.items = [
{ id: 1, name: 'Red',sizes:[{size:'s'},{size:'b'}] },
{ id: 2, name: 'Green',sizes:[{size:'s'},{size:'b'}] },
{ id: 3, name: 'Yellow',sizes:[{size:'s'},{size:'b'}] }];
I'm trying to create a select option like the one below
<select id="s1" >
<option value="?" selected="selected"></option>
<option value="Red S">Red S</option>
<option value="Red b">Red b</option>
<option value="Green S">Green S</option>
<option value="Green b">Green b</option>
<option value="Yellow S">Green S</option>
<option value="Yellow b">Green b</option>
</select>
Is it possible to achieve this using ng-options, if not what are my other options using angular.
Anything is possible with Angular ;) But for something like this (the data in that shape), using option groups would be your only option. To display them as a straight list of options as you showed, you would have to flatten your object first, and then do a ng-options on the new object/array.
<select id="s1" ng-model="selected">
<option value=""></option>
<optgroup ng-repeat="item in items" label="{{item.name}}">
<option ng-repeat="size in item.sizes">{{item.name + ' ' + size.size}}</option>
</optgroup>
</select>
Check out this Plunkr.

how to render the options inside angular select box

How do i render the values inside dropdown(selectbox options).
I need to show 'header' and 'footer' names inside selectbox.
$scope.sections = [
{
"header":{
"background-color":"#fff",
"color":"#fff"
},
"footer":{
"background-color":"#fff",
"color":"#fff"
}
}
];
I tried in the following way but not working,
<select name="section" class="form-control" ng-model ="section">
<option ng:repeat="options[0] in sections">
{{options[0]}}
</option>
</select>
You need to iterate over keys instead of values.
<option ng-repeat="(option, val) in sections[0]">
{{option}}
</option>
Or with ng-options
ng-options="option for (option, val) in sections[0]"
see the plunker
http://plnkr.co/edit/FQEooL5wNh8Xl8GprT99?p=preview

Using both <select>'s value AND text for ng-model

I currently have this:
<div>
<label for="market-type">Market Type</label>
<select id="market-type" type="text" ng-model="tradingFee.market_type">
<option value="stock">Stock Market</option>
<option value="otc">OTC Market</option>
</select>
</div>
which assigns the selected option's value to tradingFee.market_type. What I wish is to be able to do this plus assign the selected option's text to tradingFee.market_type_human_friendly_text, for example. Only being able to do one of the assignments is not enough. Is this possible somehow?
You could do this, but not with this syntax. use ng-options so that the ng-model holds both value and display name.
In your controller set array of objects:
$scope.marketType = [{id:"stock", displayName:"Stock Market"}, {id:"otc", displayName:"OTC Market"}];
and
<select id="market-type" type="text"
ng-model="tradingFee.market_type"
ng-options="mt.displayName for mt in marketType track by mt.id">
<option value="">--Select--</option>
</select>
Now the ng-model will have both id as well as value. i.e example:
tradingFee.market_type will be {id:"otc", displayName:"Stock Market"} if you select that specific item from the dropdown. With this you do not have to worry about maintaining 2 separate properties for displayName and id.
angular.module('app', [])
.run(function($rootScope) {
$rootScope.marketType = [{
id: "stock",
displayName: "Stock Market"
}, {
id: "otc",
displayName: "OTC Market"
}];
$rootScope.tradingFee = {
market_type: {
id: 'stock'
}
};
});
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
<div ng-app="app">
<select id="market-type" type="text" ng-model="tradingFee.market_type" ng-options="mt.displayName for mt in marketType track by mt.id">
<option value="">--Select--</option>
</select>
{{ tradingFee.market_type }}
</div>
You could just use ng-change on your select to fire a custom event handler that sets the secondary value.
<select id="market-type" type="text" ng-model="tradingFee.market_type"
ng-change="updateSecondary()">
<option value="stock">Stock Market</option>
<option value="otc">OTC Market</option>
</select>

Resources