Button_to execute javascript function

Ok, I know this has to be EXTREMELY simple, so please excuse the
ignorance.

However, I want the button_to method to execute some external javascript
function I have predefined called “addRow()” when the user clicks the
button.

I see all these examples of button_to … :confirm => “Are you sure?”,
but
that is the ONLY example I see for button_to html_options.

I attempted this button_to …:onclick => “addRow()”, but it appends
this
to the url ?onclick=addRow().

Anyone? Anyone?

Show me just how dumb I am this afternoon.
It won’t hurt my feelings in the least.

Thanks in advance.
~d

On 22.11.2005, at 21.37, Damon H. wrote:

I attempted this button_to …:onclick => “addRow()”, but it
appends this to the url ?onclick=addRow().

You have the onclick attribute in the url options hash. Try to divide
it up to two hashes and you should be fine.

//jarkko

Thanks for the replies Jarkko and Torben.
I can now successfully insert rows into my table upon a button click.
However, the next question I have is, can I insert rails code as TD
elements
into the table.

For example, I need to insert the following two elements in the TR I am
inserting:

<%= text_field(“purchase_order_detail”, “quantity”, “size”=>5) %>
<%= text_field_with_auto_complete :product, :product_name %>

However, whenever I attemp to insert those, I get just the TEXT, not the
functionality of the methods.

I am using the following to insert the row into the table:

new Insertion.Bottom(‘po_products’, completeRow);

Obviously, the po_products is my table id, and the complete Row is the
entire string to insert into the HTML.

Thoughts???

Thanks for all the help:

~damon

The text_field et al. commands just return their respective HTML.
That’s not working because your completeRow is not processed again by
ERb before hitting the browser. You may have luck with:

completeRow << text_field(…)

new InsertionBottom(‘po_products’, completeRow)

if the code in question is in your view. Otherwise you may have to
include ActionView::Helpers::FormHelper and
ActionView::Helpers::JavaScriptMacrosHelper so you get text_field and
text_field_with_auto_complete.

Another alternative would be to run your built template through ERb
again… that might work.

Disclaimer: I haven’t tested this code.

Brad E.
866-EDIGERS

Thanks for the suggestions Brad.

Looks like the easiest way would be to run the built template through
ERb
again (assuming it works).
How would one go about running a dynamically created page back through
ERb
and not lose the previously added row for the table (in my example at
least)?

Thanks,
~d

From glancing at the API docs (Peak Obsession
ActionController/Base.html#M000172), it looks like this might work:

current_row = render_to_string(:inline => current_row)

The render_to_string gives you a string as a result and the :inline
tells it you’re passing in a string rather than a controller /
action / id triple. Thus only complete_row is re-processed with ERb.
I think you’ll have to use render_to_string in your controller,
though, not your view.

Not sure if this is what you’re trying to accomplish (I missed the
beginning of this thread), but it might work.


Brad E.
866-EDIGERS

Brad, thanks again for the response.

However, here is how I am executing the call that generates the
completeRow:

And the javascript addRow in my view looks like:

function addRow()
{
var insertedRow1 = ‘<td rowspan=“2”><%=
text_field(“purchase_order_detail”, “quantity”, “size”=>5)
%>’;
var insertedRow2 = ‘<td rowspan=“2”><%=
text_field_with_auto_complete :product, :product_name %>’;
var insertedRow3 = ‘<td rowspan=“2”><input type=“text”
id=“description” size=“40”>’;
var insertedRow4 = ‘

<input type=“text” id=“weight”
size=“10”>’;
var insertedRow5 = ‘<input type=“text” id=“buy_price”
size=“10”>’;
var insertedRow6 = ‘<input type=“text” id=“sell_price”
size=“10”>’;
var insertedRow7 = ' <input type=“text”
id=“weight2”
size=“10”>    
';
  var completeRow  = insertedRow1 + insertedRow2 + insertedRow3 +

insertedRow4 + insertedRow5 + insertedRow6 + insertedRow7;
alert(completeRow);

    new Insertion.Bottom('po_products', completeRow);
}

So you see, the completeRow is created and then passed into the
Insertion.Bottom call in javascript.
Therefore, I don’t have th ability to run it through the
render_to_string,
unless there is some way to take the return of the addRow() and pass
THAT
through the render_to_string in the same step and the onClick of the
input.

Thoughts?

There was some talk about a similar application previously on the list.
The
tread can be found at Send list of variable size - Rails - Ruby-Forum

This might give you some ideas on how to achieve what your looking for.

Cheers

On 23.11.2005, at 5.08, Damon H. wrote:

function addRow()
size=“10”>’;
new Insertion.Bottom(‘po_products’, completeRow);
}

