5

From Angular's documentation it follows that ngSubmit is a preferred way of submitting a form. All pending operations are immediately finished and $submitted flag is set as well. Whereas listening to ngClick event does not have the same effect.

Now I need to submit a form with hotkeys having all the goodies of ngSubmit approach. Hence I need some way to trigger standard submit workflow.

I tried submit() on DOM form and it worked, but angular's form object attached to scope contains no references to DOM form, thus I need to access it through jqLite:

var frm = angular.element('#frmId');
frm.submit();

I didn't like this solution for accessing DOM in controller code so I created a directive:

function wuSubmit() {
    return {
        require: 'form',
        restrict: 'A',
        link: function(scope, element, attributes) {
            var scope = element.scope();
            if (attributes.name && scope[attributes.name]) {
                scope[attributes.name].$submit = function() {
                    element[0].submit();
                };
            }
        }
    };
}

which extends form object with $submit method.

Both variants do not work for yet unknown reason. form.submit() tries to send data, default action is not prevented.


Update 1
It turns out that Angular listens to click events of elements having type="input".
Eventually I decided to trigger click event for that element:

wuSubmit.$inject = ['$timeout'];
function wuSubmit($timeout) {
    return {
        require: 'form',
        restrict: 'A',
        link: function (scope, element, attributes) {
            var submitElement = element.find('[type="submit"]').first();

            if (attributes.name && scope[attributes.name]) {

                scope[attributes.name].$submit = submit;
            }

            function submit() {
                $timeout(function() {
                    submitElement.trigger('click');
                });
            }
        }
    };
}

Is there any out of the box solution for this functionality?

1
  • How are you binding normal form submission in your form in HTML? Commented Dec 29, 2014 at 13:55

3 Answers 3

4

Just use event .triggerHandler('submit') on form element.

myApp.directive("extSubmit", ['$timeout',function($timeout){
    return {
        link: function($scope, $el, $attr) {
            $scope.$on('makeSubmit', function(event, data){
              if(data.formName === $attr.name) {
                $timeout(function() {
                  $el.triggerHandler('submit'); //<<< This is Important

                  //equivalent with native event
                  //$el[0].dispatchEvent(new Event('submit')) 
                }, 0, false);   
              }
            })
        }
    };
}]);

Look at http://jsfiddle.net/84bodm5p/

Sign up to request clarification or add additional context in comments.

Comments

1
app.directive("form", function(){
     return {
        require: 'form',
        restrict: 'E',
        link: function(scope, elem, attrs, form) {
            form.doSubmit = function() {
                form.$setSubmitted();
                return scope.$eval(attrs.ngSubmit);
            };
        }
    };
});

Html:

<form name="myForm" ng-submit="$ctrl.submit()" novalidate>

Then call in controller

$scope.myForm.doSubmit();

1 Comment

This is a novel solution, monkey-patch the ngFormController to add a doSubmit method.
0

You can modify your directive code a bit like:

function wuSubmit() {
    return {
        require: 'form',
        restrict: 'A',
        link: function(scope, element, attributes) {
            var scope = element.scope();
            if (attributes.name && scope[attributes.name]) {
                scope[attributes.name].$submit = function() {
                    // Parse the handler of submit & execute that.
                    var fn = $parse(attr.ngSubmit);
                    $scope.$apply(function() {
                        fn($scope, {$event: e});
                    });
                };
            }
        }
    };
}

Here you don't have to add wu-submit everywhere. ng-submit will work.

Hope this helps!

2 Comments

nope.. the problem is not in calling the same handler. The problem is in making angular to perform all operations like it does when real submit happens.
Do you mean performing validations & all by saying "Performing all operations"?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.