views:

154

answers:

2

I already have a form with normal HTTP post. Now, I want to rewrite this form usign jQuery Ajax request. Here is what I have:

register_user.html.erb

<%= form_tag :action=> "register_user" %>
                               <label for="user_id_1">user_id_1:</label><br/>
                               <%= text_field "user", "user_id_1", :size => 20 %> 
                               <label for="user_id_2">user_id_2:</label><br/>
                               <%= text_field "user", "user_id_2", :size => 20 %>
<%= submit_tag "Submit" %>

users_controller.rb

def register_user

   #do something

end

So, I was trying to follow this tutorial, but was not able to follow the same instructions in my app. So any suggestions? How can I make jQuery Ajax call using the above form?

AFAIK, the application.js (file included in register_user.html.rb's head) file will be

jQuery.ajaxSetup({ 
  'beforeSend': function(xhr) {xhr.setRequestHeader("Accept", "text/javascript")}
})

jQuery.fn.submitWithAjax = function() {
  this.submit(function() {
    $.post(this.action, $(this).serialize(), null, "script");
    return false;
  })
  return this;
};

$(document).ready(function() {
  $("#new_review").submitWithAjax(); #WHAT SHOULD REPLACE #new_review?
})

But, how can I associate the submit action to the form? I am new to JS, jQuery and Rails.

UPDATE 1

Rails 2.3.8

UPDATE 2

<%= form_tag :action=> "register_user" , :html => {:id => "register_user" }%>
  1. The request does not go in the jQuery.fn.submitWithAjax = function() { } method.

  2. How can I display the @final_value data on the same page?

For now, this is my code to display the value (in register_user.html.erb):

    <%=
    if @final_value != nil
        "<h2>The Output is " + @final_value.to_s</h2>" + 
    end
     %>

Thanks for the awesome help guys!

+1  A: 

Give your form an ID, like this:

<%= form_tag :action=> "register_user", :html => {:id => "form_name" } %>

and then in your application.js, you replace #new_review with the form ID:

$(document).ready(function() {
  $("#form_name").submitWithAjax();
})

[UPDATE: the view]

You should add a file, called register_user.js.erb, that should contain the javascript needed to render what you want to show. So this javascript will be executed and will change the page. And in the javascript you use the view you now have.

So you should something like:

!= "$('#placeholder').replaceWith('#{escape_javascript(render :partial => 'render_user')}')"

To make this work, you should have some html element, like a DIV with id=placeholder (choose an appropriate name for you, of course).

nathanvda
It didn't work :(
zengr
do I need to rename register_user.html.erb to register_user.js.erb?
zengr
Yes indeed. I updated my answer.
nathanvda
+1  A: 

Hi,

Are you on rails 3? Rails3 supports unobtrusive javascript (UJS). Look at the file public/javascripts/rails.js

How does it work?

To create a remote form, do this:

<%= form_tag :action=> "register_user", :remote => true %>

this adds a data-remote attribute to your form.

Now the rails-built-in UJS hooks in and does the onsubmit thing for you. It fires events like:

ajax:before, ajax:complete, ajax:success, ajax:failure, ajax:after

Rails uses prototype and not jQuery by default, so you could (don't have to) replace prototype by jQuery. Read http://www.railsinside.com/tips/451-howto-unobtrusive-javascript-with-rails-3.html

The important part now is, you can catch these events on your form! Give your form an id to identify it:

<%= form_tag :action=> "register_user", :remote => true, :html => { :id => 'myform' } %>

Now hook the events (with jQuery) like this:

jQuery(document).ready(function() {
    jQuery('#myform').bind('ajax:complete', '', function(request) {
        alert("I got: " + request.responseText);
    });
});

you can also hook other events like ajax:failure etc.

Edit

For Rails 2.3.8 (make sure you've included the rails default js files)

Note if you want to use jquery only and drop the default included prototype library, you could use jRails (replaces prototype with jQuery): http://github.com/aaronchi/jrails

I don't know what your @final_value is, so I did a generic example:

In your view:

<h2 id="myoutput">
  <% if @final_value != nil %>
    <%= @final_value.to_s %>
  <% end %>
</h2>


<% form_remote_tag :url => { :action=> "register_user" } do %>

  <label for="user_id_1">user_id_1:</label><br/>
  <%= text_field "user", "user_id_1", :size => 20 %> 
  <label for="user_id_2">user_id_2:</label><br/>
  <%= text_field "user", "user_id_2", :size => 20 %>

  <%= submit_tag "Submit" %>

<% end %>

In your controller:

def register_user

  form_data = params['user']

  if form_data.is_a?(Hash)
    @final_value = form_data['user_id_1']
  end

  respond_to do |format|
    format.html
    format.js do

      render :update do |page|
        page.replace_html 'myoutput', @final_value
        page.visual_effect :highlight, 'myoutput'
      end

    end
end
sled
I have Rails 2.3..8
zengr
I've added an example for Rails 2.3.8
sled