Angularjs Dropdown OnChange Selected Text and Value - javascript

I am new to AngularJS and trying to get Selected Text and Value from Dropdown. I followed a lot of tutorials with still unable to get there. SelectedValue and SelectedText are always undefined. Below is my code:
Html:
<div ng-app="SelectApp">
<div ng-controller="selectController">
<select name="category-group" id="categoryGroup" class="form-control" ng-model="itemSelected" ng-change="onCategoryChange(itemSelected)">
<option value="0">Select a category...</option>
<option ng-repeat="category in categories" value="{{category.id}}"
ng-disabled="category.disabled" ng-class="{'mainCategory' : category.disabled}">
{{category.name}}
</option>
</select>
</div>
Js:
'use strict';
var app = angular.module('SelectApp', [ ]);
app.controller('selectController', ['$scope', '$window', function ($scope, $window) {
$scope.categories = [
{ id: 1, name: "- Vehicles -", disabled: true },
{ id: 2, name: "Cars" },
{ id: 3, name: "Commercial vehicles", disabled: false },
{ id: 4, name: "Motorcycles", disabled: false },
{ id: 5, name: "Car & Motorcycle Equipment", disabled: false },
{ id: 6, name: "Boats", disabled: false },
{ id: 7, name: "Other Vehicles", disabled: false },
{ id: 8, name: "- House and Children -", disabled: true },
{ id: 9, name: "Appliances", disabled: false },
{ id: 10, name: "Inside", disabled: false },
{ id: 11, name: "Games and Clothing", disabled: false },
{ id: 12, name: "Garden", disabled: false }
];
$scope.onCategoryChange = function () {
$window.alert("Selected Value: " + $scope.itemSelected.id + "\nSelected Text: " + $scope.itemSelected.name);
};
}]);
And one more thing, I have defined my first item as Select a category... then Why first item in Dropdown is always empty.
Below is my fiddle sample.
http://jsfiddle.net/Qgmz7/136/

That's because, your model itemSelected captures the current value of your select drop down which is nothing but the value attribute of your option element. You have
<option ng-repeat="category in categories" value="{{category.id}}">
in your code, so in the rendered version, you'll get
<option ng-repeat="category in categories" value="0">
but you're expecting itemSelected to be your category object and any attempt to query id or other property will return undefined.
You can use ng-options with group by with little bit of change to your data or you can use normal ng-repeat, get the selectedIndex and lookup the category object from your categories list using that index. Showcasing the first approach here.
HTML
<select name="category-group" id="categoryGroup"
ng-model="itemSelected" ng-change="onCategoryChange(itemSelected)"
ng-options="category.name group by category.group for category in categories">
</select>
Updated Data
$scope.categories = [
{ id: 0, name: "Select a category..."},
{ id: 1, name: "Cars", group : "- Vehicles -" },
{ id: 2, name: "Commercial vehicles", group : "- Vehicles -" },
{ id: 3, name: "Motorcycles", group : "- Vehicles -" }
];
$scope.itemSelected = $scope.categories[0];
Instead of disabled property, you can add a group property which can be used in group by.
Here' an updated Fiddle to illustrate the idea.

You should use ng-options to set object to your ng-model value on change of you select options.
Markup
<select name="category-group" id="categoryGroup" class="form-control"
ng-model="itemSelected" ng-change="onCategoryChange(itemSelected)"
ng-options="category.name for category in categories">
<option value="0">Select a category...</option>
</select>
Fiddle Here
Update
For persisting style you have to use ng-repeat there, in that case you will only have id binded to your ng-model and while retrieving whole object you need to filter your data.
$scope.onCategoryChange = function () {
var currentSelected = $filter('filter')($scope.categories, {id: $scope.itemSelected})[0]
$window.alert("Selected Value: " + currentSelected.id + "\nSelected Text: " + currentSelected.name);
};
Updated Fiddle

<div ng-app="SelectApp">
<div ng-controller="selectController">
<select ng-change='onCategoryChange()' ng-model="itemSelected" ng-options="category.name for category in categories">
<option value="">-- category --</option>
</select>
</div>
//http://jsbin.com/zajipe/edit?html,js,output

