I want to prevent multiple form submissions using angular.js. The question is related to this question.
When the user clicks on a form submit button the value / labe
Alternative (flexible & simple) solution (inspiration) : a wrapper function around the submit code that sets a scope variable. See live example.
Usage in controller:
$scope.submit = mutexAction($scope, 'sending', submit);
in view:
<form ng-submit="submit()">
...
<button ng-disabled="sending">
{{sending ? "Sending..." : "Send"}}
</button>
</form>
The function (put it in a service):
function mutexAction(scope, semaphoreName, action) {
return function() {
if (scope[semaphoreName]) {
// not queuing action, forget it!
return;
}
scope[semaphoreName] = true;
action()['finally'](function () {
scope[semaphoreName] = false;
});
};
}
Try a $timeout (the angularjs function)
$timeout(function(){
elm.attr('disabled',true);
}, 0)
I ended up going the directive route as well. The following is used instead of ng-click and expects the passed in function to return a promise (which restangular does). When the promise is resolved (response is returned) - it will allow subsequent submittals. Could also tweak this to add/remove ng-disabled.
// copied from ngClick and modified to provide single click only behavior
// expects function to return promise
app.directive('srMutexClick', function ($parse) {
return {
compile: function ($element, attr) {
var fn = $parse(attr['srMutexClick']);
return function srEventHandler(scope, element) {
var submitting = false;
element.on('click', function (event) {
scope.$apply(function () {
if (submitting) {
return
}
submitting = true;
// `submitting` is reset when promise is resolved
fn(scope, {$event: event}).finally(function() { submitting = false });
});
});
};
}
};
});