| Module | ProductHelper |
| In: |
app/helpers/product_helper.rb
|
画面上下に配置されるボタン群を返す。
# File app/helpers/product_helper.rb, line 484
484: def button_box(suffix)
485: buttons = {}
486: if params[:id] && @display.button_back?
487: buttons[:left] = link_to_view_motion(h(s_("button|Back")),
488: @current_view, "show",
489: {:id => params[:id], "_" => suffix},
490: {:action => "show", :id => params[:id]},
491: :class => "button reloadable_link")
492: elsif @display.button_close?
493: buttons[:left] = link_to_close({:id => nil, "_" => suffix}, {:action => "list", :id => nil}, :class => "button")
494: end
495: buttons[:center] = ""
496: if @display.button_edit? && @product.modifiable?
497: buttons[:center] += link_to_view_motion(h(s_("button|Edit")),
498: @current_view, "edit",
499: {:id => @it.id, "_" => suffix},
500: {:action => "edit", :id => @it },
501: :class => "button reloadable_link")
502: end
503: if @display.button_copy? && @product.modifiable?
504: buttons[:center] += link_to_view_motion(h(s_("button|Copy")),
505: @current_view, "copy",
506: {:id => @it.id, "_" => suffix},
507: {:action => "new", :id => @it },
508: :class => "button reloadable_link")
509: end
510: if @submit_tag
511: buttons[:center] += @submit_tag
512: end
513: if @display.button_delete? && @product.modifiable?
514: buttons[:right] = link_to_view_motion(h(s_("button|Destroy")),
515: @current_view, "destroy",
516: {:id => @it.id, "_" => suffix},
517: {:action => "destroy", :id => @it },
518: :confirm => s_('confirm|Are you sure?'),
519: :method => :post,
520: :class => "button reloadable_link")
521: end
522: return lcr_button_box(buttons)
523: end
カレンダー選択部品による入力部品を返す。
# File app/helpers/product_helper.rb, line 272
272: def calendar_picker_tags(i, object_name, it)
273: picker_field = i.picker_field(it, object_name)
274:
275: if flash[:pick] && picker_field === flash[:pick][:field] && flash[:pick][:return_value]
276: it[i.column_name] = flash[:pick][:return_value]
277: end
278:
279: e = text_field object_name, i.column_name, :size => i.size_for_input_field
280: e << " "
281: e << submit_tag(s_("submit_tag|Pick Date"), :name => "picker[#{picker_field}]", :onclick => "$('#{object_name}_#{i.column_name}').addClassName('selected')", :disabled => !i.writable?)
282: # hidden link for ajax
283: e << link_to_view_motion("",
284: @sub_view, picker_field, {},
285: {
286: :controller => "calendar",
287: :action => "calendar",
288: :return_field => picker_field,
289: :view => @sub_view,
290: }, :style => "display:none")
291: return e
292: end
# File app/helpers/product_helper.rb, line 188
188: def detail_to_tr(d, script=nil, options={}, &block)
189: tds = @detail_items.map {|i| yield(i, d)}
190: tds.unshift(content_tag(:td, " ", :class => "handle"))
191: if script
192: link = link_to_function(h(s_("button|Destroy")), script, :class => "button")
193: tds.push(content_tag(:td, link))
194: end
195: options.update({:class => cycle("even", "odd", :name => "details_to_table")})
196: content_tag(:tr, tds, options)
197: end
# File app/helpers/product_helper.rb, line 212
212: def details_to_table
213: return "" unless @product.is_a?(ProductMultiple) || @product.is_a?(ProductDetailed)
214: with_details do
215: @details.map {|d| detail_to_tr(d) {|i,d| item_to_td(i,d)}}
216: end
217: end
# File app/helpers/product_helper.rb, line 220
220: def details_to_table_input
221: return "" unless @product.is_a?(ProductMultiple) || @product.is_a?(ProductDetailed)
222: tail = sortable_details
223: tail += hidden_field_tag("new_details", @new_details.to_json)
224: tail += hidden_field_tag("old_details", @old_details.to_json)
225: tail += hidden_field_tag("order_details", @details.map {|detail| "details_#{detail.id}"}.to_json)
226: d = @product.detail_class.new
227: @detail_items.each do |i|
228: i.initialize_column_of(d)
229: end
230: temp = "new_details_#{rand(65536)}#{Time.now.to_i}"
231: instance_variable_set("@#{temp}", d)
232: tr = detail_to_tr(d, "remove_new_details(this,\#{n});", :id => temp) {|i,d| item_to_td_input(i, temp)}
233: tr = tr.gsub(temp, "new_details_\#{n}")
234: link = link_to_remote(h(s_("button|New")), {
235: :before => "add_new_details('#{escape_javascript(tr)}');",
236: :update => "space_details",
237: :url => {:action => "add_detail"},
238: }, {
239: :class => "button",
240: })
241: tail += content_tag(:div, link, :class => "right")
242: tail += content_tag(:div, "", :id => "space_details")
243: with_details(tail) do
244: rows = []
245: @details.each do |d|
246: unless @old_details.include?(d.id)
247: html_id = "details_#{d.id}"
248: rows << detail_to_tr(d, "remove_old_details(this,#{d.id});", :id => html_id) {|i,d| item_to_td_input(i, html_id)}
249: end
250: end
251: rows += @new_details.map do |n|
252: d = instance_variable_get("@new_details_#{n}")
253: html_id = "new_details_#{n}"
254: detail_to_tr(d, "remove_new_details(this,#{n});", :id => html_id) {|i,d| item_to_td_input(i, html_id)}
255: end
256: rows
257: end
258: end
詳細画面へのリンクを返す。
# File app/helpers/product_helper.rb, line 439
439: def display_aspect(controller, view)
440: url = {:controller => controller, :action => "show", :id => @it.id, :type => @model_class, :product_id => @product.id}
441: if request.xhr?
442: javascript_tag(remote_function(:update => view, :url => url))
443: else
444: link = link_to_view_motion(s_(controller), view, "show", {}, url, :class => "autoload button")
445: content_tag(:div, link, :class => "left_buttons")
446: end
447: end
項目から td を返す。
# File app/helpers/product_helper.rb, line 78
78: def item_to_td(i, it)
79: return not_permitted_column unless i.readable?
80: begin
81: data = i.to_data(it)
82: rescue NoMethodError
83: logger.error("ERROR: not found column: #{@model_class}\##{i.column_name}")
84: return "<td class=\"formError\">#{s_("formError|column not found")}</td>"
85: end
86:
87: # input_type is not available in display_to_show and display_to_list
88: ??
89:
90: case i.decorator
91: when "front"
92: content = h("#{i.decorator_parameter}#{data}")
93: when "back"
94: content = h("#{data}#{i.decorator_parameter}")
95: when "currency"
96: content = number_to_currency(data, :unit => "¥", :precision => 0)
97: when "size" # for test
98: content = h(number_to_human_size(data))
99: when "nl2br"
100: content = h(data).gsub(/\r?\n/) { "<br />" }
101: else
102: content = h(data)
103: end
104:
105: if url = i.link_url(it)
106: content = link_to(content, url)
107: end
108:
109: options = {
110: :align => i.align,
111: :class => "item",
112: }
113: options[:style] = i.style
114: content = content_tag(:div, content)
115: return content_tag(:td, content, options)
116: end
項目から td にラップされた input を返す。
# File app/helpers/product_helper.rb, line 137
137: def item_to_td_input(i, object_name)
138: it = instance_variable_get("@#{object_name}")
139: return item_to_td(i, it) if i.is_a?(ItemPseudo)
140: begin
141: data = it.__send__(i.column_name)
142: rescue NoMethodError
143: logger.error("ERROR: column not found: #{@model_class}\##{i.column_name}")
144: return "<td class=\"formError\">#{s_("formError|column not found")}</td>"
145: end
146:
147: field_options = {}
148: field_options[:readonly] = "readonly" unless i.writable?
149: text_options = {
150: :size => i.size_for_input_field,
151: :style => i.style_for_input_field,
152: }
153: text_options.update(field_options)
154: case i.input_type
155: when "picker"
156: e = picker_tags(i, object_name, it)
157: when "text"
158: e = text_field object_name, i.column_name, text_options
159: when "textarea"
160: e = text_area object_name, i.column_name, text_options
161: when "radio"
162: choices = i.split_into_input_options do |name, value|
163: radio_button_with_label(object_name, i.column_name, value, h(name), field_options)
164: end
165: unless i.required?
166: choices.unshift(radio_button_with_label(object_name, i.column_name, "", h(s_("InputOption|(blank)")), field_options))
167: end
168: e = choices.join
169: when "checkbox"
170: e = check_box(object_name, i.column_name, field_options) + i.input_parameter.to_s
171: when "select"
172: choices = i.split_into_input_options do |name, value|
173: [h(name), value]
174: end
175: unless i.required?
176: choices.unshift([h(s_("InputOption|(blank)")), ""])
177: end
178: e = select(object_name, i.column_name, choices, field_options)
179: else
180: logger.error("ERROR: invalid input type: #{i.input_type} (#{@model_class}\##{i.column_name})")
181: return "<td class=\"formError\">#{s_("formError|invalid input type")}</td>"
182: end
183:
184: return content_tag(:td, e, {:class => "input_item", :style => i.style})
185: end
項目 i からヘッダを返す。
# File app/helpers/product_helper.rb, line 73
73: def item_to_th(i)
74: content_tag(:th, h(i.human_name), {:style => i.style})
75: end
項目の一覧を含む table を返す。
# File app/helpers/product_helper.rb, line 57
57: def items_to_table
58: with_table {|item| content_tag(:th, h(item.human_name)) + item_to_td(item, @it)}
59: end
項目の一覧に対応する input の table を返す。
# File app/helpers/product_helper.rb, line 62
62: def items_to_table_input
63: table = with_table do |item|
64: options = {}
65: options[:class] = "required" if item.required?
66: label = content_tag(:label, h(item.human_name), :for => "it_#{item.column_name}")
67: content_tag(:th, label, options) + item_to_td_input(item, :it)
68: end
69: table + hidden_field(:it, "lock_version")
70: end
一覧の設定画面へのリンクを返す。
# File app/helpers/product_helper.rb, line 476
476: def link_to_list
477: link_to_view_motion(h(s_("List")), "view_list", @product.id,
478: {},
479: {:controller => "list", :action => "index", :id => @product.id},
480: {:class => "button reloadable_link"})
481: end
一覧検索(汎用検索)の設定画面へのリンクを返す。
# File app/helpers/product_helper.rb, line 465
465: def link_to_search
466: return "" unless @product.search?
467: link_to_remote(h(s_("Search")),
468: { :update => "view_search",
469: :url => {:controller => "search", :action => "index"},
470: :with => "'display_id=' + $F('list')",
471: },
472: {:class => "button"})
473: end
関連文書を選択するためのリンクを返す。
# File app/helpers/product_helper.rb, line 456
456: def link_to_select_document(it)
457: return "" if @relatable && (it == @relatable || @product.document_nodes_for(@relatable).include?(it))
458: link_to_remote(tree_icon_open,
459: :update => "document_table_base",
460: :complete => visual_effect(:highlight, "document_table", :queue => {:scope => "document", :limit => 2, :position => "end"}),
461: :url => {:controller => "document", :action => "select", :id => params[:id], :type => params[:type], :product_id => params[:relatable_product_id], :target_id => it.id, :target_type => it.class.to_s, :target_product_id => @product.id})
462: end
メール送信部品による選択の情報を返す。
# File app/helpers/product_helper.rb, line 417
417: def mailto_info
418: mail = params[:mail] || {}
419: if mail[:recipients]
420: if mail[:recipients].is_a?(String)
421: mail[:recipients] = mail[:recipients].split(/,/).map(&:to_i)
422: end
423: recipients = Person.find(mail[:recipients])
424: info = select_tag "_mail_info", options_from_collection_for_select(recipients, "id", "name_with_in", 0)
425: mail[:recipients] = mail[:recipients].join(",")
426: else
427: recipients = []
428: info = ""
429: end
430: num = text_field_tag "_mail_num", recipients.size, :readonly => true, :size => 2, :class => "mail_num", :id => nil
431: info << ns_("mailto_info|%{num} person", "%{num} people", recipients.size) % { :num => num }
432: mail.keys.each do |key|
433: info << hidden_field_tag("mail[#{key}]", mail[key], :id => nil)
434: end
435: return info
436: end
権限で許可されていないカラムの部品を返す。
# File app/helpers/product_helper.rb, line 29
29: def not_permitted_column
30: filtered_message = s_("not_permitted_column|[FILTERED]")
31: return "<td class=\"not_permitted_column\">#{filtered_message}</td>"
32: end
選択部品による入力部品を返す。
# File app/helpers/product_helper.rb, line 295
295: def picker_tags(i, object_name, it)
296: return calendar_picker_tags(i, object_name, it) if i.calendar?
297: case i
298: when ItemProper
299: case i.picked_atom
300: when "company"
301: submit_text = s_("submit_tag|Pick Company")
302: when "organization"
303: submit_text = s_("submit_tag|Pick Organization")
304: when "person"
305: submit_text = s_("submit_tag|Pick Person")
306: when "post"
307: submit_text = s_("submit_tag|Pick Post")
308: when "group"
309: submit_text = s_("submit_tag|Pick Group")
310: else
311: raise ArgumentError, "invalid picked atom: #{i.picked_atom}"
312: end
313: picker_field = i.picker_field(it, object_name)
314: picked_class = i.picked_atom.classify.constantize
315: if flash[:pick] && picker_field == flash[:pick][:field]
316: values = i.picked_values(flash[:pick])
317: v = values.find {|x| x.is_a?(picked_class)}
318: it[i.column_name] = v.id
319: elsif v = picked_class.find_by_id(it[i.column_name])
320: values = i.picked_references(v)
321: else
322: values = i.picked_keys.map {|k| k.classify.constantize.new}
323: end
324: e = ""
325: i.picked_keys.each_with_index do |k,n|
326: e << text_field_tag("picker_#{picker_field}_#{k}", values[n].name, :readonly => true, :size => i.size_for_input_field)
327: e << " "
328: end
329: onclick = i.picked_keys.map do |k|
330: "$('picker_#{picker_field}_#{k}').addClassName('selected');"
331: end.join("")
332: e << submit_tag(submit_text, :name => "picker[#{picker_field}]", :onclick => onclick, :disabled => (i.readonly? || !i.writable?))
333: unless error_message_on(object_name, i.column_name).blank?
334: e = content_tag(:div, e, :class => "fieldWithErrors")
335: end
336: # hidden link for ajax
337: e << link_to_view_motion("",
338: @sub_view, picker_field, {},
339: {
340: :controller => "picker",
341: :action => i.picked_atom,
342: :return_field => picker_field,
343: :view => @sub_view,
344: }, :style => "display:none")
345: e << hidden_field(object_name, i.column_name)
346: return e
347: when ItemPolymorphic
348: picker_field = i.picker_field(it, object_name)
349: if flash[:pick] && picker_field == flash[:pick][:field]
350: if k = flash[:pick][:lump_pick]
351: v = k.classify.constantize.find(flash[:pick][k.to_sym])
352: it.__send__("#{i.column_name}=", v)
353: else
354: v = nil
355: end
356: elsif v = it.__send__(i.column_name)
357: else
358: v = nil
359: end
360: e = ""
361: e << text_field_tag("picker_#{picker_field}", v ? v.name : "", :readonly => true, :size => i.size_for_input_field)
362: onclick = "$('picker_#{picker_field}').addClassName('selected');"
363: e << submit_tag(s_("submit_tag|Pick"), :name => "picker[#{picker_field}]", :onclick => onclick, :disabled => (i.readonly? || !i.writable?))
364: unless error_message_on(object_name, i.column_name).blank?
365: e = content_tag(:div, e, :class => "fieldWithErrors")
366: end
367: # hidden link for ajax
368: e << link_to_view_motion("",
369: @sub_view, picker_field, {},
370: {
371: :controller => "picker",
372: :action => "lump",
373: :return_field => picker_field,
374: :view => @sub_view,
375: }, :style => "display:none")
376: e << hidden_field(object_name, "#{i.column_name}_id")
377: e << hidden_field(object_name, "#{i.column_name}_type")
378: return e
379: when ItemPlural
380: picker_field = i.picker_field(it, object_name)
381: if flash[:pick] && picker_field == flash[:pick][:field]
382: if k = flash[:pick][:lump_pick]
383: values = k.classify.constantize.find(flash[:pick][k.to_sym]).__send__(i.data_method_name)
384: it[i.column_name] = values.map(&:id).join(",")
385: else
386: values = []
387: end
388: elsif v = it.__send__(i.column_name)
389: values = v.split(",").map {|id| i.datum_class.find(id) rescue nil}.compact # FIXME
390: else
391: values = []
392: end
393: e = ""
394: e << text_field_tag("picker_#{picker_field}", values.map(&:name).join(","), :readonly => true, :size => i.size_for_input_field)
395: onclick = "$('picker_#{picker_field}').addClassName('selected');"
396: e << submit_tag(s_("submit_tag|Pick"), :name => "picker[#{picker_field}]", :onclick => onclick, :disabled => (i.readonly? || !i.writable?))
397: unless error_message_on(object_name, i.column_name).blank?
398: e = content_tag(:div, e, :class => "fieldWithErrors")
399: end
400: # hidden link for ajax
401: e << link_to_view_motion("",
402: @sub_view, picker_field, {},
403: {
404: :controller => "picker",
405: :action => "lump",
406: :return_field => picker_field,
407: :view => @sub_view,
408: }, :style => "display:none")
409: e << hidden_field(object_name, i.column_name)
410: return e
411: else
412: raise ArgumentError, "invalid item type: #{i.class}"
413: end
414: end
# File app/helpers/product_helper.rb, line 260
260: def sortable_details
261: sortable_element("details_table_body",
262: :format => "/^(details_[0-9]+|new_details_[0-9]+)$/",
263: :complete => visual_effect(:highlight, "details_table"),
264: :url => {:action => "order_details"},
265: :constraint => false,
266: :ghosting => true,
267: :handle => "handle",
268: :tag => "tr")
269: end
サマリへのリンクを返す。
# File app/helpers/product_helper.rb, line 450
450: def summary_aspect(controller)
451: url = {:controller => controller, :action => "summary", :id => @it.id, :type => @model_class, :product_id => @product.id}
452: javascript_tag(remote_function(:update => "summary_#{controller.pluralize}", :url => url))
453: end
新規作成画面へのボタンを返す。
# File app/helpers/product_helper.rb, line 3
3: def td_button_new
4: if @display.button_new? && @product.modifiable?
5: b = link_to_view_motion(h(s_("button|New")),
6: @sub_view, "create",
7: {"_" => "&suffix;"},
8: {:action => "new"},
9: :class => "button reloadable_link")
10: else
11: b = " "
12: end
13: content_tag(:td, b, :class => "button_new")
14: end
(指定されていれば)CSV出力画面へのリンクを返す。
# File app/helpers/product_helper.rb, line 17
17: def td_to_csv
18: return "" unless @display.csv?
19: link = link_to_view_motion(h(s_("link_to|CSV")),
20: "view_detail",
21: "output",
22: {:controller => "output", :action => "edit", :id => @display.id},
23: {:controller => "output", :action => "edit", :id => @display.id},
24: {:id => "output", :class => "button"})
25: content_tag(:td, link, :class => "right")
26: end
# File app/helpers/product_helper.rb, line 200
200: def with_details(tail=nil, &block)
201: ths = @detail_items.map {|i| item_to_th(i)}
202: ths.unshift(content_tag(:th, " "))
203: ths.push(content_tag(:th, " ")) if tail
204: head = content_tag(:thead, content_tag(:tr, ths))
205: foot = content_tag(:tfoot, "")
206: body = content_tag(:tbody, yield, {:id => "details_table_body"})
207: table = content_tag(:table, [head, foot, body],{:id => "details_table", :class => "detail hoverable"})
208: return table + (tail || "")
209: end
詳細画面および編集画面で詳細情報を表示するための table を返す。
# File app/helpers/product_helper.rb, line 35
35: def with_table(&block)
36: row_nums = @items.map(&:coordinate_number).compact.max
37: content = []
38: return "" unless row_nums
39: (1..row_nums).each do |i|
40: pair = [
41: @items.find {|item| item.coordinates == "A#{i}"},
42: @items.find {|item| item.coordinates == "B#{i}"},
43: ]
44: row = pair.map do |item|
45: if item.is_a?(Item)
46: yield item
47: else
48: content_tag(:th, "", :class => "blank") + content_tag(:td, "", :class => "blank")
49: end
50: end.join
51: content.push(content_tag(:tr, row))
52: end
53: return content_tag(:table, content.join, :class => "detail hoverable")
54: end