I am writing an application that will allow a user to add a component to a particular page in my DB, but am stuck on a little bit of the JS.
I have the form submitting just fine. I am stuck on how to "refresh" the container div that shows all of the current components tied to a page.
I am from a PHP background, so I know that I could write a method in my model and make an ajax call to it and just use jQuery to repopulate the container div. How would I do that in Rails? Or is there a better way of doing this?
Form:
<div class="add_component_block" style="display: none">
<%= form_for page, :url => page_url(page), :class => "edit_page" do |p| %>
<div class="field">
<%= select_tag :component_id, options_for_select(@components.collect { |comp| [comp.name, comp.id] }), :include_blank => 'Select a Component' %>
</div>
<div class="action">
<%= p.submit :Submit %>
</div>
<% end %>
</div>
jQuery:
$('#page_submit').click(function(e){
$.ajax({
url: $('.edit_page').attr('action'),
type: "PUT",
data: "component_id=" + $('#component_id').val(),
success: function(data){
location.reload();
}
});
return false;
});
Thanks in advance for the help!
Working Code
Controller:
def create
if !params[:component_id]
@component = Component.new(params[:component])
respond_to do |format|
if @component.save
params[:page_id].each { |p|
PagesComponent.create({ :page_id => p, :component_id => @component.id })
} unless params[:page_id].nil?
format.html { redirect_to(@component, :notice => 'Component was successfully created.') }
format.xml { render :xm开发者_如何学Cl => @component, :status => :created, :location => @component }
else
format.html { render :action => "new" }
format.xml { render :xml => @component.errors, :status => :unprocessable_entity }
end
end
else
@component = PagesComponent.new(:page_id => params[:page_id], :component_id => params[:component_id])
if @component.save
@all_components = Page.where("id = ?", params[:page_id])
@component_list = []
@all_components.each do |pc|
pc.components.each do |c|
@component_list << c.name
end
end
render :json => @component_list
end
end
end
jQuery:
$('#page_submit').click(function(){
$('.add_component_block').hide();
$.ajax({
url: $('.edit_page').attr('action'),
type: "POST",
data: "component_id=" + $('#component_id').val(),
success: function(data){
console.log(data)
$('#page_components').empty();
$.each(data, function(i, itemData){
$('#page_components').append("Name: " + itemData + "<br />")
});
}
});
return false;
});
location.reload()
is too big a hammer if you are just wanting to update what is in the #componend_id
div. Rails is no different from PHP in this regard. When it receives a post request from the client with an XmlRpc header, it then responds with whatever you tell it to:
@my_data = MyModel.find(whatever)
if request.xhr? do
respond_to do |format|
format.html # if this method responds to HTML
format.xml do
render @my_data.to_xml, :layout => false
end
format.json do
render @my_data.to_json, :layout => false
end
end
end
When the response is received in your success
handler, you can simply populate the div with the data that is shipped back, either as XML or JSON (at least, that's how I would ship it back).
You may want to use dataType: "json"
in your $.ajax
hash to make sure the accept headers are set properly. Then simply set $('#component_id').html(data['whatevercameback'])
.
To see the entire round trip, check it out in Firebug, which will show you what you are posting and what Rails is sending back.
精彩评论