Observe_filed Rails 3.

I am trying to accomplish an observe_field in rails 3. In rails 2.3.5 I have :- <%= observe_field 'query', :frequency => 2,                 :update => "search_results",                 :url => {:controller => params[:area], :action => "search",:area => params[:area]},                 :method=>:get,                 :with => "query" %> Which works fine, checking my text_field_tag "query" and updating my "search_results" every two seconds. This is what I am trying to simulate using prototype.

At the moment I have in a basic application in Rails 3:-

<script> document.observe("dom:loaded", function() { $('search').observe('change', respondToChange()); }); </script>


<script> document.observe("dom:loaded", function() { new Form.Element.Observer(   'search',   1,   respondToChange() ) }); </script>

both of which triggers the respondToChange function when the page loads, despite the "dom:loaded", and then does not observes anymore.

Does anyone have any idea of how I might obtain the repeated observer checks on my "search" text_field_tag.

With thanks to "themiddleman" and "agnaki" somewhere out there in the ether, I have solved the problem:-

Use respondToChange not respondToChange()

As the parensthesis () execute the function wheras without () it references it.

$('search').observe('change', respondToChange()); only triggers when the focus is moved away from the text_field.

new Form.Element.Observer(   'search',   1,   respondToChange() ) }); ................................repeatedly checks the text_field and call the function every 1 second if there is a any change.

I now only have one small problem. How to call the "form_tag" from the function. Anyone have any ideas.

You might try this.up('form') inside your function, as inside the anonymous function, this is set to the 'search' field. If that doesn't work, you can always do it long-hand with myForm = $('search').up('form').


Walter Many thanks I have cracked it.


I will post the whole code later. I owe you a drink. Contact me on donsgarden.co.uk


Here is my full code if anyone is interested. This code Observes the text_field_tag "search" every 2 seconds and if there is a change in the value it triggers a search automatically. The submit button can now be done away with I think. I might add ":autocomplete => "off", :onKeyPress=>"return disableEnterKey(event)") %>" to the text_field_tag to disable the return key, not sure.

In my index.html.erb I have:-

    <h1>Listing homepages</h1>     <div id = "testsearch">        <%=render :partial => 'homepage'%>     </div>     <%= form_tag homepages_path, :method => 'get', :remote => true do %>     <%= label_tag(:search, "Search for:") %>     <%= text_field_tag :search, params[:search]%>     <%= submit_tag "search", :name => nil %>     <%end%>

    <%= set_focus_to_id 'search' %> // I have a helper "set_focus_to_id"

    <script>     document.observe("dom:loaded", function() { // ensures the page is loaded first     new Form.Element.Observer( // Observes the text_field_tag every 2 seconds       'search',       2,       respondToChange //refrences the function in the Layout <head>     ) // on a change in search calls respondToChange     });     </script>     <br />     <%= link_to 'New Homepage', new_homepage_path %>

In my application Layout head I have:_

    <script>     function respondToChange() {     $('search').up('form').submit() // The ".up finds the form in the DOM"     };     </script

In my controller#index I have:-

     def index       @homepages = Homepage.search(params[:search]) //".search method is in the Model"       respond_to do |format|        format.html # index.html.erb        format.xml { render :xml => @homepages }        format.js      end     end

In my Model I have:-

    def self.search(search_item)        if search_item         self.where('section LIKE ?', "%#{search_item}%") //Handles the ajax call.        else         self.all //Handles the html call on startup.        end     end

In the helper I have:-

    def set_focus_to_id(id)       javascript_tag("$('#{id}').focus()");     end

In the "_homepage" partial I have:-

    <table>       <tr>         <th>Id</th>         <th>Section</th>         <th>Link</th>         <th>Description</th>         <th></th>         <th></th>         <th></th>      </tr>

    <% for homepage in @homepages %>

      <tr>         <td><%= homepage.id %></td>         <td><%= homepage.section %></td>         <td><%= homepage.link %></td>         <td><%= homepage.description %></td>         <td><%= link_to 'Show', homepage %></td>         <td><%= link_to 'Edit', edit_homepage_path(homepage) %></td>         <td><%= link_to 'Destroy', homepage, :confirm => 'Are you sure?', :method => :delete %></td>       </tr>     <%end%>


And in the index.js.erb I have:-

    $('testsearch').update("<%= escape_javascript(render :partial => 'homepage') %>");

If anyone has any comments on how I could improve this please contact me or say so.

Thanks for posting…I’ve been trying to figure out how to do the same thing.

I just noticed that the form_tag does an ajax call when a submit button is pressed, but when it is submitted via a Form.Element.Observer it goes by html.

Does anyone know how can I force the Form.element.Observer to send an ajax call instead of an html call.

I think I have now solved the problem of doing an ajax call via programming. I will have to check it out in all types of browsers, but at the moment it is working in Firefox and Safari. I have now also moved both javascript "document.observe("dom:loaded" and the function it calls "respondToChange()" to the application head with content_for. All other files remain the same.

In my index.html.erb I now have:-

<h1>Listing homepages</h1> <div id = "testsearch">      <%=render :partial => 'homepage'%> </div> <%= form_tag homepages_path, :method => 'get', :remote => true do %>     <%= label_tag(:search, "Search for:") %> <%= text_field_tag :search, params[:search]%> <%= submit_tag "search", :name => nil %> <%end%>

<%= set_focus_to_id 'search' %>

<% content_for :search_javascript do %>

function respondToChange() {

    var pars = 'search=' + $('search').getValue()

        new Ajax.Request("<%= homepages_path %>" ,{       method: 'get',       parameters: pars     }); };

document.observe("dom:loaded", function() {     new Form.Element.Observer(       'search',       2,       respondToChange

    ) });

<% end %>

<br /> <%= link_to 'New Homepage', new_homepage_path %>

In my application layout file I now have:- <!DOCTYPE html> <html> <head>   <meta http-equiv="content-type" content="text/html;charset=UTF-8" />   <title>GardenR3</title>   <%= stylesheet_link_tag :all %>   <%= javascript_include_tag :defaults %>   <%= csrf_meta_tag %>

<script> <%= yield :search_javascript %> </script>

</head> <body>

<%= yield %>

</body> </html>