Module ApplicationHelper
In: app/helpers/application_helper.rb
File:application_helper.rb
(C):Hipposoft 2008, 2009
Purpose:Standard Rails application helper.

          24-Dec-2007 (ADH): Created.

Methods

Included Modules

TrackRecordSections

Public Instance methods

Return strings ‘Yes’ or ‘No’ depending on the value of the given boolean quantity.

[Source]

    # File app/helpers/application_helper.rb, line 90
90:   def apphelp_boolean( boolean )
91:     boolean ? 'Yes' : 'No'
92:   end

Run ‘collection_select’ for the given form with the given arguments for the field name of the target object to be updated, the collection, the field from within that collection to use for the values to actually set in the target object and the field from within that collection to use for the values displayed to the user.

A sixth optional boolean parameter, defaulting to ‘true’, says whether or not the selection list should allow multiple selections (for this, pass ‘true’). The function takes care of working out how tall to make the selection list (the ‘size’ parameter) internally, which is really the only reason to call here rather than calling ‘collection_select’ directly.

Single selection items will include blank entries.

[Source]

     # File app/helpers/application_helper.rb, line 203
203:   def apphelp_collection_select( form, objfield, collection, colsetfield, colseefield, multiple = true )
204:     return form.collection_select(
205:       objfield,
206:       collection,
207:       colsetfield,
208:       colseefield,
209:       multiple ? {} : { :include_blank => 'None' },
210:       apphelp_extra_selection_args( collection, multiple )
211:     )
212:   end

Output HTML suitable as a label to show whether or not the given object is active or otherwise. The second parameter lets you override the given object and force the generation of an active (pass ‘true’) or inactive (pass ‘false’) label.

[Source]

     # File app/helpers/application_helper.rb, line 139
139:   def apphelp_commit_label( item, active = nil )
140:     active = item.active if ( active.nil? )
141:     active ? '<span class="item_active">Active</span>' :
142:              '<span class="item_inactive">Inactive</span>'
143:   end

Column formatting helper for creation dates. Pass an object with a created_at method. The value returned is used for display.

[Source]

     # File app/helpers/application_helper.rb, line 518
518:   def apphelp_created_at( obj )
519:     return apphelp_date( obj.created_at )
520:   end

Standard date formatting; pass the date to format.

[Source]

     # File app/helpers/application_helper.rb, line 173
173:   def apphelp_date( date )
174:     return date.strftime( '%Y-%m-%d %H:%M:%S' )
175:   end

Return standard extra arguments for selection lists based on a collection (its size is taken) and "multiple" flag

[Source]

     # File app/helpers/application_helper.rb, line 184
184:   def apphelp_extra_selection_args( collection, multiple )
185:     return multiple ? { :multiple => true, :size => [ collection.size, 10 ].min } : {}
186:   end

Return any flash messages using class names prefixed by "flash_", with the suffix being the key name from the flash hash. The messages are wrapped by a DIV with class ‘messages’. If there are no messages to show, an empty string is returned. Optionally pass an indent string to add at the front of any non-empty line of output. If a non-empty result is returned, note that it will be terminated by "\n\n".

[Source]

     # File app/helpers/application_helper.rb, line 101
101:   def apphelp_flash_messages( indent = '' )
102:     output = ''
103: 
104:     flash.keys.each do | key |
105:       output << "<div class='flash_#{ h( key ) }'>#{ h( flash[ key ] ) }</div>"
106:     end
107: 
108:     unless ( output.empty? )
109:       output = indent + content_tag( :div, output, { :class => 'messages' } ) + "\n\n"
110:     end
111: 
112:     return output
113:   end

Equivalent of ‘h()’, but returns ’-’ for nil or empty strings.

[Source]

    # File app/helpers/application_helper.rb, line 20
20:   def apphelp_h( value )
21:     return '-' if ( value.nil? or value.empty? )
22:     return h( value )
23:   end

Simple wrapper over ‘pluralize’ to return a string indicating a number of hours mathematically rounded to two decimal places.

[Source]

     # File app/helpers/application_helper.rb, line 148
148:   def apphelp_hours( hours )
149:     pluralize( hours.precision( 2 ), 'hour' )
150:   end

Construct a header row for a list table, returning HTML for it. The table outer definition must be included externally. To define the row contents, pass an array of hashes. Each array entry corresponds to a cell in the row, built in order of appearance in the array. The hashes can contain optional property "header_align" to override the row alignment for that cell; the property‘s value is used directly as a TH "align" value.

Each hash must include property "header_text" giving the heading text for that cell. The text is placed in the cell wrapped up in an HTML link which will re-fetch the list view with modified search parameters. To achieve this requires a second mandatory input parameter, which is the name of the model being listed, singular, lower case (e.g. "user").

