ユーザー名とパスワードが空ではなく、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も使用していることを述べることができます。
できるよ:
<form name="loginform" novalidate ng-submit="loginform.$valid && login.submit()">
コントローラチェックは不要です。
送信ボタンを次のように変更します。
<button type="submit" ng-disabled="loginform.$invalid">Login</button>
だからTheHippoからの提案された答えは私のために働かなかった、代わりに私はそのように関数へのパラメータとしてフォームを送ることになった:
<form name="loginform" novalidate ng-submit="login.submit(loginForm)" class="css-form">
これにより、コントローラメソッドでフォームが利用可能になります。
$scope.login = {
submit : function(form) {
if(form.$valid)....
}
あなたのフォームは自動的にオブジェクトとして$ scopeに置かれます。 $scope[formName]
経由でアクセスできます
以下は、ng-submitのパラメータとしてフォーム自体を渡さなくても、元の設定で機能する例です。
var controller = function($scope) {
$scope.login = {
submit: function() {
if($scope.loginform.$invalid) return false;
}
}
};
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();
}
}
}
OPの質問に対する直接的な解決策ではありませんが、フォームがng-app
コンテキスト内にあり、Angularに完全に無視させたい場合は、 ngNonBindable
ディレクティブを使用して明示的に行うことができます。 :
<form ng-non-bindable>
...
</form>
上記の答えを追加するために、
以下に示すように、私は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に提出することではなかったので、上で与えられたハックはちょうどうまく機能します。
私はこれが古いスレッドであることを知っていますが、私も貢献したいと思いました。私の解決策はすでに回答としてマークされた投稿に似ています。いくつかのインラインJavaScriptチェックがうまくいきます。
ng-click="form.$invalid ? alert('Please correct the form') : saveTask(task)"
私はそれが遅れていて答えられたことを知っています、しかし私は私が作ったきちんとしたものを共有したいです。フォームの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">