LoginSignup
38
32

More than 5 years have passed since last update.

rails4 + bootstrapでajaxのvalidation結果をフォームに反映

Posted at

サーバーサイドでのvalidation結果をajaxのフォームに反映させたい時ありますよね。

htmlをエラーメッセージ表示部分を固定で準備しておきます。エラーが起こったら表示するために、最初はhideを指定して表示されなくします。

<div class="alert alert-danger hide" id="image-new-error-message">
  データの登録に失敗しました。
  <div id="errors"><ul/></div>
</div>

フォームはremoteを指定してajaxで動作するようにします。

<%= form_for Image.new, :html => {:multipart => true, :id => "image-new-form"}, :remote => true do |f| %>
<%= f.file_field :image %>
<%= f.text_field :title %>
<%= f.form_group do %>
 <%= f.submit "新規登録する" %>
<% end %>

コントローラー側の処理は保存に成功したら何も返さない。エラーが発生したらjsonでメッセージをそのまま返します。

  def create
    @image = Image.new(params.require(:image).permit([:image, :title]))
    if @image.save
      render nothing: true, status: 200
    else
      render json: {errors: @image.errors.messages}, status: 422
    end
  end

エラー時にはこんな感じでjsonが帰ってきます。

{"errors":{"image":["写真を入力してください。"],"title":["タイトルは64文字以内で入力してください。"]}}

javascriptでは、エラーだったらjsonをパースして<ul/>になっている箇所にエラーメッセージを追加。エラーが起こったフィールドから、親のform-groupを特定してhas-errorを追加します。

ポストする前と、成功した時でエラーの表示を取り除きます。

 $("#image-new-form").on("ajax:error", function(event, xhr) {
   $("#image-new-error-message").removeClass('hide').show();
   var errors = JSON.parse(xhr.responseText).errors;
   $.each(errors, (function(k, v){
     $("#errors ul").append("<li>" + v + "</li>");
     $("#image_" + k).closest(".form-group").addClass("has-error")
   }));
 }).on("ajax:success", function() {
   $("#image-new-error-message").hide();
   $("#errors ul").empty();
   $("#image-new-form" ).find(".form-group").removeClass("has-error")
 }).on("ajax:before", function() {
   $("#image-new-error-message").hide();
   $("#errors ul").empty();
   $("#image-new-form" ).find(".form-group").removeClass("has-error")
 });

これでajaxのフォームにvalidationのメッセージがそのまま反映されます。
この実装ではhelp-blockに触れていません。

38
32
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
38
32