entre entre - 2 months ago 23
AngularJS Question

angularjs disable button on $http/$q calls

following the DRY principal, i want to write a button directive which keeps button disabled for the duration of $http class.

I want to do this so as to forbid user from clicking the buttons multiple times, but i am not able to think on how to get function promise status inside a directive, given that the function resides on $scope

the scenario is very generic, buttons ng-click does call a function which in turn makes $http calls. on user click : button should get disabled and should be enabled only after the $http call is resolved, either success or failure.

Answer

Although I would be careful of over-engineering, a way to do this would be by using a custom directive. This directive

  • Accepts an option, passed by attribute, of a function in the scope that must return a promise
  • On click of the button, calls this function, and disables the button
  • On finally of the promise, it re-enables the button

-

app.directive('clickAndDisable', function() {
  return {
    scope: {
      clickAndDisable: '&'
    },
    link: function(scope, iElement, iAttrs) {
      iElement.bind('click', function() {
        iElement.prop('disabled',true);
        scope.clickAndDisable().finally(function() {
          iElement.prop('disabled',false);
        })
      });
    }
  };
});

This can be used on a button as follows:

<button click-and-disable="functionThatReturnsPromise()">Click me</button>

You can see this in action at http://plnkr.co/edit/YsDVTlQ8TUxbKAEYNw7L?p=preview , where the function that returns the promise is:

$scope.functionThatReturnsPromise = function() {
  return $timeout(angular.noop, 1000);
} 

But you could replace $timeout with a call to $http, or a function from any service that returns a promise.