A little change in your onCategoryChange() should work:
$scope.onCategoryChange = function () {
$window.alert("Selected Value: " + $scope.categories[$scope.itemSelected - 1].id + "\nSelected Text: " + $scope.categories[$scope.itemSelected -1].name);
};
JSFiddle: http://jsfiddle.net/Qgmz7/144/

ngChange only returns the value of your selected option and that's why you don't get the whole data.
Here's a working solution without changing your markup logic.
Markup:
<select
name="category-group"
id="categoryGroup"
class="form-control"
ng-model="id"
ng-change="onCategoryChange(id)">
ngChange handler:
$scope.onCategoryChange = function (id) {
//get selected item data from categories
var selectedIndex = $scope.categories.map(function(obj) { return obj.id; }).indexOf( parseInt(id) );
var itemSelected = $scope.categories[selectedIndex];
$window.alert("Selected Value: " + itemSelected.id + "\nSelected Text: " + itemSelected.name);
};
Another solution (little bit dirty) would be to change only the value of your options into something like this:
<option .... value="{{category.id}}|{{category.name}}">
...and inside your actual ngChange handler, just split the value to get all the values as an array:
$scope.onCategoryChange = function (itemSelected) {
$scope.itemSelected = itemSelected.split('|'); //string value to array
$window.alert("Selected Value: " + $scope.itemSelected[0] + "\nSelected Text: " + $scope.itemSelected[1]);
};

Here very Simple and easy code What I did
<div ng-app="myApp" ng-controller="myCtrl">
Select Person:
<select ng-model="selectedData">
<option ng-repeat="person in persons" value={{person.age}}>
{{person.name}}
</option>
</select>
<div ng-bind="selectedData">AGE:</DIV>
<br>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl',myCtrlFn);
function myCtrlFn($scope) {
$scope.persons =[
{'name': 'Prabu','age': 20},
{'name': 'Ram','age': 24},
{'name': 'S','age': 14},
{'name': 'P','age': 15}
];
}
</script>

Related

How to bind selected elements in SELECT multiple

I have a select multiple like this
<select
id="countries"
ng-model="country"
ng-options="option.name for option in countryOptions track by option.id"
multiple>
</select>
to populate this select I am doing:
let countries = [];
countries.push({
id: country.id,
name: country.name,
selected: false
});
$scope.countryOptions = countries;
then acting on another element, I loop scope.countryOptions to check if any of its elements are in another array, and in that case I mark them as selected:
$scope.countryOptions.forEach((country, index) => {
$scope.countryOptions[index].selected = activeCountries.indexOf(country.id) !== -1;
});
What should I do to have the selected elements highlighted in the select multiple (in the UI)?
Your data source $scope.countryOptions and the user's selected countries $scope.country are different. Keep your data source pure and track user selections separately.
angular.module('selectExample', [])
.controller('ExampleController', ['$scope', function($scope) {
$scope.countryOptions = [{ id: 1, name: "Brazil" },
{ id: 2, name: "France" },
{ id: 3, name: "Djibouti" }
];
let activeCountries = [1, 3]
// init
$scope.country = $scope.countryOptions.filter(c => activeCountries.indexOf(c.id) > -1)
}]);
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.10/angular.min.js"></script>
<div ng-app="selectExample">
<div ng-controller="ExampleController">
<select id="countries" ng-model="country" ng-options="option.name for option in countryOptions track by option.id" multiple>
</select>
<hr> {{country}}
</div>
</div>

Show different text from option

