| Module | ApplicationHelper |
| In: |
app/helpers/application_helper.rb
|
Methods added to this helper will be available to all templates in the application.
Works just like distance_of_time_in_words except that age_in_words rounds any ages over one year down to the nearest whole year to match the usual practice of referring to age only in completed years (not rounded to the nearest year)
# File app/helpers/application_helper.rb, line 401
401: def age_in_words age
402: age_in_days = age/86400
403: if age_in_days <= 365
404: distance_of_time_in_words age
405: else
406: # add 1 to age in days because this will be out by one day every now and again (depending on leap years),
407: # and it's better to be a day ahead than one behind for age
408: distance_of_time_in_words(((age_in_days + 1 ) / 365.25).to_i * 365.25 * 86400)
409: end
410: end
overwrites ActionView::Helpers::JavaScriptMacrosHelper#auto_complete_result, replaced
entry[field]
with
entry.send(field)
as this allows you to use dynamic methods which do not map exactly onto database fields.
# File app/helpers/application_helper.rb, line 26
26: def auto_complete_result(entries, field, phrase = nil)
27: return unless entries
28: items = entries.map { |entry| content_tag("li", phrase ? highlight(entry.send(field), phrase) : h(entry.send(field))) }
29: content_tag("ul", items.uniq)
30: end
Is this in rails as of 1.2??? need to test that to see if it is ok to drop this method. Overwrites ActionView::Helpers::DateHelper::distance_of_time_in_words to use years, months and weeks as well as days, hours and minutes File lib/action_view/helpers/date_helper.rb, line 24 Some of the figures will yield slightly imprecise results, but it shouldn‘t matter because that fits the expectation of a time expressed in words. (e.g. months may round a day or two earlier or later than is mathematically correct because 30.4 is the average no of days/month, not exact).
# File app/helpers/application_helper.rb, line 352
352: def distance_of_time_in_words(from_time, to_time = 0, include_seconds = false)
353:
354: # since times before 1970 are out of range we need to handle old dates differently from more recent times
355: if ( from_time.class == Date || to_time.class == Date ) &&
356: [from_time.year, to_time.year].min < 1970
357:
358: if to_time.class == Time
359: to_time = Date.new(to_time.year, to_time.month, to_time.day)
360: end
361: distance_in_seconds = ((to_time - from_time).abs).round * 86400
362: else
363: from_time = from_time.to_time if from_time.respond_to?(:to_time)
364: to_time = to_time.to_time if to_time.respond_to?(:to_time)
365: distance_in_seconds = ((to_time - from_time).abs).round
366: end
367:
368: distance_in_minutes = (distance_in_seconds/60).round
369: distance_in_days = (distance_in_seconds/86400).round
370:
371: case distance_in_days
372: when 0..1
373: case distance_in_minutes
374: when 0..1
375: return (distance_in_minutes==0) ? 'less than a minute' : '1 minute' unless include_seconds
376: case distance_in_seconds
377: when 0..5 then 'less than 5 seconds'
378: when 6..10 then 'less than 10 seconds'
379: when 11..20 then 'less than 20 seconds'
380: when 21..40 then 'half a minute'
381: when 41..59 then 'less than a minute'
382: else '1 minute'
383: end
384:
385: when 2..45 then "#{distance_in_minutes} minutes"
386: when 46..90 then 'about 1 hour'
387: when 90..1409 then "about #{(distance_in_minutes.to_f / 60.0).round} hours"
388: else '1 day'
389: end
390: when 2..11 then "#{distance_in_days} days"
391: when 12..51 then "#{(distance_in_days.to_f / 7).round} weeks"
392: when 52..335 then "#{(distance_in_days.to_f / 30.4).round} months"
393: when 336..548 then '1 year'
394: else "#{(distance_in_days.to_f / 365.25).round} years"
395: end
396: end
# File app/helpers/application_helper.rb, line 140
140: def end_edit_box
141: ' </div>
142: </div>'
143: end
# File app/helpers/application_helper.rb, line 65
65: def english_sentence_for_list words_to_singularize, words_to_append, list
66: if list.size > 1
67: words_to_append.sub!(/\sare\s?/, " are ")
68: sentence = words_to_singularize + " " + words_to_append + to_sentence(list) + "."
69: else
70: words_to_append.sub!(/\sare\s?/, " is ")
71: sentence = words_to_singularize.singularize + " " + words_to_append + to_sentence(list) + "."
72: end
73: sentence
74: end
Generates divs for all kinds of flashes.
# File app/helpers/application_helper.rb, line 10
10: def flash_all
11: flash_div :warning, :notice, :message
12: end
Takes a list of possible flash types and generates divs for them if there is any content. (Styles for the different kinds of flash are in application.css)
# File app/helpers/application_helper.rb, line 16
16: def flash_div *keys
17: keys.collect { |key| content_tag(:div, flash[key],
18: :class => "flash_#{key}") if flash[key] }.join
19: end
This helper generates the <form> tags and the input tags for an entity, by rendering its _form partial. Use the option :with_before to specify another partial to be rendered before the _form partial (commonly used to render names/_form for named entities in the new view).
e.g. In the view to create a new clan:
<%= form_and_fields_for @clan, { :with_before => 'name' } %>
In the view to edit the details an existing clan:
<!-- Something to edit names goes here: -->
<%= #blah blah change names %>
<!-- Then edit the clan details here: -->
<%= form_and_fields_for @clan %>
This helper is a big mess, it needs to have separate url_for options and html options
# File app/helpers/application_helper.rb, line 161
161: def form_and_fields_for thing, options = {}
162: options = {
163: :partial => 'form',
164: :id => thing.id
165: }.merge(options)
166:
167:
168: # If thing is specified as a symbol then don't say 'Create New Symbol'
169: thing_class = thing.is_a?(Symbol) ? thing.to_s.titlecase : thing.class.to_s
170:
171: if controller.action_name == 'new' || controller.action_name == 'create'
172: options = { :action => 'create', :submit => 'Create New ' + thing_class }.merge(options)
173: else
174: options = { :action => 'update', :submit => 'Save New Details' }.merge(options)
175: end
176: result = form_tag( { :action => options[:action], :id => options[:id] }, :id => thing_class + "_form", :multipart => options[:multipart] )
177: result << submit_tag(options[:submit]) unless controller.action_name =~ /^(new|create)$/
178: result << render( :partial => options[:with_before].pluralize + '/form' ) if options[:with_before]
179: result << render( :partial => options[:partial] )
180: result << render( :partial => options[:with_after].pluralize + '/form' ) if options[:with_after]
181: result << submit_tag(options[:submit])
182: result << '</form>'
183: end
Generates a link for a database entity according to the rails conventions and using the object‘s primary_names for the link text if the object acts_as_nameable.
# File app/helpers/application_helper.rb, line 47
47: def link_for thing, options = {}, html_options = {}
48: return nil if thing.nil?
49: options = { :controller => '/' + thing.class.to_s.underscore.pluralize,
50: :action => controller.action_name =~ /^(new|edit|create|update)$/ ? 'edit' : 'show',
51: :id => thing.id,
52: }.merge(options)
53: html_options = { :title => (truncate strip_tags(thing.description) rescue "")}.merge(html_options)
54: name = options[:name]? options[:name] : thing.primary_names rescue thing.class.to_s + " " + thing.id.to_s
55: options.delete :name # name should not be passed in the options hash
56: if options[:image] && thing.respond_to?(:images)
57: image = thing.images.first
58: name = thumbnail_for( image, :link => false ) + '<br />' + name unless image.nil?
59: options.delete :image # this setting should not be passed in the options hash
60: end
61:
62: link_to( name, options, html_options)
63: end
# File app/helpers/application_helper.rb, line 76
76: def list_names_for object
77: result = ""
78:
79: # for now it's good to get an error if object is nil but we
80: # could make this more robust by adding this line:
81: #
82: # return result if object.nil?
83:
84: all_names = object.names.find_all
85: Language.find_all.each do |language|
86: names = all_names.collect {|name| name if (name.language_id == language.id)}
87: names.delete nil
88: unless names.empty?
89: used_names_array = names.collect {|name|
90: link_for( name, {}, {:title => name.notes} ) if name.in_use?
91: }
92: used_names_array.delete nil
93: sentence = english_sentence_for_list 'The <strong>' + language.name + ' Names', '</strong> for this ' + self.controller.controller_name.singularize.to_s + ' are', used_names_array
94:
95: unused_names_array = names.collect {|name|
96: link_for( name, {}, {:title => name.notes} ) unless name.in_use?
97: }
98: unused_names_array.delete nil
99:
100: name_sentence = to_sentence(used_names_array) + "."
101: # unless unused_names_array.empty?
102: # sentence += english_sentence_for_list " ", "Some people have also called it ", unused_names_array
103: # end
104: result += '<div id="' + language.code + '_names">' + sentence + '</div>'
105: end
106: end
107:
108: result
109: end
# File app/helpers/application_helper.rb, line 5 5: def object_type 6: self.controller.controller_name.singularize 7: end
use to link HABTM objects. Use the :name option to descibe the subject (defaults to the class of the subject) Use the :as option to describe the object (defaults to class name).
Specifying a hash {:hidden => {:value => value_for_hidden_field}} will create a form with no visible inputs, this is useful for actions which require confirmation or which render multiple forms and allow the user to make a choice by submitting the form, but does not actually require input from the user.
# File app/helpers/application_helper.rb, line 285
285: def remote_form_add object, subject, options = {}
286:
287: # Set up all the variables
288: #
289: # at the moment subject_name and subject_type aren't done in the best way, it is not properly clear
290: # we should use the same system that we have for the remote_link methods to be consistent.
291: default_options = {
292: :name => subject.is_a?(String) ? subject : subject.class.to_s.underscore,
293: :as => object.class.to_s.underscore,
294: :autocomplete => true,
295: :controller => object.class.to_s.underscore.pluralize
296: }
297:
298: if options.is_a?(String)
299: subject_name = options
300: object_name = object.class.to_s.underscore
301: else
302: options = default_options.merge(options)
303: subject_name = options[:name]
304:
305: options = { :title => '<h3>Add new ' + subject_name + '</h3>',
306: :submit => 'Add New ' + subject_name.titlecase }.merge(options)
307: object_name = options[:as]
308: end
309:
310: subject_type = subject.is_a?(String) ? subject : subject_name
311:
312: # Build the HTML to return
313: result = options[:title]
314: result << form_remote_tag( :update => 'new_' + subject_type, :url => { :controller => options[:controller], :action => 'add_' + subject_type, :id => object }, :complete => evaluate_remote_response )
315: if options[:new]
316: result << render( :partial => subject_type.pluralize + '/form' ) # error_messages_for is called from partial
317: elsif options[:hidden]
318: result << error_messages_for( subject_type )
319: result << hidden_field( object_name, subject_type.pluralize, :value => options[:hidden][:value].to_s )
320: else
321: result << error_messages_for( subject_type )
322: result << '<p><label for="' + object_name + '_' + subject_name + '"> What is the new ' + subject_name + '\'s <strong>name</strong>?</label><br/>'
323: if options[:autocomplete]
324: auto_complete = options[:autocomplete].is_a?(String) ? options[:autocomplete] : subject_type.pluralize
325: result << text_field_with_auto_complete( object_name, auto_complete, :value => '' )
326: else
327: result << text_field( object_name, subject_type.pluralize, :value => '' )
328: end
329: end
330:
331: if options[:type_select]
332: result << '<p> ' + options[:type_select][:label] + ' <br />'
333: result << select( :subject, :class, options[:type_select][:options], { :include_blank => options[:type_select][:include_blank] }) + ' </p>'
334: end
335:
336: if options[:hidden_type_select]
337: result << hidden_field( subject_type, 'class', :value => options[:hidden_type_select][:value].to_s )
338: end
339:
340: result << submit_tag( options[:submit] )
341: result << '</form>'
342: end
Calls remote_form_add with the option :new => true which will create a new entity and link it in the same action Most commonly used for belongs_to/has_one relationships e.g. naming.
# File app/helpers/application_helper.rb, line 271
271: def remote_form_add_new object, subject, options = {}
272: default_options = {
273: :new => true
274: }
275: options = default_options.merge(options)
276: remote_form_add object, subject, options
277: end
This helper is used to generate an AJAX link which can be used to generate a form to link two objects together. The subject can either be a string or an entity of the right class.
e.g. in order to generate a link to produces a form to add a name to a image:
In /views/animals/edit.rhtml:
<div id="new_name">
<%= remote_link_to_add @animal, 'name' %>
</div>
Then in the contoller you need an action called new_name which essentially looks like:
def new_name
@animal = Animal.find(params[:id])
@name = Name.new
render :inline => "<%= remote_form_add_new @animal, @name %>"
end
n.b. in this case /controllers/animals_controller.rb inherits from NameableController which implements the new_name action.
Override the name of the entity using the :name option if the class does not match the name you wish to use. e.g To link a clan to a place but to call it an owner:
<%= remote_link_to_add @place, 'clan', {:name => 'owner'} %>
# File app/helpers/application_helper.rb, line 208
208: def remote_link_to_add object, subject, options = {}
209: if options.is_a?(String)
210: options = {:name => options}
211: elsif subject.is_a?(String)
212: default_name = subject
213: else
214: default_name = subject.class.to_s.underscore
215: end
216: options[:name] = default_name if options[:name].nil?
217:
218: default_options = {
219: :text => 'Add a new ' + options[:name]
220: }
221:
222: options = default_options.merge(options)
223:
224: '<p>' + link_to_remote(options[:text], :update => 'new_' + options[:name], :url =>{ :action => 'new_' + options[:name], :id => object, :class => options[:class] }) + '</p>'
225: end
Works just like remote_link_to_add but also calls a javascript function to replace the contents of a div with a rendered partial. e.g. you start with something like this in /views/places/edit.rhtml
<div id="owners">
<%= render :partial =>'owners' %>
</div>
Then when the controller updates the names it should render something like:
render :inline => "<%= remote_form_add @place, @clan, { :name => 'owner' } %>"
When this action is rendered the contents of the div with the id "owners" will have its contents replaced by the result of rendering the owners partial.
# File app/helpers/application_helper.rb, line 238
238: def remote_link_to_add_with_update object, subject, options = {}
239:
240: if options.is_a?(String)
241: options = {:name => options}
242: elsif subject.is_a?(String)
243: default_name = subject
244: else
245: default_name = subject.class.to_s.underscore
246: end
247: options[:name] = default_name if options[:name].nil?
248:
249: default_options = {
250: :partial => options[:name].pluralize,
251: :replace => options[:name].pluralize,
252: :object_as => object.class.to_s.underscore
253: }
254:
255: options = default_options.merge(options)
256:
257: replacement_function = update_element_function options[:replace], :action => :update do
258: render( :partial => options[:partial], :locals => { options[:object_as] => object })
259: end
260:
261: # these options aren't used by remote_link_to_add
262: options.delete :partial
263: options.delete :replace
264: options.delete :object_as
265:
266: result = remote_link_to_add(object, subject, options) + javascript_tag(replacement_function)
267: end
# File app/helpers/application_helper.rb, line 120
120: def start_edit_box object, group, options = {}, html_options = {}
121: object = object.to_s
122: group = group.to_s
123:
124: options = {:hide => true, :tip => 'Click inside this box to change this ' + object + '\'s ' + group + '...'}.merge(options)
125: html_defaults = options[:hide] ? {:class => 'editbox'} : {:class => 'editbox_nohide'}
126: html_options = html_defaults.merge(html_options)
127:
128: div_options = ""
129: html_options.each_pair do |key, value|; div_options += (key.to_s + '=\'' + value.to_s + '\''); end
130:
131: div_class = (options[:nohide] == true) ? 'editbox_nohide' : 'editbox'
132:
133: result = '<div id="change_' + group +'" ' + div_options +'>'
134: result += ' <h2> <span> ' + group.titlecase + ' </span> </h2>'
135: result += ' <div id="' + group + '_tip" class="showopposite">' + options[:tip] + '</div>' if options[:hide]
136: result += ' <div id="change_' + group + '_form">'
137: return result
138: end
# File app/helpers/application_helper.rb, line 111
111: def to_sentence array_of_strings
112: if array_of_strings.size < 2
113: return array_of_strings.to_s
114: end
115:
116: last_word = array_of_strings.pop
117: return array_of_strings.join(", ") + " and " + last_word.to_s
118: end
Overrides ActionView::Helpers::TextHelper::truncate, sets default length to 80 (instead of 30) and does not split in the middle of words.
# File app/helpers/application_helper.rb, line 34
34: def truncate text, length = 80, truncate_string = "..."
35: text = strip_tags(text.to_s)
36: result = text
37: if result.length > length
38: truncated_text = text.slice(0, length - 3)
39: truncated_text.sub!(/\W+\w*$/, '')
40: result = truncated_text + '...'
41: end
42: result
43: end