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.
Return strings ‘Yes’ or ‘No’ depending on the value of the given boolean quantity.
# 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.
# 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.
# 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.
# 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.
# 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
# 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".
# 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.
# 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.
# 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' )
# 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\"> </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 )
# 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 ) )
# 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.
# 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).
# 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.
# 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.
# 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 ) } – #{ 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").
# 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 = ' » ' 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.
# 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.
# 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.
# 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