前回作成した登録・編集機能にサーバー側でのパリでーションチェックを追加し、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>