A blank header cell is placed at the end of the row to appear above an actions column if the third mandatory parameter is non-nil. If nil, no room is made for an actions column.

See also apphelp_list_row.

E.g.:

  apphelp_list_header(
    [
      { :header_text => 'User name' },
      { :header_text => 'Age', :header_align => 'center' },
      { :header_text => 'E-mail address' }
    ],
    'users_path'
  )

[Source]

     # File app/helpers/application_helper.rb, line 332
332:   def apphelp_list_header( structure, model, actions_method )
333:     output = "        <tr valign=\"middle\" align=\"left\" class=\"info\">\n"
334: 
335:     structure.each_index do | index |
336:       entry      = structure[ index ]
337:       align      = entry[ :header_align ]
338:       sort_class = nil
339: 
340:       if ( params[ :sort ] == index.to_s )
341:         if ( params[ :direction ] == 'desc' )
342:           sort_class = "sorted_column_desc"
343:         else
344:           sort_class = "sorted_column_asc"
345:         end
346:       end
347: 
348:       output << "          <th"
349:       output << " class=\"#{ sort_class }\"" unless ( sort_class.nil? )
350: 
351:       if ( align.nil? )
352:         output << ">" if ( align.nil? )
353:       else
354:         output << " align=\"#{ align }\">"
355:       end
356: 
357:       if ( entry[ :value_method ] or entry[ :sort_by ] )
358:         output << apphelp_list_header_link( model, entry[ :header_text ], index )
359:       else
360:         output << entry[ :header_text ]
361:       end
362: 
363:       output << "</th>\n"
364:     end
365: 
366:     output << "          <th width=\"1\">&nbsp;</th>\n" unless ( actions_method.nil? )
367:     return ( output << "        </tr>\n" )
368:   end

Support function for apphelp_list_header.

Returns an HTML link based on a URL acquired by calling "models_path", where "models" comes from pluralizing the given lower case singular model name, wrapping the given link text (which will be protected in turn with a call to "h(…)"). Pass also the index of the column in the list structure. Generates a link with query string attempting to maintain or set correctly the sort and pagination parameters based on the current request parameters and given column index.

E.g.:

  apphelp_list_header_link( 'users_path', 'User name', 0 )

[Source]

     # File app/helpers/application_helper.rb, line 481
481:   def apphelp_list_header_link( model, text, index )
482: 
483:     # When generating the link, there is no point maintaining the
484:     # current page number - reset to 1. Do maintain the entries count.
485: 
486:     entries   = ''
487:     entries   = "&entries=#{ params[ :entries ] }" if params[ :entries ]
488: 
489:     # For the direction, if the current sort index in 'params' matches
490:     # the index for this column, the link should be used to toggle the
491:     # sort order; if currently on 'asc', write 'desc' and vice versa.
492:     # If building a link for a different column, default to 'asc'.
493: 
494:     direction = ''
495: 
496:     if ( params[ :sort ] == index.to_s && params[ :direction ] == 'asc' )
497:       direction = '&direction=desc'
498:     else
499:       direction = '&direction=asc'
500:     end
501: 
502:     # Get the base URL using the caller-supplied method and assemble the
503:     # query string after it.
504: 
505:     base = send( "#{ model.pluralize }_path" )
506:     url  = "#{ base }?sort=#{ index }#{ direction }&page=1#{ entries }"
507: 
508:     unless ( params[ :search ].nil? or params[ :search ].empty? )
509:       url << "&search=#{ params[ :search ] }"
510:     end
511: 
512:     return link_to( h( text ), url )
513:   end

Construct a body row for a list table, returning HTML for it. The table outer definition must be included externally. To define the row contents, pass an array of hashes. Each array entry corresponds to a cell in the row, built in order of appearance in the array. The hashes can contain optional property "value_align" to override the row alignment for that cell; the property‘s value is used directly as a TD "align" value.

Each hash must include property "value_method". This method will be invoked on the object given in the second function input parameter and must return a displayable value for the cell. The output is made safe by wrapping with a call to "h()" automatically.

The third input parameter is the name of a helper method which will be invoked with the current item as a parameter. It must return the names of actions permitted for that item, in an array. Actions will be placed in the final cell on the row as normal links. If the parameter is ‘nil’, no actions cell will be added onto the rows.

Since models can‘t always generate what you want (e.g. they don‘t have access to helpers, so creating values with associations’ "show" views linked to is difficult), you can specify property "value_helper". This helper method will be called and passed the item. Its return value is used instead of the value method, which won‘t be called and can be omitted if a helper is being used instead. HELPER TEXT IS NOT WRAPPED BY A CALL TO "h()" - value helpers MUST do this themselves.

