Module: Edgar::FieldHelper

Included in:
EdgarHelper
Defined in:
app/helpers/edgar/field_helper.rb

Overview

Edgar::FieldHelper is independent from Edgar default form (FormDrawer::Base) so you can use helper methods here for your customized form.

Instance Method Summary (collapse)

Instance Method Details

- (Object) draw_address(f, col_or_sym)

draw 'edgar_address' field

The column, which is declared as 'edgar_address', can be drawn by this helper.

INPUTS

f

FormBuilder

col_or_sym

column object returned by rec.class.columns, or symbol



133
134
135
136
137
138
139
140
# File 'app/helpers/edgar/field_helper.rb', line 133

def draw_address(f, col_or_sym)
  address_name  = f.object.class.get_belongs_to_name(col_or_sym)
  render('edgar/address',
      f:            f,
      rec:          f.object,
      address_name: address_name
  )
end

- (Object) draw_bitset(f, col, bitset = nil, options = {})

draw bitset checkboxes.

When model class has integer field (e.g. 'flags') and Flags module which defines 'bitflag' constant, model.flags integer column is drawn as bitset checkboxes. Constant name will be translated by config/locales/*.yml See ModelPermission for example.

'flags' column value is calculated at client side by JavaScript.

options is not used now.

INPUTS

f

Form builder object.

col

column object returned by rec.class.columns, or symbol

bitset

ruby module contains 'bitflag' integer constants

options

(not used)



159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
# File 'app/helpers/edgar/field_helper.rb', line 159

def draw_bitset(f, col, bitset=nil, options={})
  html          = ''
  bitset        = model.const_get(col_name.to_s.camelize + 'Bitset') if !bitset
  i             = 0
  id_array_var  = sprintf('%s_%s_var', f.object_name, col.name)
  ids           = []
  for flag in bitset.constants do
    checkbox_id = sprintf('%s_%s_%d', f.object_name, col.name, i)
    html += draw_checkbox(f, checkbox_id, flag, bitset, id_array_var) +
            label_tag(
                checkbox_id,
                f.object.class.human_const_name(bitset, flag)) +
            '  '.html_safe
    ids << checkbox_id
    i += 1
  end
  # draw hidden field to send sum-up value
  html += f.hidden_field(col.name)

  # add hidden-field name to ids' last
  ids << sprintf("%s_%s", f.object_name, col.name)

  # define arrays to calculate flags
  html += "<script> var #{id_array_var}=[" +
                ids.map{|id| "'" + id + "'"}.join(',') +
            "];</script>"
  html.html_safe
end

- (Object) draw_boolean(f, col, options = {})



89
90
91
# File 'app/helpers/edgar/field_helper.rb', line 89

def draw_boolean(f, col, options={})
  f.check_box(col.name, options)
end

- (Object) draw_checkbox(f, id, flag, bitset, id_array_var) (private)

draw Edgar flags specific checkbox



313
314
315
316
317
318
319
320
321
322
323
# File 'app/helpers/edgar/field_helper.rb', line 313

def draw_checkbox(f, id, flag, bitset, id_array_var)
  val       = f.object.send(:flags) || 0
  flag_val  = bitset.const_get(flag)
  tag(:input,
      type:     'checkbox',
      id:       id,
      name:     id,
      value:    flag_val,
      onChange: "Edgar.sum_bitset(#{id_array_var})",
      checked:  (val & flag_val) != 0 )
end

- (Object) draw_date(f, col_or_sym, options = {})

draw calendar date select

INPUTS

f

Form builder object.

col_or_sym

column object returned by rec.class.columns, or symbol

options

passed to calendar_date_select



99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'app/helpers/edgar/field_helper.rb', line 99

def draw_date(f, col_or_sym, options={})
  col_name  = get_column_name(col_or_sym)
  dom_id    = sprintf("%s_%s", f.object_name, col_name)
  f.text_field(col_name, id: dom_id) +
  javascript_tag(<<-EOJS)
    $(function(){
      $('##{dom_id}').datepicker({buttonImageOnly: true}).
          datepicker('option', {
            dateFormat:       'yy/mm/dd'
          });
    });
  EOJS
end

- (Object) draw_datetime(f, col_or_sym, options = {})

draw calendar datetime select

INPUTS

f

Form builder object.

col_or_sym

column object returned by rec.class.columns, or symbol

options

passed to calendar_date_select



119
120
121
122
123
# File 'app/helpers/edgar/field_helper.rb', line 119

def draw_datetime(f, col_or_sym, options={})
  col_name  = get_column_name(col_or_sym)
  f.text_field(col_name,
      value: datetime_fmt(f.object.send(col_name)))
end

- (Object) draw_enum(f, col_or_sym, enum = nil, options = {})

draw enum selection.

'Enum' in Edgar is a module which integer constants are defined. draw_enum() draws selection rather than simple integer text field.

Selection-option label is I18 supported by AR human_const_name API. See lib/edgar/model.rb rdoc.

EXAMPLE

Followings draws Question module's Priority selection on @question.priority integer column:

<%= edgar_form do |f| %>
    :
  <%= draw_enum(f, :priority) %>
    :
<% end %>

INPUTS

f

Form builder object.

col_or_sym

column object returned by rec.class.columns, or symbol

enum

enum module. When nil, guess by column name.

options

draw_enum options and/or passed to select helper.

Supported options

:choice_1st

additional 1st choice (mainly used SearchForm enum selection)

:class AR class which will be used for human_const_name()

SEE ALSO

get_enum()

get enum definition

draw_column_enum()

draw enum column in list

FIXME: choices for selection should be cached.



221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
# File 'app/helpers/edgar/field_helper.rb', line 221

def draw_enum(f, col_or_sym, enum=nil, options={})
  col_name            =  get_column_name(col_or_sym)
  enum                = model.const_get(col_name.to_s.camelize) if !enum
  sorted_elements     = enum.constants.sort{|a,b|
                            enum.const_get(a) <=> enum.const_get(b)}
  options_for_select  = options.dup
  choice_1st          = options_for_select.delete(:choice_1st)
  class_4_human_const = options_for_select.delete(:class) || f.object.class
  f.select(col_name,
            (choice_1st ? [choice_1st] : []) +
            sorted_elements.map{|member|
              [class_4_human_const.human_const_name(enum, member),
               enum.const_get(member)]},
            options_for_select)
end

- (Object) draw_field(f, col, options = {})

draw default field for col.type

options is passed to each rails helper. Following types are supported:

  • :date

  • :datetime

  • :integer

  • :boolean

  • :text

INPUTS

f

FormBuilder object

col

column info returned by AR.columns, or symbol

options

options hash passed to each helper.



76
77
78
79
80
81
82
83
84
85
86
87
# File 'app/helpers/edgar/field_helper.rb', line 76

def draw_field(f, col, options={})
  case col.type
  when :date
    draw_date(f, col, options[:date] || {})
  when :datetime
    draw_datetime(f, col, options[:datetime] || {})
  when :integer
    f.text_field(col.name, options[:integer])
  else
    f.text_field(col.name, options[:text])
  end
end

- (Object) draw_file(f, col_or_sym, options = {})

Field 'file_NN' in AR is handled as file attachement(upload/download) in Edgar. Where, NN is 2-digits from 00 to 99.

draw_file() helper draws file attachment(upload/download) user-interface for file_NN field. It supports:

  1. upload file (Create)

  2. download file (Read)

  3. upload another file (Update)

  4. clear the field (Delete)

Model

Integer value of file_NN column in any AR is interpreted a ID value to point to a FileInfo record. As NN means, any number of files (max 100) can be attached to any AR.

belongs_to/has_one relation can be declared between the AR and FileInfo, but it is not required. Those declarations are just for your customization level convenience.

attr_accessible(or attr_protected) to hide file_NN from mass-assignment *SHOULD BE* applied.

See Report model unit test for testing.

INPUTS

f

Form builder object.

col_or_sym

column object returned by rec.class.columns, or symbol

options

passed to select helper.

EXAMPLE

draw_file(f, :file_00) draws:

<input type=file id='file_info[file_00][uploaded_data]' ...>

SEE ALSO

ActiveRecord::Base#upsert_file_NN



278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
# File 'app/helpers/edgar/field_helper.rb', line 278

def draw_file(f, col_or_sym, options={})
  col_name  = get_column_name(col_or_sym)
  file_info = FileInfo.safe_find(f.object.send(col_name))
  error_wrapping(
    if file_info
      file_field_dom    = "file_info_#{col_name}_uploaded_data"
      file_link_dom     = "file_info_#{col_name}_link"

      file_field_sub(col_name, file_info, options.merge(:style=>'display:none')) +
      ' ' +
      (:span, :id=>file_link_dom) do
        link_to(file_info.filename,
            {:action    => 'file_download',
             :id        => f.object.id,
             :column    => col_name}) + ' ' +
        link_to_function("[#{I18n.t('clear')}]",
            sprintf("Edgar.clear_file('%s', '%s', '%s')",
                file_field_dom,
                "#{f.object_name}_#{col_name}",
                file_link_dom))
      end +
      f.hidden_field(col_name)
    else
      file_field_sub(col_name, FileInfo.new, options)
    end, f.object.errors.on(col_name)
  )
end

- (Object) draw_form_buttons(options = {})

Draw buttons for form.

When no CREATE/UPDATE permission, save button is disabled. It can be overwritten by options.

When no DELETE permission, delete button is disabled. It can be overwritten by options.

options may have:

:save

html options for 'save' button.

:search_form

html options for 'search_form' button.

:delete

html options for 'delete' button.



18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'app/helpers/edgar/field_helper.rb', line 18

def draw_form_buttons(options = {})
  cp_bitset = Edgar::ModelPermission::FlagsBitset
  create_or_update = cp_bitset::CREATE + cp_bitset::UPDATE
  result = tag(:input, {
      type:     'submit',
      name:     'commit',
      value:    I18n.t('save'),
      class:    '_edgar_form_save',
      disabled: !permitted?(create_or_update)}.merge(options[:save]||{}))
  search_form_js = <<-JS
      $('#edgar_form').hide();
      $('#edgar_search_form').show();
  JS
  result << tag(:input, {
      type:   'button',
      value:  t('search_form'),
      class:  '_edgar_form_search',
      onClick: search_form_js}.merge(options[:search_form] ||{}))
  result << tag(:input, type: 'button', value: t('clear'),
      onClick: "$.ajax('#{url_for(controller: params[:controller], action: 'clear')}.js')")

  delete_url  = polymorphic_path(@model, format: :js)
  hash        = {
      request_forgery_protection_token.to_s => form_authenticity_token
      }
  delete_url = delete_url + (delete_url.index('?') ? '&' : '?') +
      hash.to_query
  result << tag(:input, {
      type:     'button',
      value:    t('delete'),
      onClick:  "Edgar.destroy('#{delete_url}', '#{t('edgar.form.delete_confirm')}')",
      disabled: @model.new_record? || !permitted?(cp_bitset::DELETE),
      }.merge(options[:delete]||{}))
  result
end

- (Object) draw_question_history(question)



237
238
239
# File 'app/helpers/edgar/field_helper.rb', line 237

def draw_question_history(question)
  render :partial => '/questions/history', :locals=>{:question=>question}
end

- (Object) draw_search_form_buttons(f)



54
55
56
# File 'app/helpers/edgar/field_helper.rb', line 54

def draw_search_form_buttons(f)
  render 'edgar/search_form_buttons', f: f
end

- (Object) draw_search_save_popup



58
59
60
# File 'app/helpers/edgar/field_helper.rb', line 58

def draw_search_save_popup
  render :partial => 'edgar/search_save_popup'
end

- (Object) error_wrapping(html_tag, has_error) (private)

Same as ActionView::Helpers::InstanceTag class instance method



308
309
310
# File 'app/helpers/edgar/field_helper.rb', line 308

def error_wrapping(html_tag, has_error)
  has_error ? ActionView::Base.field_error_proc.call(html_tag, self) : html_tag
end

- (Object) file_field_sub(col_name, file_info, options) (private)

generate following file field:

<input type='file' name='file_info[file_NN][uploaded_data]' ...>


342
343
344
345
346
# File 'app/helpers/edgar/field_helper.rb', line 342

def file_field_sub(col_name, file_info, options)
  fields_for("file_info[#{col_name}]", file_info) do |f|
    f.file_field(:uploaded_data, {:size=>20}.merge(options))
  end
end

- (Object) find_col(rec, sym) (private)

find column info from name



326
327
328
# File 'app/helpers/edgar/field_helper.rb', line 326

def find_col(rec, sym)
  rec.class.columns.detect{|c| c.name == sym.to_s}
end

- (Object) get_column_name(col_or_sym) (private)

get column name from column object or symbol



331
332
333
334
335
336
337
# File 'app/helpers/edgar/field_helper.rb', line 331

def get_column_name(col_or_sym)
  if col_or_sym.is_a?(Symbol)
    col_or_sym
  else
    col_or_sym.name
  end
end