Praveen KJ
Praveen KJ

Reputation: 650

Rails submitting a form through ajax and updating the view

I want to update a form submit through ajax without reloading the page and update the view according to it. I tried the different methods and failed as i m new to rails.

Here's the situation.

In modal

def new
    @new_entry = current_user.notes.build
    @words = current_user.notes
    @notes_false_list = current_user.notes.where(known: false).order("title").group_by { |note| note.title[0] }
    @notes_true_list = current_user.notes.where(known: true).order("title").group_by { |note| note.title[0] }
  end

In view the form code.

<%= form_for @new_entry, :html => {:class => 'home-form without-entry clearfix'}  do |f| %>
      <%= f.text_field :title, placeholder: 'Squirrel', autofocus: true, class: 'title-field pull-left' %>
      <%= f.submit '', class: 'btn home-add without-entry' %>
  <% end %>

The create action

def create
    @new_note = current_user.notes.build(new_note_params)
    if @new_note.save
      @notes_list = current_user.notes.count
      unless @new_note.user.any_entry
        @new_note.user.toggle!(:any_entry) if @notes_list >= 50
        redirect_to root_url
      end
    else
      redirect_to root_url
    end
  end

and finally in the view i want to change

<p class="instructions count-instruction text-center">
      <%= @words.count %>
    </p>

Spent a lot of time updating this with AJAX but failed everytime. Any there to help? Thanks in advance.

Upvotes: 9

Views: 38878

Answers (4)

Milind
Milind

Reputation: 5112

your code is good,but for ajax,

  1. you need to add remote=true to your form.

    <%= form_for(@image,:html=>{:id=>"your_form_id",:multipart => true,:remote=>true}) do |f |%>

  2. Moreover at your server side,you need to create a js.erb file in views/users/show_updated_view.js.erb to reply back to browser as its a js call and NOT html call and hence need to show the user that something happened(success/error) after form submission (if its users_controller),

so inside your action,you need something like:-

        respond_to do |format|  
            format.js { render 'users/show_updated_view'}
        end  
  1. And in show_updated_view.js.erb,you should update your view for the users to know that the view has been updated or form has been successfully submitted by either hiding the entire form/resetting the form or replacing the form with new div saying that data is updated..or anything that is intuitive.There are many ways though :).

    //here i am replacing your entire form with div having a message

    $("#your_form_id").html("<div><p>You have submitted the form successfully.</p></div>");

The name of the view can be anything but you need to take care of both success and failure.

Upvotes: 17

Yen-Ju
Yen-Ju

Reputation: 477

Here is a short article on doing AJAX with Rails. A few things to note:

  1. Add remote: true in your form_for.
  2. Include format.js in your controller so that it will render create.js.erb.
  3. In create.js.erb, do something like this (not tested):

    $("p.instructions").innerHTML("<%= @notes_list %>")

Upvotes: 4

sghosh968
sghosh968

Reputation: 601

Try adding respond_to block in your controller action "create", and respective create.js.erb and put in your js that you want to get executed after the create action, and do post any error that you are getting on your browser console or rails server console, do that we can help you find where you are getting wrong

Upvotes: 0

Max Williams
Max Williams

Reputation: 32955

The thing to remember with AJAX is that you don't redirect the request (normally), you just generate some text to send back to the browser. AJAX is basically just javascript to get some text from the browser and do something with it. Often, you would want to replace a section of the page, ie replace an html tag and it's contents, with the text you get back, in which case you want the text to be some html. The way to render a chunk of html in rails is to render a partial, so you do that, and you often also do some javascript to tell the browser what to do with the text, usually to replace an element that has a specific id with the text.

def create
  @new_note = current_user.notes.build(new_note_params)
  if @new_note.save 
    @notes_list = current_user.notes.count
    unless @new_note.user.any_entry
      @new_note.user.toggle!(:any_entry) if @notes_list >= 50
    end
  end
  respond_to do |format|
    format.html { redirect_to root_url }
    format.js #default behaviour is to run app/views/notes/create.js.erb file
  end
end

the respond_to block here allows you to treat html and js (eg ajax) requests differently.

The app/views/notes/create.js.erb could have something like

page.replace "foo", :partial => "app/views/notes/bar"

Upvotes: 0

Related Questions