Search code examples
javascriptjqueryruby-on-railsajaxjquery-file-upload

How to validate form after AJAX submit?


I have a form which I submit via AJAX so expected response format from server is javascript. The problem is I can't make validation work like this. Usually I would do it just like this:

  # POST /cats
  # POST /cats.json
  def create
    @cat = Cat.new(cat_params)

    respond_to do |format|
      if @cat.save
        format.html { redirect_to @cat, notice: 'Cat was successfully created.' }
        format.json { render action: 'show', status: :created, location: @cat }
      else
        format.html { render action: 'new' }
        format.json { render json: @cat.errors, status: :unprocessable_entity }
      end
    end
  end 

But now I have a situation like this:

  # POST /cats
  # POST /cats.json
  def create
    @cat = Cat.new(cat_params)

    respond_to do |format|
      if @cat.save
        format.js { }
      else
        format.js { ????? }
      end
    end
  end

I've created create.js.erb which does everything what's needed for me if new object is saved but I don't know how to process validation display if the object is not saved. Inside my form I have this which works if I don't use AJAX:

  <% if @cat.errors.any? %>
    <div id="error_explanation">
      <ul>
      <% @cat.errors.full_messages.each do |msg| %>
        <li><%= msg %></li>
      <% end %>
      </ul>
    </div>
  <% end %>

What can I do? I am using Rails 4.


Solution

  • In your create.js.erb you can render the form again unless @cat.persisted?.

    1. Take the form in another partial for example '_form.html.erb'.

    2. If your form is inside a div with id "my_form_div",

    then the create.js.erb will be

    <%  if @cat.persisted? %>
      # code for success save
    <% else %>
      $('#my_form_div').html('<%= escape_javascript(render('form')) %>');
    <% end %>
    

    This will render the whole form again along with the errors. You can do the same for only the errors div if you don't want to render the full form again.