Skip to content Skip to sidebar Skip to footer

How To Prevent Property Change On Angular Js

I'm using AngularJs on my project and i've a property on my viewModel that is connected to a dropdown (< select >) that dropdown have a empty value witch is selected by defau

Solution 1:

what i want is to prevent user to select that empty value after he select some other value

This should happen automatically for you, as long as you don't assign the ng-model property a value initially. So using the <select> shown below, don't initialize $scope.selected_year in your controller:

<select ng-model="selected_year" ng-options="year for year in years"></select>

When the list displays initially, Angular will have added an option like this to the HTML, since $scope.selected_year is not currently set to a valid option/value:

<optionvalue="?"selected="selected"></option>

After selecting a valid choice, that option will magically disappear, so the user will not be able to select it again. Try it in this fiddle.

If the ng-model property already has a valid value assigned when the select list is first displayed, then you can assign a controller function to the undocumented ng-change parameter:

<select ... ng-change="preventUserFromDoingXzy()">

Inside function preventUserFromDoingXzy() you can do what you need to do to control what the user can select, or modify the model.

Solution 2:

You can just add ng-required to the select. If there is no initial value to the model then an empty option will be added and on change to a valid value it will remove the empty option

EDITEDjsFiddle to revert to previous value and to include the ng-change directive.

From the docs:

The expression is not evaluated when the value change is coming from the model.

This is useful in not interfering with change listeners and creating an infinite loop when reverting the old value in the $apply function

Controller

$scope.options = [{value: 'abc'},{value: 'def'}];

var confirmDialog = function(newVal, yes, no) {
    // obviously not a good way to ask for the user to confirm// replace this with a non blocking dialog//the timeout is only for the confirm since it's blocking the angular $digest
    setTimeout(function() {
        c = confirm('Is it ok? [' + newVal.value + ']');
        if(c) {
            yes();
        }
        else {
            no();
         }
    }, 0);
};

//Asking for confirmation examplefunctionCtrl($scope) {
    $scope.options = [{value: 'abc'},{value: 'def'}];

    $scope.select = undefined;
    var oldSelect = undefined;
    $scope.confirmChange = function(select) {
        if(oldSelect) {
            confirmDialog(select,
                 function() {
                    oldSelect = select;
                 },
                 function() {
                    $scope.$apply(function() {$scope.select = oldSelect;});
                });
        }
        else {
            oldSelect = select;
        }
    }
}

Template

<divng-controller="Ctrl"><selectng-model="select"ng-options="o.value for o in options"ng-requiredng-change="confirmChange(select)"></select></div>

Solution 3:

Probably the easiest, cleanest thing to do would be adding an initial option and setting disabled on it:

<optionvalue="?"selected="selected"disabled></option>

Solution 4:

Actually, it is easier to remove the empty value. Suppose you have a list of options:

$scope.options = [{value: ''}, {value: 'abc'},{value: 'def'}];

and a select:

<select ng-model="select" ng-options="o.value for o in options"></select>

Then $watch the model:

$scope.$watch('select', function(value) {
    if (value && value !== '') {
        if ($scope.options[0].value === '') {
            $scope.options = $scope.options.slice(1);
        }
    }
}, true);

See it in action here.

PS Don't forget the objectEquality parameter in the $watch or it won't work!

Post a Comment for "How To Prevent Property Change On Angular Js"