-1

I am using a custom directive to submit a form programmatically however no form validation is applied before submitting the form. I have called $setDirty() on the form field and $setSubmitted() on the form but the form is still submitted even if the required form field is empty.

directives/external.submit.js

export default class externalSubmit {
    constructor ($timeout) {
        'ngInject';
        this.$timeout = $timeout;
        this.restrict = 'A';
        this.scope = {};
    }

    link($scope, $element, $attrs) {
        $scope.$on('submit-form', function(event, data){
            if( data.id === $attrs.id ) {
              setTimeout(function() {

              /**
              * set form and fields to dirty
              * this should be enabling validation
              **/
              var $formScope = angular.element($element).scope();
              var $formController = $formScope[formName];

              $formController.$setDirty();
              $formController.$setSubmitted();
              angular.forEach($formController.$error.required, function(field) {
                field.$setDirty();
              });

                // trigger form submit
                $element.triggerHandler('submit');
              }, 0);   
            }
        });
    }

    // Create an instance so that we can access this inside link
    static factory() {
        externalSubmit.instance = new externalSubmit();
        return externalSubmit.instance;
    }
};

foo/foo.controller.js

export default class FooController {
    constructor( $rootScope ) {
      'ngInject';

      this.$rootScope = $rootScope;
      this.item = {};   

    }

    save() {
      alert('Save triggered');
    }

    submitForm(id) {
        // if no form id given, use the first form in the content area
        if ( ! id ) id = $('form')[0].id;
        this.$rootScope.$broadcast('submit-form',{'id':id} );
    }

}

foo/foo.html

<form external-submit id="primary" ng-submit="$ctrl.save()" go-back="dashboard.home()">
    <input type="hidden" ng-model="$ctrl.item.id"/>
    <input required name="title" ng-model="$ctrl.item.title" type="text" />
    <button type="submit">Internal Submit</button>
</form>

<button type="submit" ng-click="$ctrl.submitForm()">External Submit</button>
2
  • Why does the code inject $timeout but then uses a raw setTimeout instead? $timeout properly wraps setTimeout and is integrated with the AngularJS digest cycle. Using a raw setTimeout seems problematic. Commented Feb 11, 2017 at 16:31
  • Ah. Because I was getting a $timeout is not a function error. Printing $timeout to the console in the constructor shows that it is undefined. Any ideas? Commented Feb 11, 2017 at 19:15

2 Answers 2

0

Use ng-submit="$valid && $ctrl.save()"

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

1 Comment

Ok this is triggering the form validation, however when my fields are valid $ctrl.save() is never called - either when using the internal or external button.
-1

The solution is to check $formController to see if the form is valid before triggering the submit handler.

link($scope, $element, $attrs, $ctrl ) {      

    $scope.$on('submit-form', function(event, data){

        if( data.id === $attrs.id ) {
          let formName = $attrs.name;
          setTimeout(function() {

            // get the element scope
            var $formScope = angular.element($element).scope();

            // get the form controller using the form name
            var $formController = $formScope[formName];
            $formController.$setSubmitted();

            // check if form is valid before triggering submit
            if ( $formController.$valid ) {
                $element.triggerHandler('submit');
            }

            // required to update form styles
            $scope.$apply();

          }, 0);   
        }
    });
}

Comments

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.