I am trying to render a partial for the ajax request but i can't find how to do it using Ruby on Rails...
here what my array variable
#return = { :error => false, :response => "Added", :partial => ... }
render :json => ActiveSupport::JSON.encode( #return )
where ... is where the partial(html) should be...
the method name is add_item, its controller is items and i have created an add_item.html.erb file inside the items folder which has the HTML i want to pass to the array and use jQuery to add it to the DOM
i guess this could be done using
render :partial => "partial", :object => #object
but how can i add this into the array above?
Solution:
#return = { :error => false, :response => "Added", :partial => render_to_string(:partial => "partial/path", :object => #object) }
The way I do what I think you're trying to do is to fire an ajax message at add_item, and then in add_item have:
def add_item
respond_to do |format|
format.js
end
end
and make an add_item.js.erb with the jQuery contents:
$('#div-for-code').html('<%= escape_javascript(render :partial => "mypartial") %>');
not sure that it's the best way but it's worked for me.
Related
I need to output custom JSON in order to be backwards compatible with existing software, which is written in Javascript, so I need to wrap my JSON with "parseDate(" at the beginning of it, and ");" at the end of it.
I tried doing it in controller like this
def index
#data = Data.all
#products = Product.all
respond_to do |format|
format.html
format.json {render :json => { :products => {:product => #data.name}}}
end
end
And then specify it in the view:
app/views/products.json.erb
<%= p "parseData(" %>
<%= render :json %>
<%= p "};" %>
But it outputs pure JSON completely skipping both "parseData(" and ");", why? How do I make JSON to be printed in the middle of the view and then append strings to the top and bottom?
JSON renderer supports a callback option.
format.json { render :json => { :products => {:product => #data.name }}, :callback => 'parseDate' }
You can read the implementation in the renderer.rb source code.
How to update multiple partial through ajax in rails 3.2
Here i did my ajax request
$.ajax({
url: "/home/create_entry",
type: "POST",
data: params,
cache: false,
success: function(data) {
$('#'+did).html(data);
// $("#results").html('<%#=j render(:partial => 'explorer', :locals => {:entries => #entries, :entry_count=> #entry_count}) %>');
}
});
In controller written
def create_entry
if request.xhr?
#entry = Entry.new
#entry.title = params[:title]
respond_to do |format|
if #entry.save
flash[:notice] = "Entry created successfully"
#entry = Entry.last
#entries = Entry.where(:user_id => current_user.id).order(sort_column + ' ' + sort_direction)
#entry_count = #entries.count
format.js
end
end
end
And in create_entry.js.erb
<%= render :partial => 'edit_entry_form', :locals => {:entry => #entry}%>
<%= render :partial => 'explorer', :locals => {:entries => #entries}%>
Now i can able to get both data, How can i update both partial after success of ajax request ?
Thanks in advance.
You should look at using jQuery to dynamically insert the contents of these two partials into the areas of the page you want to update. Something like:
$("#divforedit_entry_form").html("<%= escape_javascript(render 'edit_entry_form' :locals => {:entry => #entry})%>");
$("#divforexplorer").html("<%= escape_javascript(render 'explorer' :locals => {:entries => #entries})%>");
First off we need to correct your AJAX call as we don't need to have the server response added onto the page only evaluated (which in Rails happens by default).
Javascript
$.ajax({
url: "/home/create_entry",
type: "POST",
data: params,
cache: false
});
Now we update the controller to perform the logic and get any required data to correctly render the partials.
Controller
def create_entry
if request.xhr?
# Create entry
respond_to do |format|
if #entry.save
# Collect any data needed for view
format.js
end
end
end
end
Now in the view we use jQuery and the Rails javascript helper to replace/insert the partials into the HTML document.
View (create_entry.js.erb)
$("#edit_entry_form").replaceWith("<%= j(render('edit_entry_form', :entry => #entry)) %>");
$("#explorer").replaceWith("<%= j(render('explorer', :entries => #entries)) %>");
The above presumes that the HTML IDs #edit_entry_form and #explorer exist.
I am using the will paginate gem for pagination. Things wok fine for me.I am trying to ajaxify it and I followed the http://railscasts.com/episodes/240-search-sort-paginate-with-ajax tutorial. But Ajax request is not being fired for me.
I have a index view. The view renders a partial called "_browser_form" which in turn renders a partial called "_listing". So I wanted to paginate the table in the _listing.
Please let me know if there is any error in my approach.
My controller:
def index
#ics = Ic.search(params[:root_name],params[:suite_name],params[:case_name],params[:name],'f').paginate(:per_page =>5, :page => params[:all_ics])
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => #ics }
end
end
My _browser_form.html.haml which is rendered from index.html.haml
- form_tag "/ics/mass_action", :method => :post, :multipart => true do
<div id="update_ics_table">
= render "listing", :show_check_boxes => show_check_boxes, :root_name=>params[:root_name],:suite_name=>params[:suite_name],:case_name=>params[:case_name],:name=>params[:name],:ic_filter=>1
</div>
=will_paginate #ics,:param_name=>:all_ics
My index.js.erb file:
$('#update_ics_table').html("<%= escape_javascript(render :partial => 'listing' ,:object => #ics) %>")
My .js file:
$(function () {
$('#update_ics_table .pagination a').live('click',
function () {
$.getScript(this.href);
return false;
}
);
});
Thanks,
Ramya.
Remove what you're doing in the Javascript and do this in the controller:
format.js {
render :update do |page|
page.replace 'listing', :partial => 'listing'
end
}
Similar: Best way to get will_paginate working with Ajax
It might have something to do with the fact that you're using HAML views and an js.erb file, but I don't use HAML so I can't be certain. Have a look at nex3's answer at this SO: How to send back js.haml in rails
If that is not the case, I think you need to change your respond_to controller action block to this:
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => #ics }
format.js #<------ This will execute index.js.erb
end
Everything I am reading about rails 3 and AJAX says that we should have
respond_to do |format|
#wines = Wine.all(:conditions => {:category => "Sparkling"})
format.js
end
and then a seperate js.erb file that is
$("wines").update("<%= escape_javascript(render :partial => "sparkling")%>")
but that one line js file seems a little extreme, can I do something like this:
respond_to do |format|
#wines = Wine.all(:conditions => {:category => "Sparkling"})
format.js {render :js => '$("wines").update("<%= escape_javascript(render :partial => "sparkling")%>"')}
end
and then leave out the extra .js.erb file
The problem I see here is a double render (am noob so I'm not sure)? What is the best way to do this?
Inline RJS is a bad practice, but you can use it like this:
def your_action
#wines = Wine.all(:conditions => {:category => "Sparkling"})
respond_to do |format|
format.js {render :update do |page|
page << '$("wines").update("<%= escape_javascript(render :partial => "sparkling")%>"')
end}
end
end
UPD
No, it's not silly to store one more file. It makes your controllers cleaner. Look with your_action.js.erb
# your controller
def your_action
#wines = Wine.all(:conditions => {:category => "Sparkling"})
end
# your you_action.js.erb
$("wines").update("<%= escape_javascript(render :partial => "sparkling")%>"
That is two lines instead of 6 :)
I'm porting an application from Merb 1.1 / 1.8.7 to Rails 3 (beta) / 1.9.1 that uses JSON responses containing HTML fragments, e.g., a JSON container specifying an update, on a user record, and the updated user row looks like . In Merb, since whatever a controller method returns is given to the client, one can put together a Hash, assign a rendered partial to one of the keys and return hash.to_json (though that certainly may not be the best way.) In Rails, it seems that to get data back to the client one must use render and render can only be called once, so rendering the hash to json won't work because of the partial render.
From reading around, it seems one could put that data into a JSON .erb view file, with <%= render partial %> in and render that. Is there a Rails-way of solving this problem (return JSON containing one or more HTML fragments) other than that?
In Merb:
controller:
only_provides :json
...
self.status = 204 # or appropriate if not async
return {
'action' => 'update',
'type' => 'user',
'id' => #user.id,
'html' => partial('user_row', format: :html, user: #user)
}.to_json
In Rails:
controller:
respond_to do |format|
format.json do
render template: '/json/message-1',
locals: {
action: 'update',
type: 'user',
id: #user.id,
partial: 'user_row.html.erb',
locals: { user: #user }
}
end
end
view: json/message-1.json.erb
{
"action": <%= raw action.to_json %>,
"type": <%= raw type.to_json %>,
"id": <%= raw id.to_json %>,
"html": <%= raw render(partial: partial, locals: locals).to_json %>
}
The closest to the original from Merb approach I could find in Rails is to use #render_to_string
render json: {
'action' => 'update',
'type' => 'user',
'id' => #user.id,
'html' => render_to_string(partial: 'user_row.html.erb', locals: { user: #user })
}
This gets around a fair bit of complexity that comes in from adding a layer of json.erb templates into the mix, whether it's Rails Purist approach I couldn't say; possibly something with RJS would typically be used.
There's another question that has more solutions for json.erb files. See json erb template cannot find other html partial
class UsersController < ApplicationController
respond_to :json
def show
#user = User.find(params[:id])
respond_with(#user) do |format|
if #user.save
format.json { render :json => #user }
else
format.json { render :json => #user.errors, :status => :unprocessable_entity }
end
end
end
end