I have a dropdown with all countries and their phone code. My drop down as a limited space, so the text must be short.
When the dropdown is open, I want to show the the country name and the phone code, but when a user select an option, I only want to show the phone code on the dropdown as the selected value.
<select ng-model="country" ng-options="c.phoneNumberCountryCode as (c.countryName + ' (+' + c.phoneNumberCountryCode + ')' ) for c in countriesList">
</select>
http://jsfiddle.net/0fadq61k/
I would combine ng-selected with ng-click in an attempt to achieve this. The problem with ng-click (inherent in Angular itself) is that while it does refresh your whole list, it does not refresh the already selected item. I would suggest that you change your design. One thing you could do is use for example the first 3 letters of the country name, or a similar combination. Place the following code in your fiddle to see an example:
HTML
<div ng-controller="Ctrl">
<select ng-model="country" ng-options="c.phoneNumberCountryCode as (c.countryName + ' (+' + c.phoneNumberCountryCode + ')' ) for c in countriesList" ng-selected="onCodeSelected(country)" ng-click="onClick()">
</select>
</div>
JS
var app = angular.module('app', []);
function Ctrl($scope) {
//this should be in a service
$scope.countriesList = [{
id: 0,
countryName: 'Portugal',
phoneNumberCountryCode: '351'
}, {
id: 1,
countryName: 'Spain',
phoneNumberCountryCode: '34'
}, {
id: 2,
countryName: 'UK',
phoneNumberCountryCode: '44'
}, {
id: 3,
countryName: 'Australia',
phoneNumberCountryCode: '61'
}];
$scope.onClick = function () {
//refresh data from service instead of hardcoded like below
$scope.countriesList[0].countryName = "Portugal";
$scope.countriesList[1].countryName = "Spain";
$scope.countriesList[2].countryName = "UK";
$scope.countriesList[3].countryName = "Australia";
}
$scope.onCodeSelected = function(countryCode) {
if (countryCode) {
angular.forEach($scope.countriesList, function(value, key) {
if (value.phoneNumberCountryCode === countryCode) {
var countryShort = $scope.countriesList[value.id].countryName.substring(0, 3);
$scope.countriesList[value.id].countryName = countryShort;
}
})
}
}
}
Can you try this,
<div ng-controller="Ctrl">
<select ng-options="item as item.id for item in items" ng-model="selected"
ng-change="dispThis(selected)"
></select> {{output}}
<div>
and in script
var app = angular.module('app', []);
function Ctrl($scope) {
$scope.items = [{
label: 'Portugal',
id: '351'
}, {
label: 'Spain',
id: '34'
}];
$scope.dispThis = function(c){
console.log(c);
$scope.output = "Country: "+c.label+" & Ph.code "+
c.id
};
}

How to set a value in a select from an object in angularjs

I'm new to Angular so please be gentle :)
I am recieving a "Brand" Object from the server and I want to set the select field with the good corresponding value.
Brands look like this :
Brands = [{name: "BRAND1", id=242},
{name: "BRAND2", id=562}]
And I got from the server:
brandFromTheServer = {name: "BRAND2", id=562};
This is my select :
<select id="brand" ng-model="product.brand" class="form-control" ng-options="brand as brand.name for brand in brands"></select>
And I want the select to be set with brandFromTheServer.
I tried in the controller:
$scope.product.brand = brandFromTheServer;
How can I set the value of the select with the brand that I'm recieving ?
Sorry, my English is terrible !
Please help :=)
I use something like this:
<select ng-options="option.name for option in advertiserList" ng-model="selectedOption.advertiserChoice" class="form-control"></select>
And in my controller I have:
$scope.advertiserList = response.advertisers;
var data = $scope.advertiserList.getIndexBy("id", $scope.currentAdvertiser.id)
$scope.selectedOption.advertiserChoice = $scope.advertiserList[data];
The method getIndexBy() is like this:
Array.prototype.getIndexBy = function (name, value) {
for (var i = 0; i < this.length; i++) {
if (this[i][name] === value) {
return i;
}
}
}
And my advertiserList json looks like this:
"advertisers": [
{
"id": 1,
"name": "Somebody Franck",
},
{
"id": 2,
"name": "Me Me me",
}
]
<select id="brand" ng-model="product.brand" class="form-control" ng- options="brand as brand.name for brand in brands">
<option value="o">Val 1</option>
<option value="1">Val 2</option>
<option value="2">Val 3</option>
</select>
$scope.product.brand = 0 or 1 or 2;
Your approach is correct when using ng-options, however the product.brand is not bound to the Brand object. Something like this works:
Controller:
$scope.brands = [
{
name: '1'
},
{
name: '2'
},{
name: '3'
}
];
$scope.product = {
brand: $scope.brands[1] // now it has a 'reference'
};

Angularjs: update select options

