I have a form with a submit button, the form will take 10 seconds to come back and I don't want the user to be clicking on the form meanwhile. My approach so far has been setting the text of the button to buttonText="Loading..."
and using ng-disable
with a flag that I'm setting when I do the submit(isSubmitted
). Considering this must be a general pattern, what is the best and most reusable way of doing this?
Asked
Active
Viewed 161 times
0

Art
- 5,864
- 3
- 30
- 32
2 Answers
2
Create a reusable component with a custom directive. The directive should create an isolate scope and use the '&' syntax to specify which parent scope function to call when the button is clicked. Pass a callback function so the directive can undo the button label change and the disabled attribute when the task is completed.
HTML:
<button wait-button do-stuff="doStuff(cbFn)">button label</button>
Directive:
myApp.directive('waitButton', function() {
return {
scope: {
doStuff: '&'
},
link: function(scope, element) {
var normalText = element.text();
var callbackFn = function() {
console.log('callback')
// element[0] is the (unwrapped) DOM element
element[0].disabled = false;
element.text(normalText);
}
element.bind('click', function() {
element[0].disabled = true;
element.text('Loading...');
// Weird syntax below! Arguments must
// be passed inside an object:
scope.doStuff({cbFn: callbackFn});
})
}
}
})
function MyCtrl($scope, $timeout) {
$scope.doStuff = function(callbackFn) {
console.log('doStuff');
// Do stuff here... then call the callback.
// We'll simulate doing something with a timeout.
$timeout(function() {
callbackFn()
}, 2000)
}
}

Mark Rajcok
- 362,217
- 114
- 495
- 492
-
how would you do this if `doStuff` came from an attribute from the element. Ideally, ``, would call `customFn`? – Art Jan 28 '13 at 06:30
-
You would still need to specify the callback argument: `on-click="customFn(cbFn)"` -- [fiddle](http://jsfiddle.net/mrajcok/7dGqA/1/). – Mark Rajcok Jan 28 '13 at 17:39
0
I recommend using jQuery .delegate function: remember "#" = control id and "."= css class
$("#create").click(function(){
$('body').append($('<div id="test" class="btn">click me<div>'));
});
//-- if you create single button use this
$("body").delegate("#test", "click", function() {
alert("worked!");
});
//-- if you create many buttons use this
// $("body").delegate(".btn", "click", function() {
// alert("worked!");
// });

greg
- 107
- 1
- 4