observe_field

I have the following in my view:

<%= observe_field 'guarantee_status', :url => {:controller => 'testcontroller', :action => 'change_status'}, :with => 'value' %> <div id="balance_div" style="display:none">   <p>     <b>Remaining Balance</b>     <%= f.text_field :balance %>   </p> </div>

No when I first load this page, I need the change_status method hit on my controller. It's only hit if I actually change the "guarantee_status" field.

here's the method in my controller:

def change_status     if request.xhr?       render :update do |page|         if params[:value].blank? || params[:value] == 'Due'           page[:balance_div].hide         else           page[:balance_div].show         end       end     end   end

Allen Walker wrote:

I have the following in my view:

<%= observe_field 'guarantee_status', :url => {:controller => 'testcontroller', :action => 'change_status'}, :with => 'value' %> <div id="balance_div" style="display:none">   <p>     <b>Remaining Balance</b>     <%= f.text_field :balance %>   </p> </div>

No when I first load this page, I need the change_status method hit on my controller. It's only hit if I actually change the "guarantee_status" field.

here's the method in my controller:

def change_status     if request.xhr?       render :update do |page|         if params[:value].blank? || params[:value] == 'Due'           page[:balance_div].hide         else           page[:balance_div].show         end       end     end   end

One way is to add the following below balance_div:

<%= javascript_tag "$('guarantee_status').onchange()" %>

Another would be to only render display:none into the div tag if the condition is met.

The first method is preferred because when a page is refreshed in Firefox it does not reset form entries, but your app is still called as a simple GET, so the div may be inappropriately made visible or hidden.

Allen Walker wrote:

Doesn't work. I tried putting the javascript_tag right after the div and outside the form itself. I understand the logic in the code but for some reason the onchange event is not causing the "change_status" to get fired. I even checked the development.log and change_status is not getting called.

OK, try this:

<%= javascript_onload "$('guarantee_status').onchange()" %>

using the following helper:

   def javascript_onload(js)      javascript_tag <<-END        olf = function() { #{js} };        if (document.addEventListener)          window.addEventListener("load", olf, false);        else          window.attachEvent("onload", olf);      END    end

No such luck again. Here's the generated HTML:

    <b>Status</b><br /> <select id="guarantee_status" name="guarantee[status]"><option value="Due">Due</option> <option value="Paid" selected="selected">In Progress</option></select>   </p>

<script type="text/javascript"> //<![CDATA[ new Form.Element.EventObserver('guarantee_status', function(element, value) {new Ajax.Request('/licensors/change_status', {asynchronous:true, evalScripts:true, parameters:'value=' + encodeURIComponent(value)})}) //]]> </script> <div id="balance_div" style="display:none">   <p>     <b>Remaining Balance</b><br />     <input id="guarantee_balance" name="guarantee[balance]" size="30" type="text" value="2430.0000" />   </p> </div>

<script type="text/javascript"> //<![CDATA[        olf = function() { $('guarantee_status').onchange() };        if (document.addEventListener)          window.addEventListener("load", olf, false);        else          window.attachEvent("onload", olf);

//]]>

</script>

Mark Reginald James wrote:

Allen Walker wrote:

No such luck again. Here's the generated HTML:

Looking at the Prototype code, observe only calls the function if the value has actually changed.

So one way would be to move the observer inline:

:onchange => remote_function(:url => ...)

Or in this case it would be faster & simpler to keep everything client-side:

function display_balance(gstatus) {    if (gstatus == '' || gstatus == 'Due')      $("balance_div").hide();     else       $("balance_div").show(); }

:onchange => 'display_balance(value)'

<%= javascript_tag "$('guarantee_status').onchange()" %>

Mark Reginald James wrote:

Allen Walker wrote:

No such luck again. Here's the generated HTML:

Looking at the Prototype code, observe only calls the function if the value has actually changed.

So one way would be to move the observer inline:

:onchange => remote_function(:url => ...)

Or in this case it would be faster & simpler to keep everything client-side:

function display_balance(gstatus) {    if (gstatus == '' || gstatus == 'Due')      $("balance_div").hide();     else       $("balance_div").show(); }

:onchange => 'display_balance(value)'

<%= javascript_tag "$('guarantee_status').onchange()" %>

-- Rails Wheels - Find Plugins, List & Sell Plugins - http://railswheels.com

Trying the client side I did:

<%= f.select :status, [['Due','Due'],['In Progress','Paid']], {}, {:onchange => 'display_balance(value)'} %>

and played in application.js:

function display_balance(gstatus) {     if (gstatus == '' || gstatus == 'Due')         $("balance_div").hide();     else         $("balance_div").show(); }

Generated HTML:

<select id="guarantee_status" name="guarantee[status]" onchange="display_balance(value)"><option value="Due">Due</option> <option value="Paid" selected="selected">In Progress</option></select>   </p>

<div id="balance_div" style="display:none">   <p>     <b>Remaining Balance</b> )<br />     <input id="guarantee_balance" name="guarantee[balance]" size="30" type="text" value="2430.0000" />   </p> </div>

It doesn't work. I'm sure I'm missing something. I'm pretty unskilled of javascript

Allen Walker wrote:

Trying the client side I did:

<%= f.select :status, [['Due','Due'],['In Progress','Paid']], {}, {:onchange => 'display_balance(value)'} %>

and played in application.js:

function display_balance(gstatus) {     if (gstatus == '' || gstatus == 'Due')         $("balance_div").hide();     else         $("balance_div").show(); }

Generated HTML:

<select id="guarantee_status" name="guarantee[status]" onchange="display_balance(value)"><option value="Due">Due</option> <option value="Paid" selected="selected">In Progress</option></select>   </p>

<div id="balance_div" style="display:none">   <p>     <b>Remaining Balance</b> )<br />     <input id="guarantee_balance" name="guarantee[balance]" size="30" type="text" value="2430.0000" />   </p> </div>

It doesn't work. I'm sure I'm missing something. I'm pretty unskilled of javascript

Allen, that should work for normal select changes, but the initial state won't be set unless you add a javascript_tag that calls either the onchange function or the display_balance function directly.

I'd recommend that you install a Javascript debugger like Firebug to work out what's going on.

Even if I do:

<%= javascript_tag "alert('Hello')" %>

Nothing happens. So it doesn't seem to be executing this javascript after the dom loads in the brower (so I still can't set the initial state)

Mark Reginald James wrote:

Ok this worked:

<%= javascript_tag "document.getElementById('guarantee_status').onchange()" %>

Allen Walker wrote:

Allen Walker wrote:

Ok this worked:

<%= javascript_tag "document.getElementById('guarantee_status').onchange()" %>

That suggests your problem was absence of the Prototype library, meaning that your AJAX call wouldn't have worked either. Do you have something like:

<%= javascript_include_tag "prototype", "application" %>

?

Mark Reginald James wrote:

Allen Walker wrote:

Ok this worked:

<%= javascript_tag "document.getElementById('guarantee_status').onchange()" %>

That suggests your problem was absence of the Prototype library, meaning that your AJAX call wouldn't have worked either. Do you have something like:

<%= javascript_include_tag "prototype", "application" %>

?

-- Rails Wheels - Find Plugins, List & Sell Plugins - http://railswheels.com

Yeah something was wrong with my

<%= javascript_include_tag :defaults %>

Got that fixed.

Regardless I had to go pure client side to get to onchange to fire properly. But I did get it to work.

Thanks for your help