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/

6 Answers 6

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.

Sign up to request clarification or add additional context in comments.

5 Comments

This example will keep the group headers using optgroup in select element rendered by group by clause in ng-options. Hope this helps :)
that's good solution but why dropdown is empty for the first time.
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 here
Thanks a lot Ankantos. Very good solution and something new to learn. :)
Glad to be of help :)
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

3 Comments

It works but my css logic is gone. If you see my sample. - Vehicles - and - House and Children - are disabled and using different css.
@UsmanKhalid take a look at updated fiddle..which will work as you want
Thanks a lot. It is working fine but why dropdown is empty for the first time?
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

Comments

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/

5 Comments

are you crazy to that..how come $scope.categories[$scope.itemSelected] will select a value from categories?
$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.
could you please look at your fiddle it is showing wrong value as its considering index of an array
Updated the code. It should output the right values now.
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..
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]);

};

Comments

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>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.