Is it possible to override ng-submit?

做~自己de王妃 提交于 2019-12-06 13:44:59

First, an element need not be "touched" for validation to work (that's about point #1). For example, this would invalidate the input, given $scope.test = "abcd"; and:

<input ng-model="test" ng-maxlength="3">

Second, #2 is easily achieved with form.$valid:

<form name="form1" ng-submit="form1.$valid && onSubmit()">
  ...
</form>

If pre-submit logic is more complicated then this, it could/should be done in the controller, for example, in the onSubmit() function.

But, if your pre-submit logic is View-related (as opposed to ViewModel-related) - and scrolling is View-related - then you could create another ngSubmit directive with higher priority and prevent default submit event handling:

.directive("ngSubmit", function() {
  return {
    require: "?form",
    priority: 10,
    link: {
      pre: function(scope, element, attrs, form) {
        element.on("submit", function(event) {        
          if (form && !form.$valid) {
            event.stopImmediatePropagation();
            event.preventDefault();

            // do whatever you need to scroll here
          }
        })
      }
    }
  }
});

Demo

EDIT:

Using pre-link is important here due to order of link function executions. The order of execution is:

1. pre-link of parent or higher priority directive
2. pre-link of child or lower priority directive
3. post-link of child or lower priority directive
4. post-link of parent or higher priority directive

So, the use of higher priority and pre-link ensures that this directive registers element.on("submit", ...) before the built-in ngSubmit does it, so it can have a first go at event handling.

This code should get you started as it addresses criterias number 1, 2 and gives you a hook for number 3.

As for scrolling to the invalid fields, I have not tried/needed that yet but sounds interesting. I guess you can get real bored and create an entire "form wrapper directive", though seems like overkill..

I would just use a service method that can be called in my controller. Are you thinking of just scrolling to the first invalid field and focusing it?

Template

<!-- Form Template -->
<form name="form" novalidate ng-submit="vm.submit(form.$valid, vm.data)">
    <input type="text"
           name="blah"
           ng-model="vm.data.blah"
           ng-model-options="{debounce: {'default': 300, blur: 0}}"
           required
           formnovalidate/>
     <div ng-messages="form.blah.$error"
          ng-messages-include="messages.html"
          ng-if="form.$submitted || form.blah.$touched">
     </div>
    <button type="submit">Submit</button>
</form>

<!-- messages.html -->
<div ng-message="required">This field is required</div>

Controller

vm.data = {};
vm.submit = function(isValid, data) {
    if (!isValid) { 
        //Scroll to bad field
        return; 
    }
    // Do form submission via service
};
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!