remote_function and :with or :submit, an update on previous post about graceful Ajax fallback

Posted by Tim Connor Tue, 07 Nov 2006 17:20:00 GMT

So the last post was a little more oversimplified than I realized. When I went to fix the bug in my implementation, I discovered I was leaving some important stuff out, like actually submitting the value of the form variable you want. :( As such, maybe it is complicated enough to use a nice concrete example.

There are two ways you can can get post the values to your remote_function (post, so discounting just putting it in the url). You can use

:with


<%= submit_tag 'Save', :name => 'save', :id => 'save' %>
<%= submit_tag 'Update Preview',
:name => 'preview',
:onclick => remote_function(
:url => {:action => :preview},
#:with => "'name_of_form_field'=value_you_want_and_javascript_is_legal" 
:with => "'patch[editing_rdoc]='+$('patch_modified_rdoc_source').value", 
:before => "$('preview_target').innerHTML='..loading..'",
:failure => "$('preview_target').innerHTML='Ajax error!'",
:update => 'preview_target'
) + ';return false;'
%> 

or :submit

<%= submit_tag 'Save', :name => 'save', :id => 'save' %>
<%= submit_tag 'Update Preview',
:name => 'preview',
:onclick => remote_function(
:url => {:action => :preview, :_method => :post},
:submit => "id_of_my_form",
:before => "$('preview_target').innerHTML='..loading..'",
:failure => "$('preview_target').innerHTML='Ajax error!'",
:update => 'preview_target'
) + ';return false;'
%> 
Note that :submit required adding the _method to my form url – I am not quite sure why it didn’t just use the one already in the form itself. Now a simplified version of my controller

#Called by the xhr
def preview
  @source = params[:patch][:editing_rdoc] unless params[:patch].nil? or params[:patch][:editing_rdoc].nil?
  render :layout => false
end

#called with fallback from .js being off
def create
  @patch = Patch.new params[:patch]
  respond_to do |format|
    #this is the heart of the matter - if preview wasn't pressed, just output the template again, with @patch values updated, but not saved to db.
    if !params[:preview] and @patch.save    
      format.html { redirect_to patch_url(@patch)  }
      format.xml do
        headers["Location"] = patch_url(@patch)
        render :nothing => true, :status => "201 Created" 
      end
    else
      format.html { render :action => "new" }
      format.xml  { render :xml => @patch.errors.to_xml }
    end
  end
end
and of course, don’t forget your very complicated preview template (simple_markup is a project specific helper, always remember your “h” or whatever you are using to escape)

<%= simple_markup @source -%>

Fix for Typo Scribbish theme v2 - aka disabling a submit button in IE 2

Posted by Tim Connor Thu, 26 Oct 2006 17:11:00 GMT

I looked into it a little more this morning, and came up with how to still get the submit button disabling, to avoid double-posts, without having to rework anything substantially.


<%= submit_tag 'Submit', :onclick => "$('commentform').onsubmit();this.disabled=true;Element.hide('preview');return false;"%>

You first call the form’s onsubmit, since IE won’t call it if you submit the form via JavaScript, then you prevent browsers that don’t cancel the form when you disable the submit button from double-submitting, by returning false at the end.

This should still work with javascript off, if you have the “Allow non-Ajax comments” setting turned on.