I have two select menus . One for country selection and other for state. I need to update states based country selected. I am able to log states but not able to list them in select menu.Please help.
Angular:
angular.module('demoApp', []).controller('DemoController', function($scope) {
$scope.countries = [
{ label: 'Please select', value: 0 },
{ label: 'India', value: 1 },
{ label: 'US', value: 2 }
];
$scope.data = [{'1':[{ label: 'Delhi', value: 0 },{ label: 'Mumbai', value: 1 },{ label: 'Chennai', value: 2 }]},
{'2':[{ label: 'Alabama', value: 3 },{ label: 'Alaska', value: 4 },{ label: 'Arizona', value: 5 }]}];
$scope.vm = {states: []};
$scope.updateStates = function(countryCode){
$scope.vm.states = $scope.data[countryCode-1];
console.log($scope.vm.states);
};
$scope.correctlySelected = $scope.countries[0];
});
HTML:
<body ng-app="demoApp">
<div ng-controller="DemoController">
<select ng-model="correctlySelected" ng-change="updateStates(correctlySelected.value)" ng-options="opt as opt.label for opt in countries">
</select>
<select ng-options="opt as opt.label for opt in vm.states">
</select>
</div>
</body>
JS Bin:
http://jsbin.com/pafosewedo/1/edit?html,js,console,output
You need to add ng-model to your states <select> - this is required when you are using ng-options
You also have an inconvenient model for the states data. Each element of the data array that corresponds to the country's states is an object with a changing key whose value is an array of states. You could make it work, but it's better to change it to something more reasonable:
$scope.data = {
1: [{ label: 'Delhi', value: 0 }, {...}, ],
2: [{...}, {...}, ] // same for US
}
Then it would work with how you specified your ng-options for states, and you wouldn't have to deal with indices:
$scope.updateStates = function(countryCode){
$scope.vm.states = $scope.data[countryCode]; // access by property
};
I think, that you should use some filter like that if you don't want to change your model:
.filter('stateFilter', function() {
return function(states, countryID) {
var filtered = [];
angular.forEach(states, function(state){
if(state.value === countryID)
filtered.push(state);
});
return filtered;
};
});
to filter out all values that have value equal to selected country.value in first select control.
To use that filter you need to modify your ng-repeat directive value in state select control:
ng-options="state as state.label for data | stateFilter:correctlySelected"
I came up with the following solution, view my JSBin
This solutions works by setting the countryCode in the scope when we are updatingStates.
$scope.updateStates = function(countryCode){
$scope.countryCode = countryCode;
$scope.vm.states = $scope.data[countryCode-1];
console.log($scope.vm.states[countryCode]);
};
This change is then reflected in the view.
<select>
<option ng-repeat='i in vm.states[countryCode]'> {{i.label}}
</option>
</select>

How to disable dropdown list item in AngularJS?

I am a beginner to AngularJS and I am making a web app that needs to disable exiting values in a dropdown list.
I know how to do it in jQuery. It is just like this: http://jsfiddle.net/qiushibaike/FcLLn/
But I don't really know how to do it in AngularJS, Should I try to disable the item or hide it? Can I set a value
HTML
<select ng-model="numbers.value" required>
<option ng-repeat="item in items"> {{item.name}} </option>
</select><br/>
JavaScript
$scope.numbers= {};
$scope.items = [
{ id: 1, name: '11111'},
{ id: 2, name: '22222'},
{ id: 3, name: '33333'}
];
If I have something like this, how can I disable or hide the option 2 and 3 by AngularJS like what I did by using jQuery?
This is also possible with ngOptions.
You just need to add "disable when" in your ng-options tag.
In your case, you can also do like this
HTML
<select ng-model="numbers.value"
ng-options="var.name as var.name disable when var.disabled for var in items" required>
<option value="">-- Select --</option></select>
Javascript
$scope.items = [
{ id: 1, name: '11111'},
{ id: 2, name: '22222', disabled: true },
{ id: 3, name: '33333', disabled: true }
]
Plunkr
If you want to disable any option dynamically from your code,
here is a Plunkr : Dynamic Example.
Use Angular's ngDisabled directive.
HTML
<select ng-model="numbers.value" required>
<option ng-repeat="item in items" ng-disabled="item.disabled"> {{item.name}} </option>
</select>
Javascript
$scope.items = [
{ id: 1, name: '11111'},
{ id: 2, name: '22222', disabled: true },
{ id: 3, name: '33333', disabled: true }
]

Categories

Resources