Skip to content

Instantly share code, notes, and snippets.

@zacksheppard
Last active August 29, 2015 14:04
Show Gist options
  • Select an option

  • Save zacksheppard/79f413dbb3af43f757ab to your computer and use it in GitHub Desktop.

Select an option

Save zacksheppard/79f413dbb3af43f757ab to your computer and use it in GitHub Desktop.
Submitting AJAX forms in rails

Notes from Flatiron School lecture w08.d04 showing different ways to us AJAX forms in Rails. We will use a Todo list as an example domain for the examples.

Lowest level of abstraction


views/lists/index.erb.html This will create the list input form (Note: This should also work in Sinatra)

<% form_for List.new do |f| %>
  <input id="new-todo" placeholder="What needs to be done?" autofocus="" autocomplete="off">
<% end %>

<ul id="todo-list">
  <% @lists.each do |list| %>
    <li>
      <div class="view"><label><% link_to list.name, list %></label>
      </div>
    </li>
  <% end %>
</ul>

/assets/javascripts/lists.js This will listen to the form, catch the request, send it to the create route and reply modifying the page.

// create a function to handle the form data
function createList(event){
  // prevent the form from submitting a normal http POST
  event.preventDefault();
  
  // AJAX post, using the forms specified "action". serialize() makes it a string. then JSON makes it JSON, which is a hash.
  $.post($this).attr("action"),$(this).serialize(), function(json){
    // prepend that data fomratted into a new li
    new_list_html = '<li><a href="lists/'+ json.id +'">'+ json.name +'</li>
    $('ul').prepend(new_list_html)
  });
};

// Event listener that will call the above function.
$(function(){
  $("form.new_list").submit(createList);
})

AJAX form using remote: :true

This uses a built in rails method called remote to let the form know it will be using a remote submission that isn't the norm. remote: :true is part of rails/jquery-rails

When you tell the form it is a remote form it adds what's known as the 'universal handler' which will select that form, bind an event to it's submit action, take off the original form envelope (the standard form submission), take the form data, put it in a new AJAX envelope, and send it out to the server.

(Note: This example doesn't use a database so there would be a Where does the post go that isn't included here.)

views/index.erb.html Create the list input form

 # The 'remote: :true' here is the key that makes this work.
<% form_for List.new, remote: :true do |f| %>
  <input id="new-todo" placeholder="What needs to be done?" autofocus="" autocomplete="off">
<% end %>

<ul id="todo-list">
  # The iterator '<% @lists.each do |list| %>' is now taken care of in `views/lists/create.js.erb`
  # The li itself is now in a partial in ``views/lists/_list.html.erb``
</ul>

views/lists/create.js.erb

// ?? Need to look up the j render. I assume it's javascript render? 
$('ul').prepend("<%=j render @list %>")

views/lists/_list.html.erb

<li>
  <div class="view"><label><% link_to list.name, list %></label>
  </div>
</li>

/assets/javascripts/lists.js Notice that this file isn't here at all in this pattern

// The string injection is handled in the create.js.erb file
// The event handler has been abstracted away in remote: :true
// the post has also been abstracted away in remote: :true. When using remote: :true a new attribute to the form 'data-remote="true"'

[continue at 1:33 from first vid]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment