Code


<!DOCTYPE html> <html> <head> <script src="angular.js"></script> <script src="script.js"></script> <style> label { width: 120px; display: inline-block; vertical-align: middle; } select { width: 150px; display: inline-block; vertical-align: middle; } textarea { width: 250px; height: 100px; } </style> </head> <body ng-app="mainModule"> <div ng-controller="mainController"> <h3>1. Options in the HTML template</h3> <label for="simpleColorSel">Simple select:</label> <select id="simpleColorSel" ng-model="simpleColorValue"> <option value="red">Red</option> <option value="green">Green</option> <option value="blue">Blue</option> </select><br /> <br /> <strong>Selected color:</strong> {{simpleColorValue}}<br /> <br /> <h3>2. Options from an array</h3> <!-- label for value in array --> <label for="colorsArraySel">Array select 1:</label> <select id="colorsArraySel" ng-model="colorsArrayValue" ng-options="color for color in colorsArray"> <option value="">[No color]</option> </select><br /> <br /> <strong>Selected color:</strong> {{colorsArrayValue}}<br /> <br /> <br /> <!-- label for value in array --> <label for="peopleArraySel1">Array select 2:</label> <select id="peopleArraySel1" ng-model="peopleArrayValue1" ng-options="person.firstName for person in peopleArray"> <option value="">[No person]</option> </select><br /> <br /> <strong>Selected person:</strong><br /> <textarea>{{peopleArrayValue1 | json}}</textarea><br /> <br /> <br /> <!-- label for value in array --> <label for="peopleArraySel2">Array select 3:</label> <select id="peopleArraySel2" ng-model="peopleArrayValue2" ng-options="getPersonFullName(person) for person in peopleArray"> <option value="">[No person]</option> </select><br /> <br /> <strong>Selected person:</strong><br /> <textarea>{{peopleArrayValue2 | json}}</textarea><br /> <br /> <br /> <!-- select as label for value in array --> <label for="peopleArraySel3">Array select 4:</label> <select id="peopleArraySel3" ng-model="peopleArrayValue3" ng-options="person.lastName as getPersonFullName(person) for person in peopleArray"> <option value="">[No person]</option> </select><br /> <br /> <strong>Selected person:</strong> {{peopleArrayValue3}}<br /> <br /> <br /> <!-- label group by group for value in array --> <label for="peopleArraySel4">Array select 5:</label> <select id="peopleArraySel4" ng-model="peopleArrayValue4" ng-options="getPersonFullName(person) group by person.sex for person in peopleArray"> <option value="">[No person]</option> </select><br /> <br /> <strong>Selected person:</strong><br /> <textarea>{{peopleArrayValue4 | json}}</textarea><br /> <br /> <br /> <!-- select as label group by group for value in array track by trackexpr --> <label for="peopleArraySel5">Array select 6:</label> <select id="peopleArraySel5" ng-model="peopleArrayValue5" ng-options="person as getPersonIdAndFullName(person) group by person.sex for person in peopleArray track by person.id"> <option value="">[No person]</option> </select><br /> Type the ID to select a person: <input type="text" ng-model="selPersonId" ng-change="selectPersonById(selPersonId)" /><br /> <br /> <strong>Selected person:</strong><br /> <textarea>{{peopleArrayValue5 | json}}</textarea><br /> <br /> <br /> <h3>3. Options from an object</h3> <!-- label for (key, value) in object --> <label for="colorsObjectSel">Object select 1:</label> <select id="colorsObjectSel" ng-model="colorsObjectValue" ng-options="code for (code, name) in colorsObject"> <option value="">[No color]</option> </select><br /> <br /> <strong>Selected color:</strong> {{colorsObjectValue}}<br /> <br /> <br /> <!-- select as label for (key, value) in object --> <label for="peopleObjectSel1">Object select 2:</label> <select id="peopleObjectSel1" ng-model="peopleObjectValue1" ng-options="id as person.firstName for (id, person) in peopleObject"> <option value="">[No person]</option> </select><br /> <br /> <strong>Selected person ID:</strong> {{peopleObjectValue1}}<br /> <br /> <br /> <!-- label group by group for (key, value) in object --> <label for="peopleObjectSel2">Object select 3:</label> <select id="peopleObjectSel2" ng-model="peopleObjectValue2" ng-options="person.lastName group by person.sex for (id, person) in peopleObject"> <option value="">[No person]</option> </select><br /> <br /> <strong>Selected person:</strong><br /> <textarea>{{peopleObjectValue2 | json}}</textarea><br /> <br /> <br /> <!-- select as label group by group for (key, value) in object --> <label for="peopleObjectSel3">Object select 4:</label> <select id="peopleObjectSel3" ng-model="peopleObjectValue3" ng-options="person as getPersonFullName(person) group by person.sex for (id, person) in peopleObject"> <option value="">[No person]</option> </select><br /> <br /> <strong>Selected person:</strong><br /> <textarea>{{peopleObjectValue3 | json}}</textarea><br /> <br /> <br /> <h3>4. Selecting multiple options</h3> <label for="multiColorsSel">Multiple select:</label> <select id="multiColorsSel" ng-model="multiColorsValue" ng-options="color for color in colorsArray" multiple> <option value="">[No color]</option> </select><br /> <br /> <strong>Selected colors:</strong> {{multiColorsValue}} </div> </body> </html>
angular.module("mainModule", []) .controller("mainController", function ($scope) { $scope.colorsArray = ["Red", "Green", "Blue"]; $scope.peopleArray = [ {id: "1", firstName: "John", lastName: "Doe", sex: "M"}, {id: "2", firstName: "Alice", lastName: "White", sex: "F"}, {id: "3", firstName: "Michael", lastName: "Green", sex: "M"} ]; $scope.colorsObject = { "R": "Red", "G": "Green", "B": "Blue" }; $scope.peopleObject = { "1": {firstName: "John", lastName: "Doe", sex: "M"}, "2": {firstName: "Alice", lastName: "White", sex: "F"}, "3": {firstName: "Michael", lastName: "Green", sex: "M"} }; $scope.getPersonFullName = function (person) { return person.firstName + " " + person.lastName; }; $scope.getPersonIdAndFullName = function (person) { return "(" + person.id + ") " + person.firstName + " " + person.lastName; }; $scope.selectPersonById = function (id) { $scope.peopleArrayValue5 = {id: id}; }; });

