Topic: Observe_field in 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',
  2,
  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 using Prototype and Rails 3.

Re: Observe_field in Rails 3

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.

Re: Observe_field in Rails 3

I have cracked it.

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

I will post the whole code later.

Re: Observe_field in Rails 3

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.

Re: Observe_field in Rails 3

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.

Re: Observe_field in Rails 3

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>