prevent multiple form submissions using angular.js - disable form button

后端 未结 9 712
耶瑟儿~
耶瑟儿~ 2020-12-13 21:22

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

相关标签:
9条回答
  • 2020-12-13 21:50

    Just add a new property in your controller

    $scope.processing = false;
    

    In your method

    $scope.processData = function(){
        $scope.processing = true;
        $http.post('').then(function(){
            $scope.processing = false;
        });
    });
    

    In your html bind ng-disabled attribute to the $scope.processing property to disable the button and show text while the method is processing.

    0 讨论(0)
  • 2020-12-13 21:50

    Here is a general way to do it for all AJAX requests using $http interceptors. If you have all of your REST routes starting from /api/ then:

         angular.module('yourapp').factory('loadingInterceptor',['$q','$rootScope',function($q,$rootScope) {
             var apiRe = /^\/api\//;
        return {
            request: function(config) {
                if (config.url.match(apiRe)) {
                    $rootScope.loading = true;
                }
                config.headers = config.headers || {};
    
                return config;
            },
            response: function(res) {
                $rootScope.loading = false;
                return $q.resolve(res);
            },
    
            'responseError': function(rejection) {
                $rootScope.loading = false;
                return $q.reject(rejection);
            }
        };
    }]);
    
    
    angular.module('yourapp').config(['$httpProvider', function($httpProvider) {
        $httpProvider.interceptors.push('loadingInterceptor');
    }]);
    

    Using interceptor you won't have to put $scope.isLoading in each controller. The downside is that any button with ng-disabled="loading" will be blocked during request.

    0 讨论(0)
  • 2020-12-13 21:52

    The easiest and most common way of doing it is to rely on $submitted property of form object like so:

    <form name="formName" ng-submit="submit()">
      ...
      <button type="submit" ng-disabled="formName.$submitted">Submit</button>
    </form>
    
    0 讨论(0)
  • 2020-12-13 21:58

    I have a standard form and just use angular in the front-end, so if you just need to prevent a button being clicked twice while the server is responding then you can use this simple directive which is re-usable and requires no controller or ngModel.

    http://plnkr.co/edit/2aZWQSLS8s6EhO5rKnRh?p=preview

    app.directive('clickOnce', function($timeout) {
        return {
            restrict: 'A',
            link: function(scope, element, attrs) {
                var replacementText = attrs.clickOnce;
    
                element.bind('click', function() {
                    $timeout(function() {
                        if (replacementText) {
                            element.html(replacementText);
                        }
                        element.attr('disabled', true);
                    }, 0);
                });
            }
        };
    });
    

    It will disable the button and optionally change the text of the button. Use like so:

    <button click-once>Button just disables</button>
    <button click-once="Loading...">Text changes and button disables</button>
    

    In its current form this will only work if you are doing standard form submissions and not ajax submission.

    0 讨论(0)
  • here is the simple way to do similar stuff with simple logical checks, text change can also be done in similar fashion.

    <button type="submit" class="btn btn-success btn-lg btn-block"  ng-disabled="!userForm.$valid || isValid">Submit!</button>
    
    
     $scope.isValid = false;
        $scope.submitForm = function () {
            $scope.isValid = true;
            console.log('submit');
        }
    
    0 讨论(0)
  • 2020-12-13 22:06

    An addition to spenthil answer, a variant in coffee script + you can enable a button back if you need (e.g. when a form validation has failed and you want to try again)

    class ClickOnceDirective
    
        constructor: (@$timeout) ->
            link = (scope, element, attrs) =>
    
                originalText = element.html()
                replacementText = attrs.clickOnce
    
                element.bind('click', =>
                    @$timeout ->
    
                        if (replacementText)
                            element.html(replacementText)
    
                        element.attr('disabled', true)
    
                        # enable back
                        @$timeout ->
                             element.attr('disabled', false)
                            if (replacementText)
                                 element.html(originalText)
                        , 500
    
                    , 0)
    
             return {
             link
             restrict: 'A'
            }
    
    directivesModule.directive 'clickOnce', ['$timeout', ClickOnceDirective]
    
    0 讨论(0)
提交回复
热议问题