Codebeerstartups

Ajaxify your site with remote => true and respond_to block

Introduction

user

Mohit Jain

Rails Developer


tips-and-tricks utilities

Ajaxify your site with remote => true and respond_to block

Posted by Mohit Jain on .
Featured

tips-and-tricks utilities

Ajaxify your site with remote => true and respond_to block

Posted by Mohit Jain on .

Here is a small application which is basically a scaffold but create, edit, update and destroy are done using ajax ie remote => true option in rails. See Demo.

So the very first thing is understand repond_to block. If you run a scaffold command and see new action code it looks like:

# GET /products/new
  # GET /products/new.json
  def new
    @product = Product.new

    respond_to do |format|
      format.html # new.html.erb
      format.json { render json: @product }
    end
  end

which means this will respond to only two kinds of request one is HTML and second is json.

Now for your-your ajax request your need to tell the controller to respond to js request which can be done but adding a line i.e.,.

# GET /products/new
  # GET /products/new.json
  # GET /products/new.js
  def new
    @product = Product.new

    respond_to do |format|
      format.html # new.html.erb
      format.json { render json: @product }
      format.js
    end
  end

Now you have told the controller to send the response for js request. Create a file ie new.js.erb. This is the file where you write some js code to make the response to do the desired stuff.

Cool. Let’s start from scratch.

Step 1: Make a new application Step 2: Generate a scaffold Step 3: Start making the js requests and add some code to get desired results.

Create an application and generate a scaffold ie:

rails g scaffold products name:string price:integer

Once You have it. Make a js requests for new link from index.html.erb ie:

<%= link_to 'New Product', new_product_path, :remote => true, :id => "new_product_link" %>

Now enable js requests in the controller for new action ie:

# GET /products/new
  # GET /products/new.json
  def new
    @product = Product.new

    respond_to do |format|
      format.html # new.html.erb
      format.json { render json: @product }
      format.js
    end
  end

Now create a new.js.erb file in products directory and add this line of code:

$('#new_product_link').hide().after('');

This will hide the new_product_link and add a new product form. Hit refresh of you index page and try to click on new product link. ;)

Now if you try to submit the form, it will be submitted as normal form. To make it ajax. Modify the form like this:

<%= form_for @product, :remote => true do |f| %> # adding remote=> true to form.

Now refresh and try to submit the form. The form will be submitted, but the request is not handled properly on controller end. Here is the same code for create action.

# POST /products
# POST /products.json
def create
  @product = Product.new(params[:product])

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

and create.js.erb

$('#new_product').remove();
$('#new_product_link').show();
$('#products').append(' @product)%>');

Hey hey.. Before you try to submit the form. Modify your index.html.erb like this so that you can render a product row in index.html.erb.

<h1>Listing products</h1>
<table>
  <tr>
    <th>Name</th>
    <th>Price</th>
    <th></th>
    <th></th>
    <th></th>
  </tr>
  <tbody id="products">
<% @products.each do |product| %>
<%= render "product", :product => product %>
<% end %>
</tbody>
</table>
<br />
<%= link_to 'New Product', new_product_path, :remote => true, :id => "new_product_link" %>

and a product.html.erb partial ie _product.html.erb

<tr id="product_<%= product.id %>">
  <td><%= product.name %></td>
  <td><%= product.price %></td>
  <td><%= link_to 'Show', product %></td>
  <td><%= link_to 'Edit', edit_product_path(product) %></td>
  <td><%= link_to 'Destroy', product, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>

Once you make this modification. You can see that rendering a new form and create a new product is completely Ajaxified. In the same way, you can do for edit form and update and for destroy.

Source code: Clone this repo to see the whole code

This is how you can do a lot of things to Ajaxify your site with respond_to and remote => true.

Update:

Do check out how to add validations in ajax based forms

user

Mohit Jain

http://codebeerstartups.com

Rails Developer