0

I have a select box with a blank option and some other options. The options are not generated with ngOptions directive, because they are generated on server side (with Symfony forms).

In some cases I want to unselect the selected value of the select box. So that the blank option is selected. But I cannot get this to work. The select box does not get updated.

I have created a jsfiddle to show the problem.

html

<div ng-controller="MyCtrl">
    <form name="form">
        <select ng-model="foo.hero" name="foo[hero]" my-directive="">
            <option value=""></option>
            <option value="1">Batman</option>
            <option value="2">Superman</option>
            <option value="3">Spiderman</option>
        </select>
    </form>
    <p>Selected: {{ foo.hero }}</p>
</div>

javascript

var myApp = angular.module('myApp',[]);

function MyCtrl($scope) {
    $scope.foo = {hero: '2'};
}

myApp.directive('myDirective', function($timeout) {
    return {
        require: ['ngModel', '?form'],
        link: function(scope, element, attrs, ctlrs) {
            $timeout(function() {
                var modelController = ctlrs[0];
                modelController.$setViewValue('');
            });
        }
    };
});
stollr
  • 6,534
  • 4
  • 43
  • 59
  • possible duplicate of [How to have a default option in select box - Angular.js](http://stackoverflow.com/questions/18194255/how-to-have-a-default-option-in-select-box-angular-js) – Dean Ward Jun 25 '14 at 14:49
  • Not really. My problem is, that I have to change the selected value in a directive. – stollr Jun 25 '14 at 14:56
  • OK, `ng-init` doesn't fit because the value is changing at some point later? you need to do this at some point `later? In that case I'd probably write an `ng-timeout` that mirrors `ng-init` functionality but wraps it in `$timeout`... Effectively what @Delta does below... – Dean Ward Jun 25 '14 at 15:27

3 Answers3

1

Use modelController.$render() after you call $setViewValue. This will update the DOM element(s).

myApp.directive('myDirective', function($timeout) {
    return {
        require: ['ngModel', '?form'],
        link: function(scope, element, attrs, ctlrs) {
            $timeout(function() {
                var modelController = ctlrs[0];
                modelController.$setViewValue('');
                modelController.$render();
            });
        }
    };
});

Updated fiddle here.

Patrick
  • 6,828
  • 3
  • 23
  • 31
0

Do this:

        $timeout(function() {
            scope.foo.hero = '';
        });

since the model of your select is foo.hero whenever you change it then the select will change the selected.

Delta
  • 869
  • 6
  • 12
0

Not sure why you need to muck around with modelController? Can't you just update the model to the default value?

myApp.directive('myDirective', function($timeout) {
    return {
        scope: {
            model: '=?ngModel'
        },
        link: function(scope, element, attrs, ctlrs) {
            $timeout(function() {
                scope.model = '';
            });
        }
    };
});

Updated fiddle here.

Dean Ward
  • 4,793
  • 1
  • 29
  • 36