Ruby on Rails: defaults helpers onchange options_for_select Rails select select_tag to_sym
by bseanvt
2 comments
Rails Select Tag and Onchange Event Calling a Remote Function with Default Option Selected
Here is a little code snippet that will fire off a request to update_client_path when you change the select field. This stands alone, rather than being apart of a larger form. The Client::CATEGORY argument is a hash, which I populated manually in my Client.rb model. It is something like this
CATEGORY = {:lead => "Prospective clients", :past => "Previous clients..."}
In my view I have
<%= select_tag "client_category",
options_for_select(Client::CATEGORY.keys, @client.category.to_sym),
{ :onchange => remote_function( :url => update_client_path(@client), :with=>"'change_to='+this.value+''" ) } %>
One gotcha is that the select_tag, options_for_select argument expects a symbol if you’re passing in a hash as the type of the collection! It may not set the default if you provide it with a string for the second arg (which specifies which option should be set as selected).
You also need to make sure that the url update_client_path is set in your routes file and that your controller (clients_controller in this case) has the appropriate method to handle the request.
Posts Ruby on Rails: api collection helpers html select
by bseanvt
leave a comment
Collection Select Helper and OnChange Event in Rails
Given a collection of Active Record objects, you may use the collection_select helper method to produce a select form field. You need to pass in a number of arguments to the helper function.
1) object – your model object used in the collection
2) method – a valid model attribute or method
3) collection – a collection of active record model objects
4) option_value – value being set from the model for the <option value=”option_value”> html element
5) option_name – what is displayed for the user e.g., <option> option_name <
6) option – general options
7) options for the select html element
# helper and arguments...
# collection_select( model, id, collection, option_value, option_name, options, html_options)
<%= collection_select("states", "state_id",
State.participating,
"abbreviation", "name",
{:selected=> get_current_state_or_nil },
{:onchange=>"document.location='/states/'+this.value"}
) %>
#which will produce something like...
<pre id="line27"><select id="state_id" name="state[id]" onchange="document.location='/states/'+this.value">
<option value="AL">Alabama</option>
<option value="AK">Alaska</option>
<option value="AZ">Arizona</option>
<option value="AR">Arkansas</option>
</select>
Programming: block concat content_tag dry helpers html strings views wrapper yield
by bseanvt
2 comments
Yield a Block within Rails Helper Method with Multiple Content_tags Using Concat
To clean up some repetitive html coding in views, pass a block of text to a helper function which will wrap it for you the same way, each and every time. For example, I have a ‘help’ link which will toggle the display of a block of text if a link is clicked. I use this “+/- help” link throughout my application in various views. I could create a partial but this gets messy. Instead this is what I want to write in my views…
<% help do %> here is my help text... <% end %>
which will render HTML similar to this…
<a href='#' 'class='help' id='help_link_123456' onclick='some_func_to_toggle_state'>+/- help</a> <div id="help_123456"> here is my help text... </div>
In order to accomplish this you need to create a helper method. Assigning a unique id, just a random number, will help avoid collisions with the state of the toggled div if you use this more than once per page. Placing other HTML helper methods inside the concat() method allows multiple tags as well as rendering the block passed to the function in the appropriate place. It looks a little unwieldy, but works nicely.
# app/helpers/application_helper.rb
module ApplicationHelper
def help(&block)
uniqid = rand; concat( link_to_function("+/- help") do |page|
page["help_#{uniqid}"].toggle
page.visual_effect :highlight, "help_#{uniqid}"
end + content_tag(:div,:class=>"help",:id=>"help_#{uniqid}", :style=>"display:none") do
yield
end )
end
end
Ruby on Rails: 12 hour time datetime helpers initializers leading zero strftime
by bseanvt
5 comments
Rails Helper to Remove Leading Zero in 12 Hour Time Format
I can’t find a strftime() format that will output the hour without the leading zero. For instance 6:20 will be instead 06:20. This just looks a little sloppy. I created a datetime.rb intializer which will contain custom datetime formats for my application.
# RAILS_ROOT/config/initializers/datetime.rb Time::DATE_FORMATS[:date] = "%a %b %d, %Y" Time::DATE_FORMATS[:time] = "%I:%M%p" # ...
Next I set up a helper function which will string together the :date and :time formats and remove the leading zero in the hour with the .gsub method on the string.
# RAILS_ROOT/app/helpers/application_helper.rb
def fulltime(created_at)
created_at.to_s(:date)+" "+created_at.to_s(:time).gsub(/^0/,'').downcase
end
In a view I’ll just pass the timestamp to the fulltime function
fulltime(@post.created_at)
Ruby on Rails: datetime helpers time time ago in words
by bseanvt
leave a comment
Date and Time Helpers in Rails
Just for reference http://api.rubyonrails.org/classes/ActionView/Helpers/DateHelper.html#M001695
This post was created about <%= time_ago_in_words @post.created_at %> ago
Make Rails Lib Module Methods Available to Views
If you create a module in the lib/ directory of your Rails application you won’t have access to those methods in your views. If you don’t want to put those methods in a helper file, you need to add a method to your module that makes them available for you views like so…
#in lib/my_module_name.rb
module MyModuleName
def my_method_for_views
#logic...
end
def self.included(base)
base.send :helper_method, :my_method_for_views if base.respond_to? :helper_method
end
end
Programming Ruby on Rails: autosave helpers periodical prototype Rails
by bseanvt
leave a comment
Rails Prototype JS and TinyMCE Autosave
TinyMCE is a nice little WYSIWYG for text processing online. It uses iFrames and Javascript callbacks to manipulate textarea form fields. Using it with Rails can be somewhat problematic if you want to set up an observer on a field that TinyMCE is managing. The reason is that TinyMCE uses an iFrame and a callback to update the textarea before the form is submitted.
More detailed information on the TinyMCE specifics can be found at this site <a href=”http://www.crossedconnections.org/w/?p=88″>
In Rails, there is a nifty helper function called “observe_field” that will generate Javascript which listens for changes on form fields. However, because TinyMCE only updates the field after the form is submitted the contents of the textarea are not updated when you type in it. Therefore, your observe_field function is listening but doesn’t see anything new. The iFrame is a kind of buffer that will write to the textarea later.
A simple solution to this problem is to call the function that writes to the textarea. This will update the textarea and the observer_field function will notice the changes. You can use prototype “PeriodicalExecuter” to trigger a function that will contain the TinyMCE callback function. Below is the code.
script type="text/javascript" charset="utf-8"
function triggerTinyMCE(){
tinyMCE.triggerSave(true, true);
}
new PeriodicalExecuter(triggerTinyMCE, 30);
/script
<%= observe_field( :post_body,
:frequency => 1,
:update => :update_status,
:url => { :action => :update_body } ) %>
However, the only problem with this approach is that you’re kind of running two functions that do the same thing. Instead it would make more sense to get rid of the observe_field function altogether and have the PeriodicalExecuter trigger a function that makes the ajax request at the same time. This would look something like
script type="text/javascript" charset="utf-8"
function triggerTinyMCE(){
tinyMCE.triggerSave(true, true);
var content = escape($F('post_body'));
var url = "/posts/update_body";
var params = "post_body="+content;
var aRequest = new Ajax.Request(url,
{
method: 'post',
parameters: params,
onSuccess: function(data){
$("update_status").innerHTML = data.responseText;
}
});
}
new PeriodicalExecuter(triggerTinyMCE, 10);
/script


