3.5.
Buttons
Notice something about the previous
form_to_remote
example: in the generated HTML, the only difference between a regular form and an Ajaxified form is the addition of an
onsubmit
attributethe rest of the form, including the submit buttons, are
vanilla
HTML. Where
form_to_remote
creates a special, Ajaxified form with normal submit buttons,
submit_to_remote
does the
opposite
: it creates a special submit button for a plain form. For example:
<%= form_tag :action => 'reverse' %>
<p>Text to reverse: <%= text_field_tag 'text_to_reverse' %></p>
<p id="reversed2"></p>
<p><%= submit_to_remote 'submit', 'Reverse!',
:update => 'reversed2',
:url => { :action => 'reverse' } %></p>
<%= end_form_tag %>
The first parameter to
submit_to_remote
determines the
name
attribute on the button, and the second sets the value, which appears in the button. When you click the button, the end result is exactly the same as before. However, the difference is that the form can be submitted both via Ajax or non-Ajax
methods
. Consider this variation with two submit buttons:
<%= form_tag :action => 'reverse' %>
<p>Text to reverse: <%= text_field_tag 'text_to_reverse' %></p>
<p id="reversed"></p>
<p><%= submit_to_remote 'submit', 'Submit via Ajax',
:update => 'reversed',
:url => { :action => 'reverse' } %></p>
<p><%= submit_tag "Submit non-Ajax" %></p>
<%= end_form_tag %>
In practice, a common application for
submit_to_remote
would be checking a form for validity before actually submitting it for creation. For example, during a sign-up process you could allow the
user
to check whether a
chosen
username is available.
3.5.1. Buttons for Arbitrary Functions
The
button_to_function
helper creates a button that triggers a JavaScript function. Just like
link_to_function
, the first argument becomes the text inside the button, and the second argument is the JavaScript to be evaluated. For example:
<%= button_to_function "Greet", "alert('Hello world!')" %>
To create a button that initiates an Ajax request, you can combine
button_to_function
with
remote_function
. That helper takes the same arguments as
link_to_remote
and returns the JavaScript needed for a remote function.
<%= button_to_function "Check Time",
remote_function(:update => "current_time",
:url => { :action => 'get_time' }) %>
3.5.2. Custom Helpers
Given the existence of
link_to_function
and
link_to_remote
, you would expect that
button_to_function
would have a corresponding
button_to_remote
but there is no such
beast
. Fortunately, it's easy to implement, and it gives us a good reason to examine how to implement custom helpers. Because we're working in the
chapter3
controller, custom helpers can be defined in either
app/helpers/chapter3_helper.rb
or
app/helpers/application_helper.rb
they'll be accessible from our templates either way. For the new
button_to_remote
helper, we want to
mimic
the API of
link_to_remote
: the first parameter should be the button label, and the second should be a hash of options that's passed to
remote_function
. Here's an implementation:
def button_to_remote name, options = {}
button_to_function name, remote_function(options)
end
As you can see, this is little more than a wrapper for
button_to_function
, but it allows us to have the same familiar API as
link_to_remote
:
<%= button_to_remote "Get Time Now",
:update => "current_time",
:url => { :action => 'get_time' } %>
Custom helpers are an invaluable tool for keeping templates clean and
maintainable
. Any time you find yourself creating complicated logic or repeating yourself in the view, consider extracting the job to a helper.
|