前回作成した登録・編集機能にサーバー側でのパリでーションチェックを追加し、Rails側で表示する設定を追加しました。
1)Railsモデルにバリデーションを登録
nameのカラムを20文字以下に制限します。
$ vi app/models/user.rb
class User < ActiveRecord::Base
validates :name, presence: true, length: { maximum: 20 }
end
2)バリデーションエラーメッセージをAngularJSコントローラで設定
Rails側でのバリデーションエラーメッセージは、下記のようにJSONフォーマットでリターンしています。
render json: @user.errors, status: :unprocessable_entity
①underscore.jsをインクルード
underscoreの機能を使用するので下記設定を追加します。
・underscore-min.jsを入手し、vendor/assets/javascriptsディレクトリに配置。
・application.jsに追加
$ vi app/assets/javascripts/application.js
//= require underscore-min
②Editコントローラにバリデーションエラーメッセージの設定追加
$resourceサービスのcreate、updateアクション失敗時のコールバック関数にバリデーションメッセージを設定します。
$ vi app/assets/javascripts/mymodule.js.erb
mymodule.controller("UsersEditCtrl", function($scope, $routeParams, userResource,$location) {
$scope.submit = function() {
function success(response) {
$location.path("/users");
}
function failure(response) {
console.log("failure", response)
_.each(response.data, function(errors, key) {
_.each(errors, function(e) {
$scope.form[key].$dirty = true;
$scope.form[key].$setValidity(e, false);
});
});
}
if ($routeParams.id) {
userResource.update($scope.user, success, failure);
} else {
userResource.create($scope.user, success, failure);
}
};
$scope.errorMessage = function(name) {
var s = $scope.form[name].$error;
result = [];
_.each(s, function(key, value) {
result.push(value);
});
return result.join(", ");
};
});
3)ng-classを使ってバリデーションエラー時のCSS設定を追加
バリデーションエラー発生時に、動的にBootstrap3の”has-error”CSSクラスを設定します。
これで、エラー発生時に入力項目が赤くなります。
$ vi app/assets/javascripts/mymodule.js.erb
$scope.errorClass = function(name) {
var s = $scope.form[name];
return s.$invalid && s.$dirty ? "has-error" : "";
};
4)ビューにエラーを表示する記述追加
$ vi app/assets/templates/users/edit.html
<form name="form" ng-submit="submit()" class="form-horizontal" novalidate>
<div class="form-group" ng-class="errorClass('name')>
<label class="col-sm-2 control-label" for="name">名前</label>
<div class="col-sm-10">
<input class="form-control" ng-model="user.name" type="text" name="name" placeholder="名前" required autofocus>
<span class="help-block" ng-show="form.name.$invalid && form.name.$dirty">
{_{errorMessage('name')}}
</span>
</div>
</div>
<div class="form-group" ng-class="errorClass('email')">
:
</div>
</form>