0

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?

Art
  • 5,864
  • 3
  • 30
  • 32

2 Answers2

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)
    }
}

Fiddle

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