Reputation: 3534
I would love to be able to have an ERB partial like this:
<ul id='things-index'>
<% @things.each do |t| %>
<li><%= t.name %></li>
<% end %>
</ul>
And be able to update it in the controller like so:
class ThingsController < ApplicationController
def create
@thing = Thing.new(params[:thing])
@thing.save
respond_to do |format|
format.html
format.js do
@things = Thing.all
page.replace('things-index')
end
end
end
end
Meaning that JavaScript would be sent as a response without me having to explicity write a js.erb template like the following create.js.erb
:
$('#things-index').replaceWith('<%= escape_javascript(render("things/index")) %>')
There may be something like this already, either built in to Rails or available as a gem, but if there is, I'm not aware of it.
I suppose ideally, it would re-render the 'index' action via JS and send the update to the browser, so it might look more like this:
respond_to do |format|
format.html
format.js do
render 'index'
end
end
And know to replace #things-index
(or allow me to explicitly specify it).
Whoops...Apparently there was page.replace_html
when Prototype was part of Rails, but that functionality has been replaced by the .js.erb
template method. That seems much less DRY to me (tons of near-identical js.erb
templates), so if anyone has a solution, I'd appreciate it.
Upvotes: 3
Views: 4846
Reputation: 160321
You can pass whatever you want to your js.erb, including what to replace, and with what.
$('<%= @id %>').replaceWith('<%= escape_javascript(render(@renderable)) %>')
Note Even in 2012 this wasn't really a recommended way of doing things like this. These days (early 2015) I'd say it's even less recommended given the great client-side technologies available.
Upvotes: 4
Reputation: 5231
Another solution would be to send back just the data, for the client to render as it choses:
respond_to do |format|
format.html
format.json do
@things = Thing.all
render :json => @things
end
end
And on the client side:
function updateList(data){
var $item,
$list = $('#things-index');
$list.find('li').remove();
$.each(data, function(i, item){
$item = $('<li />').text(item.name);
$list.append($item);
});
}
$.getJSON('/my/route.json', function(data){
updateList(data);
});
Upvotes: 2