Module | ApplicationHelper |
In: |
app/helpers/application_helper.rb
|
フレームワークのどの view でも利用できる helper を定義する。
CHECK_BUGS | = | true |
アプリケーションメニューのタイトルとして表示するとともに設定する。
# File app/helpers/application_helper.rb, line 247 247: def application_menu_title_only(title, view_handle=true) 248: @title = title 249: return "<table class=\"application_menu\">\n<tr class=\"application_menu_line1\">\n<td>\n<span class=\"\#{view_handle ? 'view_handle ' : ''}title\">\#{h title}</span>\n</td>\n</tr>\n</table>\n" 250: end
ラベルつきの check_box
# File app/helpers/application_helper.rb, line 40 40: def check_box_with_label(object_name, method, label, options = {}, checked_value = "1", unchecked_value = "0") 41: with_label(label, options, object_name, method) do |o| 42: check_box(object_name, method, o, checked_value, unchecked_value) 43: end 44: end
固定のオプションの配列 c から構成される select box を返す。
# File app/helpers/application_helper.rb, line 402 402: def constant_select_tag(c, name, x, k, blank=nil) 403: options = c.map {|pair| [s_(pair.first), pair.last]} 404: options.unshift([blank, ""]) if blank 405: select_tag(name, options_for_select(options, x.attributes[k])) 406: end
params に対応するエラーメッセージのノードを返す。
# File app/helpers/application_helper.rb, line 322 322: def error_messages_for(*params) 323: if @stale_object_error 324: message = [ content_tag(:h4, s_("Attempted to update a stale object")), 325: content_tag(:p, s_("Someone has updated the object. Please go back to show the new version of it.")) 326: ] 327: return content_tag(:div, message.join, :class => "errorExplanation") 328: end 329: options = params.last.is_a?(Hash) ? params.pop.symbolize_keys : {} 330: objects = params.collect {|object_name| instance_variable_get("@#{object_name}") }.compact 331: object_names = params.dup 332: count = objects.inject(0) {|sum, object| sum + object.errors.count } 333: if count.zero? 334: '' 335: else 336: return [ 337: '<div class="errorExplanation">', 338: '<h4>', 339: n_("%{num} error prohibited this data from being saved", 340: "%{num} errors prohibited this data from being saved", 341: count) % { :num => count }, 342: '</h4>', 343: '<p>', 344: n_("There was a problem with the following field.", 345: "There were problems with the following fields.", 346: count), 347: '</p>', 348: '</div>', 349: ].join("") 350: end 351: end
左|中央|右にレイアウトされたボタン列を返す。
# File app/helpers/application_helper.rb, line 409 409: def lcr_button_box(buttons=@lcr_buttons) 410: return "<table class=\"lcr_button_box\">\n<tr>\n<td class=\"lcr_button_box_left\">\#{buttons[:left] || ' '}</td>\n<td class=\"lcr_button_box_center\">\#{buttons[:center] || ' '}</td>\n<td class=\"lcr_button_box_right\">\#{buttons[:right] || ' '}</td>\n</tr>\n</table>\n" 411: end
「閉じる」リンク リンクの html 要素の ID は "link_#{@current_view}_close*" という形になる。
# File app/helpers/application_helper.rb, line 71 71: def link_to_close(motion_params, options, html_options = {}) 72: return link_to_view_motion(h(s_("button|Close")), @current_view, "close", motion_params, options, html_options) 73: end
サブ画面へのリンク リンクの html 要素の ID の形は "link_#{part of view}_#{motion}_#{join of motion_params ‘key_value’ with ‘_’}" となる。
十分なエントリがなければ @fragment_hash から計算される。 値が nil なエントリは無視される。 "_" というキーでリンクの html 要素の ID に suffix を与えることができる。
ハッシュで指定された場合、十分なエントリがなければ @fragment_hash から計算される。
ただし :id などいくつかのエントリは上書きされる。
# File app/helpers/application_helper.rb, line 174 174: def link_to_view_motion(name, view, motion, motion_params, options, html_options = {}) 175: view ||= @current_view 176: if /\Aview_([a-z0-9]+)\z/ =~ view 177: view = $1 178: end 179: if CHECK_BUGS 180: if @current_view.nil? 181: raise "[bug] @current_view is nil" 182: end 183: if /[^a-z0-9]/ =~ view 184: raise "[bug] invalid view #{view.inspect}" 185: end 186: if motion.nil? && "view_#{view}" != @current_view 187: raise "[bug] missing motion" 188: end 189: end 190: motion ||= @fragment_hash.motion(view) 191: link_params = ["link", view, motion] 192: motion_params = motion_params.with_indifferent_access 193: if options.is_a?(Hash) 194: link_to_options = options.with_indifferent_access 195: end 196: @fragment_hash[view].each do |key, value| 197: if value 198: motion_params[key] = value unless motion_params.key?(key) 199: if link_to_options 200: link_to_options[key] = value unless link_to_options.key?(key) 201: end 202: end 203: end 204: @fragment_hash.default_params(view).each do |key, default_value| 205: if motion_params[key] == default_value 206: motion_params.delete(key) 207: end 208: if link_to_options 209: if link_to_options[key] == default_value 210: link_to_options.delete(key) 211: end 212: end 213: end 214: suffix = motion_params.delete("_") 215: motion_params.keys.sort.each do |key| 216: if motion_params[key] 217: link_params << key << motion_params[key] 218: end 219: end 220: link_params << suffix 221: html_options[:id] = link_params.compact.join("_") 222: 223: if html_options[:confirm] && html_options[:method] == :post 224: html_options[:onclick] = "if (confirm('#{h html_options[:confirm]}')) { onAjaxLink(this); }; return false" 225: html_options.delete(:confirm) 226: html_options.delete(:method) 227: elsif html_options[:onclick] 228: html_options[:onclick] = "#{html_options[:onclick]}return onAjaxLink(this)" 229: else 230: html_options[:onclick] = "return onAjaxLink(this)" 231: end 232: link_to_options ||= options 233: return link_to(name, link_to_options, html_options) 234: end
選択部品へのリンク
# File app/helpers/application_helper.rb, line 367 367: def open_to_pick(x, options = {}) 368: c = x.class.to_s 369: singular = c.underscore 370: plural = singular.pluralize 371: dom_id = "search_#{plural}_#{x.id}" 372: url = {:action => "open_#{singular}", :id => x.id} 373: url = url.update(options) 374: link_to_remote(tree_icon_open, { 375: :url => url, 376: :success => "$$('#search_#{plural} a').each(function(x){x.style.fontWeight='normal';});$('#{dom_id}').style.fontWeight='bold';", 377: :update => "area_#{plural}", 378: }, { 379: :id => dom_id, 380: :class => "dropdown" 381: }) 382: end
ページ部品
# File app/helpers/application_helper.rb, line 76 76: def pagination(locals) 77: { 78: :html_class => "", 79: :left_columns => "", 80: :options => {}, 81: :right_columns => "", 82: :suffix => "", 83: }.each do |key, value| 84: locals[key] ||= value 85: end 86: tds = [] 87: tds << locals[:left_columns] 88: if previous_page = locals[:pages].current.previous 89: img = image_tag("previous_page_found.gif", :alt => _("Previous page")) 90: if locals[:update] 91: a = link_to_remote(img, 92: :update => locals[:update], 93: :complete => visual_effect(:highlight, locals[:update]), 94: :url => locals[:options].merge({:action => locals[:action], :page => previous_page.to_i, :per => locals[:per]})) 95: else 96: a = link_to_view_motion(img, 97: locals[:view], nil, 98: {"page" => previous_page.to_i, "_" => locals[:suffix]+"_prev"}, 99: locals[:options].merge({:page => previous_page.to_i}), 100: :class => locals[:html_class]) 101: end 102: else 103: a = image_tag("previous_page_not_found.gif", :alt => _("Previous page")) 104: end 105: tds << content_tag(:td, a, :class => "previous_page") 106: current = locals[:pages].current_page.to_i 107: ((current-2)..(current+2)).each do |n| 108: if locals[:pages].has_page_number?(n) 109: if current == n 110: b = n.to_i 111: elsif locals[:update] 112: b = link_to_remote(n.to_s, 113: :update => locals[:update], 114: :complete => visual_effect(:highlight, locals[:update]), 115: :url => locals[:options].merge({:action => locals[:action], :page => n, :per => locals[:per]})) 116: else 117: b = link_to_view_motion(n.to_s, 118: locals[:view], nil, 119: {"page" => n, "_" => locals[:suffix]}, 120: locals[:options].merge({ :page => n }), 121: :class => locals[:html_class]) 122: end 123: else 124: b = " " 125: end 126: tds << content_tag(:td, b, :class => "each_page") 127: end 128: if next_page = locals[:pages].current.next 129: img = image_tag("next_page_found.gif", :alt => _("Next page")) 130: if locals[:update] 131: c = link_to_remote(img, 132: :update => locals[:update], 133: :complete => visual_effect(:highlight, locals[:update]), 134: :url => locals[:options].merge({:action => locals[:action], :page => next_page.to_i, :per => locals[:per]})) 135: else 136: c = link_to_view_motion(img, 137: locals[:view], nil, 138: {"page" => next_page.to_i, "_" => locals[:suffix]+"_next"}, 139: locals[:options].merge({:page => next_page.to_i}), 140: :class => locals[:html_class]) 141: end 142: else 143: c = image_tag("next_page_not_found.gif", :alt => _("Next page")) 144: end 145: tds << content_tag(:td, c, :class => "next_page") 146: d = n_("%{first_item}-%{last_item} of %{item_count} item", 147: "%{first_item}-%{last_item} of %{item_count} items", 148: locals[:pages].item_count) % { 149: :first_item => locals[:pages].current.first_item, 150: :last_item => locals[:pages].current.last_item, 151: :item_count => locals[:pages].item_count 152: } 153: tds << content_tag(:td, d) 154: tds << locals[:right_columns] 155: content = content_tag(:tr, tds.join) 156: return content_tag(:table, content, :class => "pagination") 157: end
ラベルつきの radio box
# File app/helpers/application_helper.rb, line 47 47: def radio_box_with_label(object_name, method) 48: "#{object_name.classify}::LABEL_#{method.upcase}".constantize.map do |pair| 49: radio_button_with_label(object_name, method, pair.last, s_(pair.first)) 50: end.join(" ") 51: end
ラベルつきの radio_button_tag
# File app/helpers/application_helper.rb, line 61 61: def radio_button_tag_with_label(name, value, label_body, checked = false, options = {}) 62: options[:id] ||= "#{name}_#{value}" 63: return radio_button_tag(name, value, checked, options) + content_tag(:label, label_body, {:for => options[:id]}) 64: end
ラベルつきの radio_button
# File app/helpers/application_helper.rb, line 54 54: def radio_button_with_label(object_name, method, tag_value, label, options = {}) 55: with_label(label, options, object_name, method, tag_value) do |o| 56: radio_button(object_name, method, tag_value, o) 57: end 58: end
選択部品へのリンクを構成する。
# File app/helpers/application_helper.rb, line 354 354: def search_to_pick(singular, options = {}) 355: plural = singular.to_s.pluralize 356: url = {:action => "search_#{plural}"} 357: url = url.update(options) 358: { 359: :url => url, 360: :update => "area_#{plural}", 361: :complete => visual_effect(:highlight, "area_#{plural}"), 362: :html => {:action => url_for(url)} 363: } 364: end
fragment を埋め込む
# File app/helpers/application_helper.rb, line 262 262: def set_fragment(fragment) 263: return "<form>\n<input type=\"hidden\" class=\"fragment_setter\" value=\"\#{h fragment}\">\n</form>\n" 264: end
ノードとして表示するとともに、タイトルを設定する。
# File app/helpers/application_helper.rb, line 237 237: def set_title(title, hidden=request.xhr?) 238: @title = title 239: if hidden 240: return "<h1 class='title' style='display: none'>#{h(title)}</h1>" 241: else 242: return "<h1 class='title'>#{h(title)}</h1>" 243: end 244: end
状態遷移時の効果を加えた submit_tag。
# File app/helpers/application_helper.rb, line 305 305: def submit_tag(value, options={}) 306: options = options.with_indifferent_access 307: disable_with = options.delete("disable_with") || s_("submit_tag|please wait ...") 308: onclick = options.delete("onclick") 309: if onclick 310: onclick = "App.onSubmitTag(this,'#{disable_with}');#{onclick};return false;" 311: else 312: onclick = "return App.onSubmitTag(this,'#{disable_with}');" 313: end 314: options = { 315: "class" => "button", 316: "onclick" => onclick, 317: }.merge(options) 318: super(value, options) 319: end
「閉じる」アイコン
# File app/helpers/application_helper.rb, line 25 25: def tree_icon_close 26: '<span class="tree_icon tree_icon_close">▼</span>' 27: end
「閉じる」アイコン(タグ無し)
# File app/helpers/application_helper.rb, line 10 10: def tree_icon_close_without_tag 11: "▼" 12: end
「末端」アイコン
# File app/helpers/application_helper.rb, line 35 35: def tree_icon_leaf 36: '<span class="tree_icon tree_icon_leaf"> </span>' 37: end
「末端」アイコン(タグ無し)
# File app/helpers/application_helper.rb, line 20 20: def tree_icon_leaf_without_tag 21: " " 22: end
「開く」アイコン
# File app/helpers/application_helper.rb, line 30 30: def tree_icon_open 31: '<span class="tree_icon tree_icon_open">▲</span>' 32: end
「開く」アイコン(タグ無し)
# File app/helpers/application_helper.rb, line 15 15: def tree_icon_open_without_tag 16: "▲" 17: end
Ajax に対応したフォームを構成する。
# File app/helpers/application_helper.rb, line 272 272: def x_form_tag(url={}, options={}, *parameters_for_url, &block) 273: view = @current_view 274: url = url_for(url) if url.is_a?(Hash) 275: if /\Aview_[a-z0-9]+\z/ !~ view 276: raise "invalid view #{view.inspect}" 277: end 278: options[:url] ||= url 279: options[:update] = view 280: options[:form] = true 281: options[:html] ||= {} 282: 283: function = remote_function(options) 284: if view != "view_main" 285: function.sub!(/Updater\('#{view}',/) do 286: "Updater($('#{view}')||$('view_main')," 287: end 288: end 289: function.sub!(/asynchronous:true,/) do 290: "app_view:'#{view}',#{$&}" 291: end 292: 293: options[:html][:onsubmit] = (options[:html][:onsubmit] ? options[:html][:onsubmit] + "; " : "") 294: if view != "view_main" 295: options[:html][:onsubmit] << "if(!$('#{view}')&&!$('view_main')){return true};" 296: else 297: options[:html][:onsubmit] << "if(!$('#{view}')){return true};" 298: end 299: options[:html][:onsubmit] << "#{function};return false;" 300: 301: form_tag(options[:html].delete(:action) || url_for(options[:url]), options[:html], *parameters_for_url, &block) 302: end