Angularjs Dropdown OnChange Selected Text and Value
Asked Answered
S

6

7

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/

Supersensible answered 7/8, 2015 at 19:13 Comment(0)
K
11

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.

Konstantine answered 7/8, 2015 at 19:28 Comment(5)
This example will keep the group headers using optgroup in select element rendered by group by clause in ng-options. Hope this helps :)Konstantine
that's good solution but why dropdown is empty for the first time.Supersensible
That's because we've not set any default value for itemSelected in our controller. Add your default value to your categories list and set that value as shown hereKonstantine
Thanks a lot Ankantos. Very good solution and something new to learn. :)Supersensible
Glad to be of help :)Konstantine
A
8

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

Ashcraft answered 7/8, 2015 at 19:27 Comment(3)
It works but my css logic is gone. If you see my sample. - Vehicles - and - House and Children - are disabled and using different css.Supersensible
@UsmanKhalid take a look at updated fiddle..which will work as you wantAshcraft
Thanks a lot. It is working fine but why dropdown is empty for the first time?Supersensible
W
3
<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

Wallboard answered 7/8, 2015 at 19:53 Comment(0)
S
3

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/

Sanctified answered 7/8, 2015 at 20:1 Comment(5)
are you crazy to that..how come $scope.categories[$scope.itemSelected] will select a value from categories?Ashcraft
$scope.itemSelected Will return the value (as a Number) of the selected item in the option list. By passing it to the object You are able to select the n-property of the object and you will have access to the data.Sanctified
could you please look at your fiddle it is showing wrong value as its considering index of an arrayAshcraft
Updated the code. It should output the right values now.Sanctified
No dude that could harm..if suppose you have skipped one/two element id and then took third one..then $scope.itemSelected - 1 will won't work..Ashcraft
A
1

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]);

};
Anatomical answered 7/8, 2015 at 19:44 Comment(0)
S
0

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>
Sacroiliac answered 29/9, 2017 at 11:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.