See also apphelp_list_header.

E.g.:

  apphelp_list_row(
    [
      { :value_method => 'name' },
      { :value_method => 'age', :value_align => 'center' },
      { :value_method => 'email_as_link' } # Custom method in User model
    ],
    User.find( :first )
  )

[Source]

     # File app/helpers/application_helper.rb, line 409
409:   def apphelp_list_row( structure, item, actions_method )
410:     output = "        <tr valign=\"top\" align=\"left\" class=\"#{ cycle( 'even', 'odd' ) }\">\n"
411: 
412:     # Handle the item columns first
413: 
414:     structure.each_index do | index |
415:       entry = structure[ index ]
416:       align = entry[ :value_align ]
417: 
418:       output << "          <td"
419: 
420:       if ( align.nil? )
421:         output << ">" if ( align.nil? )
422:       else
423:         output << " align=\"#{ align }\">"
424:       end
425: 
426:       method = entry[ :value_method ]
427:       helper = entry[ :value_helper ]
428: 
429:       if ( helper )
430:         output << send( helper, item )
431:       else
432: 
433:         # Restricted users can only edit their own account. Since they are not
434:         # allowed to list other users on the system, the list view is disabled
435:         # for them, so there can never be in-place editors in that case. For
436:         # any other object type, restricted users have no edit permission. The
437:         # result? Disable all in-place editors for restricted users.
438: 
439:         in_place = entry[ :value_in_place ] && @current_user.privileged?
440: 
441:         if ( in_place )
442:           output << safe_in_place_editor_field( item, method )
443:         else
444:           output << h( item.send( method ) )
445:         end
446:       end
447: 
448:       output << "</td>\n"
449:     end
450: 
451:     # Add the actions cell?
452: 
453:     unless ( actions_method.nil? )
454:       actions = send( actions_method, item ) || []
455:       output << "          <td class=\"list_actions\" nowrap=\"nowrap\">\n"
456:       actions.each do | action |
457:         output << "            "
458:         output << link_to( action.humanize, { :action => action, :id => item.id } )
459:         output << "\n"
460:       end
461:       output << "          </td>\n"
462:     end
463: 
464:     return ( output << "        </tr>\n" )
465:   end

Return HTML representing a human-readable list of the given objects, as links to titles for the objects. To list a different field, provide the field name as a symbol in the optional second parameter.

[Source]

     # File app/helpers/application_helper.rb, line 288
288:   def apphelp_object_list( objects, field = :title )
289:     return 'None' if ( objects.nil? or objects.empty? )
290: 
291:     objects.collect! do | object |
292:       link_to( h( object.send( field ) ), object )
293:     end
294: 
295:     return objects.join( ', ' )
296:   end

Return HTML suitable for an edit form, providing a grouped list of projects that can be assigned to something. The list is grouped by customer in default customer sort order, along with a ‘None’ entry for unassigned projects. Pass an ID for the select list, a name for the select list, and an ID to match within the list to have one of the entries selected (or omit for no pre-selected item). Pass an optional fourth parameter of "true" to include a "none" entry, else exclude it (exclusion is the default behaviour).

[Source]

     # File app/helpers/application_helper.rb, line 235
235:   def apphelp_project_selector( select_id, select_name, match, include_none = false )
236: 
237:     customers = []
238: 
239:     # Add the "none" entry; but of a hack, this... :-(
240: 
241:     if ( include_none )
242:       dummy_project           = Project.new
243:       dummy_project.id        = ''
244:       dummy_project.title     = 'None'
245: 
246:       dummy_customer          = Customer.new
247:       dummy_customer.id       = ''
248:       dummy_customer.title    = 'None'
249:       dummy_customer.projects = [ dummy_project ]
250: 
251:       customers.push( dummy_customer )
252:     end
253: 
254:     # Create a dummy customer for the unassigned projects.
255: 
256:     dummy_customer          = Customer.new
257:     dummy_customer.title    = 'No assigned customer'
258:     dummy_customer.projects = Project.active.unassigned
259: 
260:     customers.push( dummy_customer ) unless ( dummy_customer.projects.empty? )
261: 
262:     # Find all customers and loop through, adding those that have at least
263:     # one assigned project to the 'customers' array.
264: 
265:     Customer.active.each do | customer |
266:       customers.push( customer ) unless ( customer.projects.active.count.zero? )
267:     end
268: 
269:     return 'There are no active projects.' if ( customers.empty? )
270: 
271:     data = "<select id=\"#{ select_id }\" name=\"#{ select_name }\">"
272:     data << option_groups_from_collection_for_select(
273:       customers, # Use customers for groups
274:       :projects, # A customer's "projects" method returns its project list
275:       :title,    # Use the customer title for the group labels
276:       :id,       # A project's "id" method returns the value for an option tag
277:       :title,    # A project's "title" method is used for the option contents
278:       match      # Match this ID for the selected option item
279:     )
280:     return data << '</select>'
281:   end

