开发者

Rails and Ajax form submission

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