当输入验证失败时,Angularjs防止表单提交

时间:2022-12-05 07:54:11

I'm writing a simple login form using angularjs with some client side input validation to check that the user name and password is not empty and longer than three characters. See the below code:

我正在使用angularjs编写一个简单的登录表单,并进行一些客户端输入验证,以检查用户名和密码是否为空,且长度不超过三个字符。看下面的代码:

<form name="loginform" novalidate ng-submit="login.submit()" class="css-form">
    <fieldset>

        <div class="control-group input-prepend">
            <span class="add-on"><i class="icon-user"></i></span>
            <input type="text" ng-model="login.username" name="username" required ng-minlength="3" placeholder="username" />
        </div>

        <div class="control-group input-prepend">
            <span class="add-on"><i class="icon-lock"></i></span>
            <input type="password" ng-model="login.password" name="password" required ng-minlength="3" placeholder="" />
        </div>

        <div class="control-group">
            <input class="btn" type="submit" value="Log in">
        </div>

    </fieldset>
</form>

And the controller:

控制器:

var controller = function($scope) {

    $scope.login = {
        submit: function() {

            Console.info($scope.login.username + ' ' + $scope.login.password);
        }
    }

};

The problem is that the login.submit function will be called even if the input is not valid. Is it possible to prevent this behaviour?

问题是登录。即使输入无效,也将调用submit函数。有可能防止这种行为吗?

As a side note I can mention that I use bootstrap and requirejs as well.

作为附带说明,我可以提到我也使用bootstrap和requirejs。

9 个解决方案

#1


315  

You can do:

你能做什么:

<form name="loginform" novalidate ng-submit="loginform.$valid && login.submit()">

No need for controller checks.

不需要对控制器进行检查。

#2


62  

Change the submit button to:

将提交按钮更改为:

<button type="submit" ng-disabled="loginform.$invalid">Login</button>

#3


42  

So the suggested answer from TheHippo did not work for me, instead I ended up sending the form as a parameter to the function like so:

所以来自TheHippo的建议答案对我不起作用,相反,我将表单作为参数发送给函数如下:

<form name="loginform" novalidate ng-submit="login.submit(loginForm)" class="css-form">

This makes the form available in the controller method:

这使得控制器方法中的表单可用:

