Observe_field


#1

I have the following in my view:

<%= observe_field ‘guarantee_status’, :url => {:controller =>
‘testcontroller’, :action => ‘change_status’}, :with => ‘value’ %>

Remaining Balance <%= f.text_field :balance %>

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


#2

Allen W. wrote:

      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.


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


#3

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.

Mark Reginald J. wrote:

Allen W. wrote:

      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.


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


#4

Allen W. 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


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


#5

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

<b>Status</b><br />

Due

In Progress

Mark Reginald J. wrote:

Allen W. 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


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


#6

Allen W. 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


#7

Allen W. wrote:

else

Remaining Balance )

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.


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


#8

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 J. wrote:

Allen W. wrote:

else

Remaining Balance )

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.


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


#9

Mark Reginald J. wrote:

Allen W. 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:

Due

In Progress

Remaining Balance )

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


#10

Allen W. 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


#11

Mark Reginald J. wrote:

Allen W. 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


#12

Ok this worked:

<%= javascript_tag
“document.getElementById(‘guarantee_status’).onchange()” %>

Allen W. wrote:

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)