Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I make angularjs ngChange handler be called only when user finishes typing

I have an input field, where I want to apply the variant of ngChange.

The input field is sort of binding with an ajax call, when user changes the input, the server side will process the data, however, I don't wanna make the call too often.

Say the user wanna input a really string, I want the call be made only after user finishes the word he is about to type. Nevertheless, I don't wanna use event such as blur. What would be a better way to implement this, rather than setTimeout?

like image 211
9blue Avatar asked Mar 03 '14 21:03

9blue


3 Answers

Use ng-model-options in Angular > 1.3

 <input type="text"
         ng-model="vm.searchTerm"
         ng-change="vm.search(vm.searchTerm)"
         ng-model-options="{debounce: 750}" />

Without ng-model-options -- In markup:

<input ng-change="inputChanged()">

In your backing controller/scope

var inputChangedPromise;
$scope.inputChanged = function(){
    if(inputChangedPromise){
        $timeout.cancel(inputChangedPromise);
    }
    inputChangedPromise = $timeout(taskToDo,1000);
}

Then your taskToDo will only run after 1000ms of no changes.

like image 157
calebboyd Avatar answered Nov 04 '22 12:11

calebboyd


As of Angular 1.3, you could use Angular ng-model-options directive

<input ng-change="inputChanged()" ng-model-options="{debounce:1000}">

Source: https://stackoverflow.com/a/26356084/1397994

like image 22
Adrien Avatar answered Nov 04 '22 12:11

Adrien


Write your own directive- this will only run the commands on myText based on the conditions you set

<input my-change-directive type="text ng-model="myText" />

.directive('myChangeDirective',function() {
    return {
        require : 'ngModel',
        link : function($scope,$element,$attrs) {
            var stringTest = function(_string) {
                //test string here, return true
                //if you want to process it
            }
            $element.bind('change',function(e) { 
                if(stringTest($attrs.ngModel) === true) {
                    //make ajax call here
                    //run $scope.$apply() in ajax callback if scope is changed
                }
            });
        }
    }
})
like image 31
koolunix Avatar answered Nov 04 '22 11:11

koolunix