| 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