So you see, the completeRow is created and then passed into the
Insertion.Bottom call in javascript.
Therefore, I don’t have th ability to run it through the
render_to_string, unless there is some way to take the return of
the addRow() and pass THAT through the render_to_string in the same
step and the onClick of the input.

Thoughts?

The problem is that you are trying to call Rails (=backend) methods
on the client side. That is not possible for obvious reasons. If
possible, you can make those methods run beforehand so the javascript
will not try to insert a ruby method call but the result of that
call. From a short look I don’t see why your code couldn’t be
executed beforehand.

However, if you depend on something that you won’t know before the js
call, you need to use AJAX if you need something depending on backend
calls. You could easily use AJAX for the kind of thing you’re trying
to accomplish.

//jarkko

Hi mdamonhill,

can u tell me how u have did that? i m not getting what Jarkko wants to
say.
I also want to execute a javascript function on onclick of button_to

Pls help me, it’s urgent

Regards,
Pratiksha

mdamonhill wrote:

Thanks for the replies Jarkko and Torben.
I can now successfully insert rows into my table upon a button click.
However, the next question I have is, can I insert rails code as TD
elements
into the table.

For example, I need to insert the following two elements in the TR I am
inserting:

<%= text_field(“purchase_order_detail”, “quantity”, “size”=>5) %>
<%= text_field_with_auto_complete :product, :product_name %>

However, whenever I attemp to insert those, I get just the TEXT, not the
functionality of the methods.

I am using the following to insert the row into the table:

new Insertion.Bottom(‘po_products’, completeRow);

Obviously, the po_products is my table id, and the complete Row is the
entire string to insert into the HTML.

Thoughts???

Thanks for all the help:

~damon

I also want to execute a javascript function on onclick of button_to

Use “button_to_function”

Rodrigo

Sorry - I completely misunderstood you Damon. I thought you were
giving me ERb when you were actually using JS. This is what happens
when you miss the first half of the thread! Sorry for chasing the
rabbit trail.

Like Jarkko implied, the helper methods are just an easier method for
creating static HTML. It looks like your HTML is going to be static
(not dependent on server-side info)–thus, the HTML generated will be
the same whenever that button is clicked; it would just add a new row
to the PO with the same HTML.

In that case, the best option would probably be to throw all that ERb
code in a view (temporarily), render it, do a “View Source” on the
rendered page, and throw the static HTML in your Javascript code.
Thus you would have something like this:

var completeRow = '

<input type=“text”
name="purchase_order_detail[quantity]
id=“purchase_order_detail_quantity” size=“5” /> … ';

However, something like what I recommended earlier might work (though
it might violate MVC separation):

–(controller)
@completeRow = render_to_string(:inline => '<td…><%= text_field… %

')

–(view)
function addRow {
var completeRow = ‘<%= @completeRow %>’;
new Insertion.Bottom(…);
}

That way would give you the advantage of still having the ERb code in
your codebase, but it throws views in your controller, which is kind
of ugly.

Jarkko is right, though–with JS you’re dealing with client-side code
only. If your added row is dependent on runtime data, you’ll need to
do an AJAX call or something similar. But Prototype makes that
easy… you’d just need an AJAX.Updater.

On another note… do you run into problems having the same HTML ID
repeated on multiple products? I’m not quite familiar with
Insertion.Bottom, but it looks like every Weight field, Description
field, and the like would have the same ID. Technically that’s
illegal under XHTML, but I don’t know if it will actually cause
problems. I remember some thread on the Rails list about ways to deal
with this, but I’m not sure what the outcome was.

Hope this helps!

Brad E.
866-EDIGERS

hi,
If I call a javascript function on clicking a button in RoR, it is
appending it to the url. I am not understanding what you meant by " Try
to divide it up to two hashes ". Please guide me how to solve this.

Thanks.

Jarkko L. wrote:

On 22.11.2005, at 21.37, Damon H. wrote:

I attempted this button_to …:onclick => “addRow()”, but it
appends this to the url ?onclick=addRow().

You have the onclick attribute in the url options hash. Try to divide
it up to two hashes and you should be fine.

//jarkko