Rails Against The Machine

Just a mind dump. Why are you even reading this?

Wednesday, 16 January 2008

 

Display Validation Errors For Your Ajaxified Form

Ajax login/sign up form:

<% unless logged_in? %>
<%= error_messages_for :user %>

<div id="login_div">
<h1>Login or sign up</h1>

<%= error_div_for user %>
<% remote_form_for :user, :url => {:controller => :account, :action => :signup}, :update => { :success => "login_div", :failure => "login_div" } do |f| -%>
<p><label for="email">Email</label><br/>
<%= f.text_field :email %></p>

<p><label for="password">Password</label><br/>
<%= f.password_field :password %></p>


<p><label for="password_confirmation">Confirm Password</label><br/>
<%= f.password_field :password_confirmation %></p>

<p><%= submit_tag 'Sign up' %></p>

<% end -%>
</div>

<%= observe_field(:user_password, :url =>{ :controller => :account, :action => :autofill }, :frequency => 0.5, :with => "'email='+ escape($('user_email').value) + '&password=' + escape($('user_password').value)") %>
<% end %>


When the user types their email and the correct password. They are automatically logged in. This is accomplished by an observe field.
<%= observe_field(:user_password, :url =>{ :controller => :account, :action => :autofill }, :frequency => 0.5, :with => "'email='+ escape($('user_email').value) + '&password=' + escape($('user_password').value)") %>


If they click sign up they are signed up via ajax without whole page refresh using remote form for.
<% remote_form_for :user, :url => {:controller => :account, :action => :signup}, :update => { :success => "login_div", :failure => "login_div" } do |f| -%>


The only issue is validation. This blog shows you how to write a custom rjs.erb file to write validation errors back using the ajax event. But honestly why bother! all you need is to use the :failure callback.

:update => { :success => "login_div", :failure => "login_div" }


Ok now the controller method.

  def signup
@user = User.new(params[:user])
return unless request.post?
@user.save!
self.current_user = @user
if request.xml_http_request?
render :action => 'welcome.html.erb', :layout =>false
end
redirect_back_or_default(:controller => '/account', :action => 'index')
flash[:notice] = "Thanks for signing up!"
rescue ActiveRecord::RecordInvalid
if request.xml_http_request?
render :action => 'signup', :layout =>false
end
end


Only thing notable here is the
request.xml_http_request?
method which tells you if the call was a ajax request.

But we can clean this up by defining ajax request as a custom mime type.

  before_filter :adjust_format_for_ajax

def adjust_format_for_ajax
request.format = :ajax if request.xml_http_request?
end


    respond_to do |format|
format.html do
flash[:notice] = "Thanks for signing up!"
redirect_back_or_default(:controller => 'account', :action => 'index')
end
format.ajax do
render :template=>'shared/welcome.html.erb', :layout =>false
return
end
end


Its no shorter but it is neater, especially if you are handling different mime types anyway

Comments: Post a Comment

Subscribe to Post Comments [Atom]





<< Home

Archives

July 2007   August 2007   September 2007   December 2007   January 2008   February 2008   March 2008   April 2008   June 2008   July 2008   August 2008   October 2008   November 2008   January 2009  

This page is powered by Blogger. Isn't yours?

Subscribe to Comments [Atom]