2

Using rails and .js.erb to make an AJAX request (and append values to a div), how do you prevent rendering a new layout? In other words, stay on the same page without going anywhere and just append the fresh data from the server in a div. No reloading the same page, no redirecting.

At the moment my controller looks like this

  def update_shipping
    @order = Order.find(params[:id])
    @order.shipping_option_id = params[:shipping_options]
    @order.save!

    respond_to do |format|
      format.js
      format.html
    end
  end

and my form like zisss:

        <%= form_tag update_shipping_order_path(@order), method: :put, remote: true do %>
          <%= select_tag 'shipping_options', @options_for_select, onchange: 'this.form.submit()' %>
        <% end %>

and my routes look like a so:

resources :orders do
  member do
    put :update_shipping
  end
end

But I get a 'Template is Missing' error

Please help!!

Marco Prins
  • 7,189
  • 11
  • 41
  • 76
  • 2
    please post your js code here – Rajdeep Singh Apr 04 '14 at 08:59
  • 1
    What does your `update_shipping.html.erb` (or .js) look like? The controller wants to render this file by default after your action. Ideally, it should contain only the `div` you want to return to the AJAX function for rendering on your current page. – KappaNossi Apr 04 '14 at 09:00
  • $('#shipping_cell').html('<%=j view_in_preferred_currency(@order.shipping_option.price) %>'); @KappaNossi – Marco Prins Apr 04 '14 at 09:01

4 Answers4

2

You need to add a update_shipping.js.erb file under app/views/your_controller/ directory. Note the name of the javascript file should be same as the action. Since you have a remote:true in your form so rails will try to render a javascript template in your case update_shipping.js.erb.

Now in your update_shipping.js.erb file write some basic javascript to update the page elements like

#update_shipping.js.erb
$('.some-div').html(<%=j @model.some_value' %>)
Monideep
  • 2,790
  • 18
  • 19
0

Try this:-

respond_to do |format|
          format.js { render :nothing => true }
          format.html
        end
techvineet
  • 5,041
  • 2
  • 30
  • 28
0

If you don't want to render a layout, you can use !request.xhr? like so:

respond_to do |format|
    format.html { layout: !request.xhr? }
    format.js 
end

If you're looking to get your ajax-powered JS to fire, you just need to call your .js.erb file the same as your view:

#app/views/controller/update_shipping.js.erb
alert("This JS is returned & fired after the Ajax request");

You'll be best doing this in your routes.rb too:

resources :orders do
    put :update_shipping
end
Richard Peck
  • 76,116
  • 9
  • 93
  • 147
0

A little late, I came across this searching for the same issue. It must of slipped out of my mind at some point while working with action cable, but what is needed is a http response code of no_content. Http response codes tell the browser how to act when a request is returned. Here is a link to a list of them, and their symbols in rails. More on 204 no content

Here is how it would look:

def update_shipping
    @order = Order.find(params[:id])
    @order.shipping_option_id = params[:shipping_options]
    @order.save!

    head :no_content #or head 204
end

edit: what solved the solution for me was a link provided by William Denniss in this stack overflow question