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>

or

<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

Walter Many thanks I have cracked it.

$('search').up('form').submit()

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

Don

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%>

    </table>

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>