Example


Description


If we need an HTML select element to let the user choose an option in a drop-down list, we have three different choices with AngularJS:

  • write the available options directly in the HTML template
  • read the options from an array
  • read the options from the properties of an object

Point 1 of the example shows how we can write the options directly in the HTML template. This is the same syntax of a standard HTML select element, but with the ng-model attribute that lets us bind the selected value to a model variable. When the model variable is null, the drop-down list shows also a blank option that is the default selection before we set a value on the variable, but when another value is selected, the blank option is not shown anymore. In the following points of the example we'll also see how we can specify our own blank option to make it always available to the user. Basically, all we need to do is add an option HTML element with the value attribute set as a blank string "" and write inside the option tag the text that we want to display as label in the drop-down list. Every time that blank option will be selected, the model variable will be set to null.

Point 2 shows how we can use an array as data source of the select element options. We have two different arrays defined on the scope, colorsArray and peopleArray. The first one is simply a list of strings while the second one contains objects. The options available in the drop-down list are described through the ng-options directive and they can be specified in these ways (all of them are illustrated in the example):

  • label for value in array
    we see this in three different examples:

    • ng-options=color for color in colorsArray

      this means "use colorsArray as data source, for each item put its value in the color variable and use the color variable value as label in the options of the drop-down list" (here all the values in the array are strings)

    • ng-options=person.firstName for person in peopleArray

      this means "use peopleArray as data source, for each item put its value in the person variable and use the firstName property of the person variable as label in the options of the drop-down list" (here all the values in the array are objects)

    • ng-options=getPersonFullName(person) for person in peopleArray

      this means "use peopleArray as data source, for each item put its value in the person variable and use the result of the getPersonFullName function (with the person parameter) as label in the options of the drop-down list"

  • select as label for value in array

    ng-options=person.lastName as getPersonFullName(person) for person in peopleArray

    this means "use peopleArray as data source, for each item put its value in the person variable, use the result of the getPersonFullName function (with the person parameter) as label in the options of the drop-down list, but set the value of the lastName property of person in the model variable whenever an item is selected in the drop-down list"

  • label group by group for value in array

    ng-options=getPersonFullName(person) group by person.sex for person in peopleArray

    this means "use peopleArray as data source, for each item put its value in the person variable, use the result of the getPersonFullName function (with the person parameter) as label in the options of the drop-down list and display all those options grouped by the sex property of person"

  • select as label group by group for value in array track by trackexpr

    ng-options=person as getPersonIdAndFullName(person) group by person.sex for person in peopleArray track by person.id

    this means "use peopleArray as data source, for each item put its value in the person variable, use the result of the getPersonIdAndFullName function (with the person parameter) as label in the options of the drop-down list and display all those options grouped by the sex property of person, then use the id property of person to search for the item to select when an object is assigned to the model variable"; normally, a strict equality "===" is used to compare an object assigned to the model variable to the objects in the array and we need to take special care knowing this, so let's illustrate the different behaviors depending on our actions:

    • trackexpr has not been specified in ng-options and you want to select the second object in peopleArray so you assign to peopleArrayValue5 a new object
      {id: "2", firstName: "Alice", lastName: "White", sex: "F"}
      that you've just created; the value will not be selected because
      objectInArray!===yourNewObject
      (they're not the same object reference)

    • trackexpr has not been specified in ng-options and you want to select the second object in peopleArray so you assign to peopleArrayValue5 a variable myPersonObj that is a reference to an actual item of the array; the value will be selected because
      myPersonObj===peopleArray[1]

    • trackexpr has been specified in ng-options with the value person.id and you want to select the second object in peopleArray so you assign to peopleArrayValue5 a new object
      {id: "2"}
      that you've just created; the value will be selected because the id property of each item in peopleArray is compared to the id property of your new object to search for the item to select and it doesn't matter if the object in the array is not the same reference as yours, all that matters is that both the objects must have the id property and the values of the property must match

Point 3 shows how we can use an object as data source of the select element options. We have two different objects defined on the scope, colorsObject and peopleObject. In the first one, each property name is a color code while the property value is the actual color. In the second one, each property name is the ID of a person while the property value is an object representing the person. When we use an object as data source, all the items in the drop-down list are ordered alphabetically by property name. The options available in the drop-down list are described through the ng-options directive and they can be specified in these ways (all of them are illustrated in the example):

  • label for (key, value) in object

    ng-options=code for (code, name) in colorsObject

    this means "use colorsObject as data source, for each property put its name in the code variable and its value in the name variable, use the code variable as label in the options of the drop-down list"; whenever an item is selected in the drop-down list, the corresponding property value is assigned to the model variable

  • select as label for (key, value) in object

    ng-options=id as person.firstName for (id, person) in peopleObject

    this means "use peopleObject as data source, for each property put its name in the id variable and its value in the person variable, use the firstName property of the person variable as label in the options of the drop-down list and set the value of id in the model variable whenever an item is selected in the drop-down list"

  • label group by group for (key, value) in object

    ng-options=person.lastName group by person.sex for (id, person) in peopleObject

    this means "use peopleObject as data source, for each property put its name in the id variable and its value in the person variable, use the lastName property of the person variable as label in the options of the drop-down list and display all those options grouped by the sex property of person"

  • select as label group by group for (key, value) in object

    ng-options=person as getPersonFullName(person) group by person.sex for (id, person) in peopleObject

    this means "use peopleObject as data source, for each property put its name in the id variable and its value in the person variable, use the result of the getPersonFullName function (with the person parameter) as label in the options of the drop-down list and display all those options grouped by the sex property of person, set the value of person in the model variable whenever an item is selected in the drop-down list"

In point 4 of the example we see how we can allow the user to select multiple options. We just need to add the multiple attribute to the select element and the selection will be assigned as array to the model variable whenever it changes.