$scope.login = {
    submit : function(form) {
        if(form.$valid)....
    }

#4


13  

Your forms are automatically put into $scope as an object. It can be accessed via $scope[formName]

您的表单将自动作为对象放入$scope中。可以通过$scope[formName]访问它

Below is an example that will work with your original setup and without having to pass the form itself as a parameter in ng-submit.

下面是一个示例,它将使用您的原始设置,而不需要在ng-submit中将表单本身作为参数传递。

var controller = function($scope) {

    $scope.login = {
        submit: function() {
            if($scope.loginform.$invalid) return false;

        }
    }

};

Working example: http://plnkr.co/edit/BEWnrP?p=preview

工作示例:http://plnkr.co/edit/BEWnrP?p=preview

#5


12  

HTML:

HTML:

<div class="control-group">
    <input class="btn" type="submit" value="Log in" ng-click="login.onSubmit($event)">
</div>

In your controller:

在你的控制器:

$scope.login = {
    onSubmit: function(event) {
        if (dataIsntValid) {
            displayErrors();
            event.preventDefault();
        }
        else {
            submitData();
        }
    }
}

#6


3  

Although not a direct solution for the OPs question, if your form is within an ng-app context, but you want Angular to ignore it altogether, you can do this explicitly using the ngNonBindable directive:

虽然这不是操作问题的直接解决方案,但是如果你的表单是在一个ng-app上下文中,但是你想完全忽略它,你可以使用ngNonBindable指令显式地做到这一点:

<form ng-non-bindable>
  ...
</form>

#7


2  

Just to add to the answers above,

为了补充上面的答案,

I was having a 2 regular buttons as shown below. (No type="submit"anywhere)

我有两个常规按钮如下所示。(没有类型=“提交”)

<button ng-click="clearAll();" class="btn btn-default">Clear Form</button>
<button ng-disabled="form.$invalid" ng-click="submit();"class="btn btn-primary pull-right">Submit</button>

No matter how much i tried, pressing enter once the form was valid, the "Clear Form" button was called, clearing the entire form.

无论我尝试了多少次,只要表单有效,按下enter键,就会调用“Clear form”按钮,清除整个表单。

As a workaround,

作为一个解决方案,

I had to add a dummy submit button which was disabled and hidden. And This dummy button had to be on top of all the other buttons as shown below.

我必须添加一个无效和隐藏的虚拟提交按钮。这个假按钮必须在所有其他按钮的顶部,如下所示。

<button type="submit" ng-hide="true" ng-disabled="true">Dummy</button>

<button ng-click="clearAll();" class="btn btn-default">Clear Form</button>

<button ng-disabled="form.$invalid" ng-click="submit();"class="btn btn-primary pull-right">Submit</button>

Well, my intention was never to submit on Enter, so the above given hack just works fine.

嗯,我的意图是永远不提交进入,所以以上给出的黑客只是工作很好。

#8


1  

I know this is an old thread but I thought I'd also make a contribution. My solution being similar to the post already marked as an answer. Some inline JavaScript checks does the trick.

我知道这是一条古老的线索,但我认为我也会做出贡献。我的解决方案类似于已经标记为答案的帖子。一些内联JavaScript检查可以实现这一点。

ng-click="form.$invalid ? alert('Please correct the form') : saveTask(task)"

#9


0  

I know it's late and was answered, but I'd like to share the neat stuff I made. I created an ng-validate directive that hooks the onsubmit of the form, then it issues prevent-default if the $eval is false:

我知道已经很晚了,有人回答了我的问题,但我想和大家分享一下我做的那些漂亮的东西。我创建了一个ng-validate指令,它可以钩出表单的onsubmit,如果$eval是错误的,那么它就会发出prevent-default:

app.directive('ngValidate', function() {
  return function(scope, element, attrs) {
    if (!element.is('form'))
        throw new Error("ng-validate must be set on a form elment!");

    element.bind("submit", function(event) {
        if (!scope.$eval(attrs.ngValidate, {'$event': event}))
            event.preventDefault();
        if (!scope.$$phase)
            scope.$digest();            
    });
  };
});

In your html:

html:

<form name="offering" method="post" action="offer" ng-validate="<boolean expression">

#1


315  

You can do:

你能做什么:

<form name="loginform" novalidate ng-submit="loginform.$valid && login.submit()">

No need for controller checks.

不需要对控制器进行检查。

#2


62  

Change the submit button to:

将提交按钮更改为:

<button type="submit" ng-disabled="loginform.$invalid">Login</button>

#3


42  

So the suggested answer from TheHippo did not work for me, instead I ended up sending the form as a parameter to the function like so:

所以来自TheHippo的建议答案对我不起作用,相反,我将表单作为参数发送给函数如下:

<form name="loginform" novalidate ng-submit="login.submit(loginForm)" class="css-form">

This makes the form available in the controller method:

这使得控制器方法中的表单可用:

$scope.login = {
    submit : function(form) {
        if(form.$valid)....
    }

#4


13  

Your forms are automatically put into $scope as an object. It can be accessed via $scope[formName]

您的表单将自动作为对象放入$scope中。可以通过$scope[formName]访问它

Below is an example that will work with your original setup and without having to pass the form itself as a parameter in ng-submit.

下面是一个示例,它将使用您的原始设置,而不需要在ng-submit中将表单本身作为参数传递。

var controller = function($scope) {

    $scope.login = {
        submit: function() {
            if($scope.loginform.$invalid) return false;

        }
    }

};

Working example: http://plnkr.co/edit/BEWnrP?p=preview

工作示例:http://plnkr.co/edit/BEWnrP?p=preview

#5


12  

HTML:

HTML:

<div class="control-group">
    <input class="btn" type="submit" value="Log in" ng-click="login.onSubmit($event)">
</div>

In your controller:

在你的控制器:

$scope.login = {
    onSubmit: function(event) {
        if (dataIsntValid) {
            displayErrors();
            event.preventDefault();
        }
        else {
            submitData();
        }
    }
}

#6


3  

Although not a direct solution for the OPs question, if your form is within an ng-app context, but you want Angular to ignore it altogether, you can do this explicitly using the ngNonBindable directive:

虽然这不是操作问题的直接解决方案,但是如果你的表单是在一个ng-app上下文中,但是你想完全忽略它,你可以使用ngNonBindable指令显式地做到这一点:

<form ng-non-bindable>
  ...
</form>

#7


2  

Just to add to the answers above,

为了补充上面的答案,

I was having a 2 regular buttons as shown below. (No type="submit"anywhere)

我有两个常规按钮如下所示。(没有类型=“提交”)

<button ng-click="clearAll();" class="btn btn-default">Clear Form</button>
<button ng-disabled="form.$invalid" ng-click="submit();"class="btn btn-primary pull-right">Submit</button>

No matter how much i tried, pressing enter once the form was valid, the "Clear Form" button was called, clearing the entire form.

无论我尝试了多少次,只要表单有效,按下enter键,就会调用“Clear form”按钮,清除整个表单。

As a workaround,

作为一个解决方案,

I had to add a dummy submit button which was disabled and hidden. And This dummy button had to be on top of all the other buttons as shown below.

我必须添加一个无效和隐藏的虚拟提交按钮。这个假按钮必须在所有其他按钮的顶部,如下所示。

<button type="submit" ng-hide="true" ng-disabled="true">Dummy</button>

<button ng-click="clearAll();" class="btn btn-default">Clear Form</button>

<button ng-disabled="form.$invalid" ng-click="submit();"class="btn btn-primary pull-right">Submit</button>

Well, my intention was never to submit on Enter, so the above given hack just works fine.

嗯,我的意图是永远不提交进入,所以以上给出的黑客只是工作很好。

#8


1  

I know this is an old thread but I thought I'd also make a contribution. My solution being similar to the post already marked as an answer. Some inline JavaScript checks does the trick.

我知道这是一条古老的线索,但我认为我也会做出贡献。我的解决方案类似于已经标记为答案的帖子。一些内联JavaScript检查可以实现这一点。

ng-click="form.$invalid ? alert('Please correct the form') : saveTask(task)"

#9


0  

I know it's late and was answered, but I'd like to share the neat stuff I made. I created an ng-validate directive that hooks the onsubmit of the form, then it issues prevent-default if the $eval is false:

我知道已经很晚了,有人回答了我的问题,但我想和大家分享一下我做的那些漂亮的东西。我创建了一个ng-validate指令,它可以钩出表单的onsubmit,如果$eval是错误的,那么它就会发出prevent-default:

app.directive('ngValidate', function() {
  return function(scope, element, attrs) {
    if (!element.is('form'))
        throw new Error("ng-validate must be set on a form elment!");

    element.bind("submit", function(event) {
        if (!scope.$eval(attrs.ngValidate, {'$event': event}))
            event.preventDefault();
        if (!scope.$$phase)
            scope.$digest();            
    });
  };
});

In your html:

html:

<form name="offering" method="post" action="offer" ng-validate="<boolean expression">