web-dev-qa-db-ja.com

入力検証が失敗したときにAngularjsがフォーム送信を防ぐ

ユーザー名とパスワードが空ではなく、3文字を超えていないことを確認するために、クライアント側の入力検証を伴う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>

そしてコントローラー:

var controller = function($scope) {

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

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

};

問題は、入力が無効であってもlogin.submit関数が呼び出されることです。これを防ぐことは可能ですか?

付記として、私はbootstrapとrequirejsも使用していることを述べることができます。

152
Runar Halse

できるよ:

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

コントローラチェックは不要です。

324
cyberwombat

送信ボタンを次のように変更します。

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

だからTheHippoからの提案された答えは私のために働かなかった、代わりに私はそのように関数へのパラメータとしてフォームを送ることになった:

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

これにより、コントローラメソッドでフォームが利用可能になります。

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

あなたのフォームは自動的にオブジェクトとして$ scopeに置かれます。 $scope[formName]経由でアクセスできます

以下は、ng-submitのパラメータとしてフォーム自体を渡さなくても、元の設定で機能する例です。

var controller = function($scope) {

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

        }
    }

};

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

13
davidmdem

HTML:

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

あなたのコントローラで:

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

OPの質問に対する直接的な解決策ではありませんが、フォームがng-appコンテキスト内にあり、Angularに完全に無視させたい場合は、 ngNonBindable ディレクティブを使用して明示的に行うことができます。 :

<form ng-non-bindable>
  ...
</form>
3
Ian Clark

上記の答えを追加するために、

以下に示すように、私は2つの通常のボタンを持っていました。 (タイプなし= "送信"どこでも)

<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>

いくら試しても、フォームが有効になったらEnterキーを押す「フォームのクリア」ボタンが呼び出され、フォーム全体がクリアされました。

回避策として

無効にして非表示にしたダミーの送信ボタンを追加する必要がありました。 そしてこのダミーボタンは下に示すように他のすべてのボタンの上になければなりませんでした

<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>

さて、私の意図は決してEnterに提出することではなかったので、上で与えられたハックはちょうどうまく機能します。

2
vighnu

私はこれが古いスレッドであることを知っていますが、私も貢献したいと思いました。私の解決策はすでに回答としてマークされた投稿に似ています。いくつかのインラインJavaScriptチェックがうまくいきます。

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

私はそれが遅れていて答えられたことを知っています、しかし私は私が作ったきちんとしたものを共有したいです。フォームのonsubmitをフックするng-validateディレクティブを作成し、$ evalがfalseの場合は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();            
    });
  };
});

あなたのHTMLで:

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