As apphelp_collection_select, but runs ‘select’ rather than ‘collection_select’. The parameters are adjusted accordingly.

[Source]

     # File app/helpers/application_helper.rb, line 217
217:   def apphelp_select( form, objfield, choices, multiple = true )
218:     return form.select(
219:       objfield,
220:       choices,
221:       {},
222:       apphelp_extra_selection_args( choices, multiple )
223:     )
224:   end

Return ‘sign in’ or ‘you are signed in’ text indicating current status.

[Source]

     # File app/helpers/application_helper.rb, line 118
118:   def apphelp_sign_or_signed_in
119:     if ( @current_user )
120:       if ( @current_user.name.nil? or @current_user.name.empty? )
121:         signinfo = 'Creating new account'
122:       else
123:         signinfo = "You are signed in as #{ h( @current_user.name ) } &ndash; #{ link_to( 'sign out', signout_path() ) } "
124:       end
125:     else
126:       # The Application Controller forces redirection to the sign-in page
127:       # if the user isn't signed in.
128:       signinfo = "Please #{ link_to( 'sign in', signin_path() ) }"
129:     end
130: 
131:     return signinfo
132:   end

Return data for the navigation bar ("slug").

[Source]

    # File app/helpers/application_helper.rb, line 58
58:   def apphelp_slug
59:     action = h( action_name )
60:     ctname = h( controller.controller_name )
61:     sep    = '&nbsp;&raquo;&nbsp;'
62:     slug   = link_to( 'Home page', home_path() ) << sep
63: 
64:     if ( ctname == 'users' and action == 'home' )
65:       slug = 'Home page'
66:     elsif ( ctname == 'sessions' and action == 'new' )
67:       slug << 'Sign in'
68:     elsif ( action == 'index' or action == 'list' )
69:       slug << apphelp_title()
70:     elsif ( ctname == 'reports' )
71:       if ( action == 'create' )
72:         slug << link_to( 'Reports', new_report_path() ) <<
73:                 sep <<
74:                 'Show report'
75:       else
76:         slug << 'Reports'
77:       end
78:     else
79:       slug << link_to( ctname.capitalize(), send( "#{ ctname }_path" ) ) <<
80:               sep <<
81:               apphelp_title()
82:     end
83: 
84:     return slug
85:   end

Pass a string representation of worked hours or a duration and a string to show instead of "0.0", if that‘s the duration/worked hours value. Optionally, pass in a string to use instead of an empty string, should the duration/worked hours value be empty itself.

[Source]

     # File app/helpers/application_helper.rb, line 166
166:   def apphelp_string_hours( hours, alt_str, empty_str = nil )
167:     return ( empty_str ) if ( hours.empty? and not empty_str.nil? and not empty_str.empty? )
168:     return ( hours == '0.0' ? alt_str : hours )
169:   end

Terse hours - precision 2, don‘t show ".0", no string suffix. If you want a blank string instead of "0", pass "true" in the second parameter.

[Source]

     # File app/helpers/application_helper.rb, line 155
155:   def apphelp_terse_hours( hours, zero_is_blank = false )
156:     hours = hours.precision( 2 ).to_s.chomp( '0' ).chomp( '0' ).chomp( '.' )
157:     return '' if ( hours == '0' and zero_is_blank )
158:     return hours
159:   end

Return a dynamic title based on the current request action and controller.

[Source]

    # File app/helpers/application_helper.rb, line 28
28:   def apphelp_title
29:     action = h( action_name )
30:     ctname = h( controller.controller_name )
31: 
32:     if ( [ '', 'index', 'list' ].include?( action ) )
33:       title = ctname.capitalize
34:     else
35:       if ( action == 'home' )
36:         title = 'Home page'
37:       else
38:         ctname = ctname.singularize()
39: 
40:         if ( ctname == 'user' )
41:           title = "#{ action.capitalize } account"
42:         elsif ( ctname == 'task_import' )
43:           title = 'Bulk task import'
44:         else
45:           title = "#{ action.capitalize } #{ ctname }"
46:         end
47:       end
48:     end
49: 
50:     # Awkward special case
51:     title = "Enter timesheets" if ( title == "New timesheet" )
52: 
53:     return title
54:   end

[Validate]