This project is archived and is in readonly mode.
remote_form_for improperly concats </form> too early when there are errors for a given resource
Reported by Daniel Rice | August 9th, 2009 @ 03:59 AM
With Rails 2.3.2, I found this while writing an AJAX form to update a users email address.
When using remote_form_for, the prototype helper method properly appends onto the partial when you initially click "Update Email" link. The resulting form updates as expected. BUT, when you fill out the form incorrectly (the user resource doesn't not pass validation, could be anything, the specific validator doesn't appear to matter) and the controller reloads the form, it improperly terminates the form after the first wrapped div and then renders the submit button useless because the input tags are now outside of the form tag!
The form works properly by using form_for tag so I see this as a
defect in the remote_form_for helper. Details below:
_show_email.html.erb
<p><b>Email Address: </b><span id="email_target"><%=h @user.email%><%= link_to_remote 'Update Email', :update=>'email_target', :url=>{:controller=>'users', :action=>'edit_email_ajax'} %></span></p>
_edit_email.html.erb
<% remote_form_for(@user, :update=>'email_target',:url=>{:controller=>'users', :action=>'update_email_ajax'}) do |f| -%>
<p><%= f.error_messages %></p>
<p><label for="email">Email</label><br/>
<%= f.text_field :email %></p>
<p><label for="email_confirmation">Confirm Email</label><br/>
<%= f.text_field :email_confirmation %></p>
<p><%= f.submit 'Submit' %></p>
<%end -%>
user_controller.rb snippet
def edit_email_ajax
@user = current_user
render :partial=>'edit_email'
end
def update_email_ajax
@user = current_user
if @user.update_attributes(params[:user])
render :partial=>'show_email'
else
render :partial=>'edit_email'
end
end
rendered HTML code from form without errors - notice the /form
tag is at the end in its proper place.
<form action="/users/update_email_ajax" class="edit_user" id="edit_user_1" method="post" onsubmit="new Ajax.Updater('email_target', '/users/update_email_ajax', {asynchronous:true, evalScripts:true, parameters:Form.serialize(this)}); return false;"><div style="margin: 0pt; padding: 0pt;"><input name="_method" value="put" type="hidden"><input name="authenticity_token" value="bcedBLfJCarXCWIGJ85gjGAaO5Q7hUKinqowlWou2iI=" type="hidden"></div> <p></p>
<p><label for="email">Email</label><br>
<input id="user_email" name="user[email]" size="30" value="phonk64@gmail.com" type="text"></p>
<p><label for="email_confirmation">Confirm Email</label><br>
<input id="user_email_confirmation" name="user[email_confirmation]" size="30" type="text"></p>
<p><input id="user_submit" name="commit" value="Submit" type="submit"></p>
</form>
rendered HTML when the user has errors - notice the end form tag
is found after the error explanation box, which then renders the
Submit tag not working properly on the page since it is outside of
the form tag block now.
<form action="/users/update_email_ajax" class="edit_user" id="edit_user_1" method="post" onsubmit="new Ajax.Updater('email_target', '/users/update_email_ajax', {asynchronous:true, evalScripts:true, parameters:Form.serialize(this)}); return false;">
<div style="margin: 0pt; padding: 0pt;"><input name="_method" value="put" type="hidden"><input name="authenticity_token" value="bcedBLfJCarXCWIGJ85gjGAaO5Q7hUKinqowlWou2iI=" type="hidden"></div><p></p>
<div class="errorExplanation" id="errorExplanation"><h2>1 error prohibited this user from being saved</h2><p>There were problems with the following fields:</p><ul><li>Email address is invalid. Ex: example@examples.com</li></ul></div>
</form>
<p><label for="email">Email</label><br>
</p><div class="fieldWithErrors"><input id="user_email" name="user[email]" size="30" value="phonk64gmail.com" type="text"></div>
<p><label for="email_confirmation">Confirm Email</label><br>
<input id="user_email_confirmation" name="user[email_confirmation]" size="30" value="" type="text"></p>
<p><input id="user_submit" name="commit" value="Submit" type="submit"></p>
</span></code>
Has anyone seen this? An easy workaround is to just not use AJAX and use form_for since it behaves properly, but of course I'd rather use AJAX :)
Comments and changes to this ticket
-
Daniel Rice September 4th, 2009 @ 03:35 AM
I have been able to determine this to be a bug in Firefox 3.5, not a bug in rails. See attached for the rendered HTML in Safari 4 which works perfectly and places the tag in the correct location.
-
Mike Riley July 29th, 2010 @ 02:48 PM
- State changed from new to resolved
- Importance changed from to
Hello Daniel,
Thanks for the update on this. I am marking this ticket as resolved. If there is any further information or issues with this, let us know so we can investigate.
Mike Riley
Create your profile
Help contribute to this project by taking a few moments to create your personal profile. Create your profile »
<h2 style="font-size: 14px">Tickets have moved to Github</h2>
The new ticket tracker is available at <a href="https://github.com/rails/rails/issues">https://github.com/rails/rails/issues</a>