Module | ProductHelper
In: | app/helpers/product_helper.rb

### Methods

button_box calendar_picker_tags detail_to_tr details_to_table details_to_table_input display_aspect item_to_td item_to_td_input item_to_th items_to_table items_to_table_input link_to_list link_to_search link_to_select_document mailto_info not_permitted_column picker_tags sortable_details summary_aspect td_button_new td_to_csv with_details with_table

### Public Instance methods

button_box(suffix)

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

[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

calendar_picker_tags(i, object_name, it)

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

[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

detail_to_tr(d, script=nil, options={}) {|i, d| ...}

[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

details_to_table()

[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

details_to_table_input()

[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

display_aspect(controller, view)

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

[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

item_to_td(i, it)

項目から 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

item_to_td_input(i, object_name)

項目から 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

item_to_th(i)

項目 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

items_to_table()

項目の一覧を含む 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

items_to_table_input()

項目の一覧に対応する 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

link_to_list()

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

[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

link_to_search()

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

[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

link_to_select_document(it)

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

[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

mailto_info()

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

[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

not_permitted_column()

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

[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

picker_tags(i, object_name, it)

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

[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

sortable_details()

[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

summary_aspect(controller)

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

[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

td_button_new()

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

[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

td_to_csv()

(指定されていれば)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

with_details(tail=nil) {|, {:id => "details_table_body"}| ...}

[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

with_table() {|item| ...}

詳細画面および編集画面で詳細情報を表示するための 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]