BootstrapでAngularを使用しています。参照用のコードは次のとおりです。
<form name="newUserForm" ng-submit="add()" class="" novalidate>
<input type="text" class="input" ng-model="newUser.uname" placeholder="Twitter" ng-pattern="/^@[A-Za-z0-9_]{1,15}$/" required></td>
<button type="submit" ng-disabled="newUserForm.$invalid" class="btn btn-add btn-primary">Add</button>
</form>
ブートストラップにはinput:invalid {.... }
という形式の無効なフィールドのスタイルがあります。これらは、フィールドが空のときに作動します。また、Angularを介したパターンマッチングもあります。これにより、「:invalid」がオフで「.ng-invalid」がオンの場合に奇妙なケースが作成され、「。ng-invalid」クラスのbootstrap CSSクラスを再実装する必要があります。
2つのオプションが表示されますが、両方に問題があります
そこにあるAngular-Bootstrapディレクティブはスタイリングをカバーしません。
スタイリングにはBootstrapの「エラー」クラスを使用します。より少ないコードを書くことができます。
<form name="myForm">
<div class="control-group" ng-class="{error: myForm.name.$invalid}">
<label>Name</label>
<input type="text" name="name" ng-model="project.name" required>
<span ng-show="myForm.name.$error.required" class="help-inline">
Required</span>
</div>
</form>
編集:他の回答とコメントが指摘しているように、-Bootstrap 3でクラスは「エラー」ではなく「エラー」になりました。
クラスは、Bootstrap= 3:
<form class="form-horizontal" name="form" novalidate ng-submit="submit()" action="/login" method="post">
<div class="row" ng-class="{'has-error': form.email.$invalid, 'has-success': !form.email.$invalid}">
<label for="email" class="control-label">email:</label>
<div class="col">
<input type="email" id="email" placeholder="email" name="email" ng-model="email" required>
<p class="help-block error" ng-show="form.email.$dirty && form.email.$error.required">please enter your email</p>
<p class="help-block error" ng-show="form.email.$error.email">please enter a valid email</p>
...
'has-error'
と'has-success'
を囲む引用符に注意してください:それを見つけるのに時間がかかりました...
別の解決策:子入力に従ってhas-error
クラスを切り替えるディレクティブを作成します。
app.directive('bsHasError', [function() {
return {
restrict: "A",
link: function(scope, element, attrs, ctrl) {
var input = element.find('input[ng-model]');
if (input.length) {
scope.$watch(function() {
return input.hasClass('ng-invalid');
}, function(isInvalid) {
element.toggleClass('has-error', isInvalid);
});
}
}
};
}]);
そして、テンプレートでそれを簡単に使用します
<div class="form-group" bs-has-error>
<input class="form-control" ng-model="foo" ng-pattern="/.../"/>
</div>
@ farinczの答え のマイナーな改善。ここではディレクティブが最善のアプローチであることに同意しますが、_.form-group
要素なので、コードを更新して、.form-group
または親<form>
要素(含まれるすべての.form-group
要素):
angular.module('directives', [])
.directive('showValidation', [function() {
return {
restrict: "A",
link: function(scope, element, attrs, ctrl) {
if (element.get(0).nodeName.toLowerCase() === 'form') {
element.find('.form-group').each(function(i, formGroup) {
showValidation(angular.element(formGroup));
});
} else {
showValidation(element);
}
function showValidation(formGroupEl) {
var input = formGroupEl.find('input[ng-model],textarea[ng-model]');
if (input.length > 0) {
scope.$watch(function() {
return input.hasClass('ng-invalid');
}, function(isInvalid) {
formGroupEl.toggleClass('has-error', isInvalid);
});
}
}
}
};
}]);
@Andrew Smithの回答のマイナーな改善。入力要素を変更し、require
キーワードを使用します。
.directive('showValidation', [function() {
return {
restrict: "A",
require:'form',
link: function(scope, element, attrs, formCtrl) {
element.find('.form-group').each(function() {
var $formGroup=$(this);
var $inputs = $formGroup.find('input[ng-model],textarea[ng-model],select[ng-model]');
if ($inputs.length > 0) {
$inputs.each(function() {
var $input=$(this);
scope.$watch(function() {
return $input.hasClass('ng-invalid');
}, function(isInvalid) {
$formGroup.toggleClass('has-error', isInvalid);
});
});
}
});
}
};
}]);
すばらしい回答をありがとう@farincz。ユースケースに合わせて、いくつかの変更を加えました。
このバージョンには3つのディレクティブがあります。
bs-has-success
bs-has-error
bs-has
(他の2つを一緒に使用する場合に便利)私が行った変更:
element.find()
はタグ名による要素の検索のみをサポートするため、jQueryを使用していない人のためにelement.find()
に渡される文字列を変更しました。element.find()
を$timeout
にラップして、要素にまだDOMにレンダリングされた子がない場合をサポートします(たとえば、要素の子がng-if
でマークされている場合)。if
式を変更しました(if(input)
からの戻り値は @ farincz's answer からのelement.find()
==は常にtrueを返します) jQuery配列)。誰かがこれが役に立つと思うことを願っています!
angular.module('bs-has', [])
.factory('bsProcessValidator', function($timeout) {
return function(scope, element, ngClass, bsClass) {
$timeout(function() {
var input = element.find('input');
if(!input.length) { input = element.find('select'); }
if(!input.length) { input = element.find('textarea'); }
if (input.length) {
scope.$watch(function() {
return input.hasClass(ngClass) && input.hasClass('ng-dirty');
}, function(isValid) {
element.toggleClass(bsClass, isValid);
});
}
});
};
})
.directive('bsHasSuccess', function(bsProcessValidator) {
return {
restrict: 'A',
link: function(scope, element) {
bsProcessValidator(scope, element, 'ng-valid', 'has-success');
}
};
})
.directive('bsHasError', function(bsProcessValidator) {
return {
restrict: 'A',
link: function(scope, element) {
bsProcessValidator(scope, element, 'ng-invalid', 'has-error');
}
};
})
.directive('bsHas', function(bsProcessValidator) {
return {
restrict: 'A',
link: function(scope, element) {
bsProcessValidator(scope, element, 'ng-valid', 'has-success');
bsProcessValidator(scope, element, 'ng-invalid', 'has-error');
}
};
});
使用法:
<!-- Will show success and error states when form field is dirty -->
<div class="form-control" bs-has>
<label for="text"></label>
<input
type="text"
id="text"
name="text"
ng-model="data.text"
required>
</div>
<!-- Will show success state when select box is anything but the first (placeholder) option -->
<div class="form-control" bs-has-success>
<label for="select"></label>
<select
id="select"
name="select"
ng-model="data.select"
ng-options="option.name for option in data.selectOptions"
required>
<option value="">-- Make a Choice --</option>
</select>
</div>
<!-- Will show error state when textarea is dirty and empty -->
<div class="form-control" bs-has-error>
<label for="textarea"></label>
<textarea
id="textarea"
name="textarea"
ng-model="data.textarea"
required></textarea>
</div>
Guilhermeの bowerパッケージ をインストールすることもできます。
スタイリングが問題であるが、ネイティブ検証を無効にしたくない場合は、スタイリングを独自の詳細スタイルでオーバーライドしないでください。
input.ng-invalid, input.ng-invalid:invalid {
background: red;
/*override any styling giving you fits here*/
}
CSSセレクターの特異性を使用して問題をカスケードします。
次のJason Imの答えに対する私の改善は、show-validation-errorsとshow-validation-errorの2つの新しいディレクティブを追加します。
'use strict';
(function() {
function getParentFormName(element,$log) {
var parentForm = element.parents('form:first');
var parentFormName = parentForm.attr('name');
if(!parentFormName){
$log.error("Form name not specified!");
return;
}
return parentFormName;
}
angular.module('directives').directive('showValidation', function () {
return {
restrict: 'A',
require: 'form',
link: function ($scope, element) {
element.find('.form-group').each(function () {
var formGroup = $(this);
var inputs = formGroup.find('input[ng-model],textarea[ng-model],select[ng-model]');
if (inputs.length > 0) {
inputs.each(function () {
var input = $(this);
$scope.$watch(function () {
return input.hasClass('ng-invalid') && !input.hasClass('ng-pristine');
}, function (isInvalid) {
formGroup.toggleClass('has-error', isInvalid);
});
$scope.$watch(function () {
return input.hasClass('ng-valid') && !input.hasClass('ng-pristine');
}, function (isInvalid) {
formGroup.toggleClass('has-success', isInvalid);
});
});
}
});
}
};
});
angular.module('directives').directive('showValidationErrors', function ($log) {
return {
restrict: 'A',
link: function ($scope, element, attrs) {
var parentFormName = getParentFormName(element,$log);
var inputName = attrs['showValidationErrors'];
element.addClass('ng-hide');
if(!inputName){
$log.error("input name not specified!")
return;
}
$scope.$watch(function () {
return !($scope[parentFormName][inputName].$dirty && $scope[parentFormName][inputName].$invalid);
},function(noErrors){
element.toggleClass('ng-hide',noErrors);
});
}
};
});
angular.module('friport').directive('showValidationError', function ($log) {
return {
restrict: 'A',
link: function ($scope, element, attrs) {
var parentFormName = getParentFormName(element,$log);
var parentContainer = element.parents('*[show-validation-errors]:first');
var inputName = parentContainer.attr('show-validation-errors');
var type = attrs['showValidationError'];
element.addClass('ng-hide');
if(!inputName){
$log.error("Could not find parent show-validation-errors!");
return;
}
if(!type){
$log.error("Could not find validation error type!");
return;
}
$scope.$watch(function () {
return !$scope[parentFormName][inputName].$error[type];
},function(noErrors){
element.toggleClass('ng-hide',noErrors);
});
}
};
});
})();
エラーのコンテナにshow-validation-errorsを追加して、フォームフィールドの有効性に基づいてコンテナを表示/非表示にできます。
また、show-validation-errorは、特定のタイプのフォームフィールドの有効性に基づいて要素を表示または非表示にします。
使用目的の例:
<form role="form" name="organizationForm" novalidate show-validation>
<div class="form-group">
<label for="organizationNumber">Organization number</label>
<input type="text" class="form-control" id="organizationNumber" name="organizationNumber" required ng-pattern="/^[0-9]{3}[ ]?[0-9]{3}[ ]?[0-9]{3}$/" ng-model="organizationNumber">
<div class="help-block with-errors" show-validation-errors="organizationNumber">
<div show-validation-error="required">
Organization number is required.
</div>
<div show-validation-error="pattern">
Organization number needs to have the following format "000 000 000" or "000000000".
</div>
</div>
</div>
</form>
返信するには遅すぎると思いますが、あなたがそれを愛することを願っています:
[〜#〜] css [〜#〜]選択、日付、パスワードなどの他のタイプのコントロールを追加できます
input[type="text"].ng-invalid{
border-left: 5px solid #ff0000;
background-color: #FFEBD6;
}
input[type="text"].ng-valid{
background-color: #FFFFFF;
border-left: 5px solid #088b0b;
}
input[type="text"]:disabled.ng-valid{
background-color: #efefef;
border: 1px solid #bbb;
}
[〜#〜] html [〜#〜]:ng-required以外のコントロールには何も追加する必要はありません
<input type="text"
class="form-control"
ng-model="customer.ZipCode"
ng-required="true">
試してみて、コントロールにテキストを入力してください。本当に便利で素晴らしいと思います。
AngularJS自体の名前を聞いたことがない場合、これは非常に古い質問回答スレッドであることがわかります:-)
しかし、Angular + Bootstrapクリーンで自動化された方法でフォーム検証を行うために、私は達成するためのかなり小さなモジュールを書きましたどの形式のHTMLまたはJavascriptも変更せずに同じ。
チェックアウト Bootstrap Angular Validation 。
以下は3つの簡単な手順です。
bower install bootstrap-angular-validation --save
<script src="bower_components/bootstrap-angular-validation/dist/bootstrap-angular-validation.min.js"></script>
bootstrap.angular.validation
アプリケーションにそれだけ!!これはBootstrap 3およびjQueryis isnot required。
これは、jQuery検証の概念に基づいています。このモジュールは、追加の検証と検証エラーの一般的な一般的なメッセージを提供します。
<div class="form-group has-feedback" ng-class="{ 'has-error': form.uemail.$invalid && form.uemail.$dirty }">
<label class="control-label col-sm-2" for="email">Email</label>
<div class="col-sm-10">
<input type="email" class="form-control" ng-model="user.email" name="uemail" placeholder="Enter email" required>
<div ng-show="form.$submitted || form.uphone.$touched" ng-class="{ 'has-success': form.uemail.$valid && form.uemail.$dirty }">
<span ng-show="form.uemail.$valid" class="glyphicon glyphicon-ok-sign form-control-feedback" aria-hidden="true"></span>
<span ng-show="form.uemail.$invalid && form.uemail.$dirty" class="glyphicon glyphicon-remove-circle form-control-feedback" aria-hidden="true"></span>
</div>
</div>
</div>
フィドルなしでは確実に伝えるのは難しいですが、angular.jsコードを見ると、クラスを置き換えるものではありません-独自のコードを追加および削除するだけです。したがって、すべてのbootstrap=クラス(bootstrap UIスクリプトによって動的に追加された))は、angularによって変更されません。
とはいえ、検証のためにAngular-Angularのみを使用すると同時にBootstrapのJS機能を使用することは意味がありません。bootstrap =スタイルとangular JSつまり、カスタム検証ディレクティブを使用してbootstrap cssクラスを要素に追加します。