Improve this Doc View Source

## Overview

The controller for the select directive. The controller exposes a few utility methods that can be used to augment the behavior of a regular or an ngOptions select element.

## Methods

- ###

  `$hasEmptyOption();`

  Returns `true` if the select element currently has an empty option element, i.e. an option that signifies that the select is empty / the selection is null.

- ###

  `$isUnknownOptionSelected();`

  Returns `true` if the select element's unknown option is selected. The unknown option is added and automatically selected whenever the select model doesn't match any option.

- ###

  `$isEmptyOptionSelected();`

  Returns `true` if the select element has an empty option and this empty option is currently selected. Returns `false` if the select element has no empty option or it is not selected.

## Examples

### Set a custom error when the unknown option is selected

This example sets a custom error "unknownValue" on the ngModelController when the select element's unknown option is selected, i.e. when the model is set to a value that is not matched by any option.

    <div ng-controller="ExampleController">
      <form name="myForm">
        <label for="testSelect"> Single select: </label><br>
        <select name="testSelect" ng-model="selected" unknown-value-error>
          <option value="option-1">Option 1</option>
          <option value="option-2">Option 2</option>
        </select><br>
        <span class="error" ng-if="myForm.testSelect.$error.unknownValue">
          Error: The current model doesn't match any option</span><br>

        <button ng-click="forceUnknownOption()">Force unknown option</button><br>
      </form>
    </div>

    angular.module('staticSelect', [])
     .controller('ExampleController', ['$scope', function($scope) {
       $scope.selected = null;

       $scope.forceUnknownOption = function() {
         $scope.selected = 'nonsense';
       };
    }])
    .directive('unknownValueError', function() {
      return {
        require: ['ngModel', 'select'],
        link: function(scope, element, attrs, ctrls) {
          var ngModelCtrl = ctrls[0];
          var selectCtrl = ctrls[1];

          ngModelCtrl.$validators.unknownValue = function(modelValue, viewValue) {
            if (selectCtrl.$isUnknownOptionSelected()) {
              return false;
            }

            return true;
          };
        }

      };
    });

### Set the "required" error when the unknown option is selected.

By default, the "required" error on the ngModelController is only set on a required select when the empty option is selected. This example adds a custom directive that also sets the error when the unknown option is selected.

    <div ng-controller="ExampleController">
      <form name="myForm">
        <label for="testSelect"> Select: </label><br>
        <select name="testSelect" ng-model="selected" required unknown-value-required>
          <option value="option-1">Option 1</option>
          <option value="option-2">Option 2</option>
        </select><br>
        <span class="error" ng-if="myForm.testSelect.$error.required">Error: Please select a value</span><br>

        <button ng-click="forceUnknownOption()">Force unknown option</button><br>
      </form>
    </div>

    angular.module('staticSelect', [])
     .controller('ExampleController', ['$scope', function($scope) {
       $scope.selected = null;

       $scope.forceUnknownOption = function() {
         $scope.selected = 'nonsense';
       };
    }])
    .directive('unknownValueRequired', function() {
      return {
        priority: 1, // This directive must run after the required directive has added its validator
        require: ['ngModel', 'select'],
        link: function(scope, element, attrs, ctrls) {
          var ngModelCtrl = ctrls[0];
          var selectCtrl = ctrls[1];

          var originalRequiredValidator = ngModelCtrl.$validators.required;

          ngModelCtrl.$validators.required = function() {
            if (attrs.required && selectCtrl.$isUnknownOptionSelected()) {
              return false;
            }

            return originalRequiredValidator.apply(this, arguments);
          };
        }
      };
    });

    it('should show the error message when the unknown option is selected', function() {

      var error = element(by.className('error'));

      expect(error.getText()).toBe('Error: Please select a value');

      element(by.cssContainingText('option', 'Option 1')).click();

      expect(error.isPresent()).toBe(false);

      element(by.tagName('button')).click();

      expect(error.getText()).toBe('Error: Please select a value');
    });