Question

I'm trying to create an AngularJS Directive to manage the promps of a <select> input. The 3 different modes are as follows:

  1. Don't allow a blank option
    • This is the default behavior
  2. Allow a blank option with no text
    • Achieved by setting allow-blank="true" on the directive
  3. Allow a blank option with prompt text
    • Achieved by setting allow-blank to any value other than "true"

However, the blank options are never available.

Demo on Plunker

Template

<select ng-options="tag.id as tag.name for tag in myTags">
  <option ng-if="allowBlank === 'true'" value=""></option>
  <option ng-if="allowBlank && allowBlank !== 'true'" value="">{{allowBlank}}</option>
</select>

Directive

myApp.directive('mySelector', ['$http', function($http) {
  return {
    templateUrl:'my-selector-template.html',
    restrict: 'E',
    scope: {
      allowBlank: '@?'
    },
    replace: true,
    controller: function ($scope) {
      $scope.myTags = [
        {"name":"aliquam in","id":1},
        {"name":"massa velit","id":2},
        {"name":"nec vestibulum","id":3}
      ];
    }
  };
}]);
Was it helpful?

Solution

The problem is that the content of the select is transcluded (see below). If you inspect the elements that are output you don't even see the option tags you defined inside.

As you're just using a string you should use a pre-linking function where you add the correct option in via javascript. The following code should do the trick (Forked Plunk).

link: {
  pre: function(scope, element, attrs){
    if(attrs.allowBlank === 'true') element.append('<option value=""></option>');
    else if(attrs.allowBlank && attrs.allowBlank !== '') element.append('<option value="">' + attrs.allowBlank + '</option>');
  }
}

EDIT The select does not 'transclude' it's contents, as @lightswitch05 pointed out the select directive grabs the first child with value="" as the empty node (source ref). Then later it clears out the contents of the select and dynamically adds in the relevant <option> tags (source ref)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top