Module ProductHelper
In: app/helpers/product_helper.rb

Methods

Public Instance methods

画面上下に配置されるボタン群を返す。

[Source]

     # 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

カレンダー選択部品による入力部品を返す。

[Source]

     # 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

[Source]

     # 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, "&nbsp;", :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

[Source]

     # 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

[Source]

     # 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

詳細画面へのリンクを返す。

[Source]

     # 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 を返す。

[Source]

     # 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 => "&yen;", :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 を返す。

[Source]

     # 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 からヘッダを返す。

[Source]

    # 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 を返す。

[Source]

    # 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 を返す。

[Source]

    # 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

一覧の設定画面へのリンクを返す。

[Source]

     # 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

一覧検索(汎用検索)の設定画面へのリンクを返す。

[Source]

     # 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

関連文書を選択するためのリンクを返す。

[Source]

     # 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

メール送信部品による選択の情報を返す。

[Source]

     # 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

権限で許可されていないカラムの部品を返す。

[Source]

    # 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

選択部品による入力部品を返す。

[Source]

     # 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

[Source]

     # 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

サマリへのリンクを返す。

[Source]

     # 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

新規作成画面へのボタンを返す。

[Source]

    # 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 = "&nbsp;"
12:     end
13:     content_tag(:td, b, :class => "button_new")
14:   end

(指定されていれば)CSV出力画面へのリンクを返す。

[Source]

    # 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

[Source]

     # 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, "&nbsp;"))
203:     ths.push(content_tag(:th, "&nbsp")) 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 を返す。

[Source]

    # 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

[Validate]