Class: AlForm

Inherits:
Object
  • Object
show all
Defined in:
lib/al_form.rb,
lib/al_form/multipart.rb,
lib/al_form/make_tiny_form.rb,
lib/al_form/make_tiny_sheet.rb,
lib/al_form/generate_sql_table.rb,
lib/al_form/generate_form_template.rb,
lib/al_form/generate_list_template.rb,
lib/al_form/generate_sheet_template.rb

Overview

フォームクラス

htmlフォームからの送信を受け取り、ユーザーアプリケーションへ渡す。

Defined Under Namespace

Classes: UploadedFile

Constant Summary

AL_LINE_EVEN_ODD =

HTMLタグ生成用クラス名テーブル

["al-line-even", "al-line-odd"]
METHOD_LIST =

ダイナミックローディングメソッド名テーブル

{
  :make_tiny_form=>"al_form/make_tiny_form",
  :make_tiny_form_main=>"al_form/make_tiny_form",
  :make_tiny_sheet=>"al_form/make_tiny_sheet",
  :generate_form_template=>"al_form/generate_form_template",
  :generate_sheet_template=>"al_form/generate_sheet_template",
  :generate_list_template=>"al_form/generate_list_template",
  :generate_sql_table=>"al_form/generate_sql_table",
}
@@request_get =
Hash

GETリクエストを解析してHash化した値のキャッシュ

{}
@@request_post =
Hash

POSTリクエストを解析してHash化した値のキャッシュ

{}
@@flag_request_oversize =
Boolean

リクエストサイズ過大エラーフラグ

false

Instance Attribute Summary (collapse)

Class Method Summary (collapse)

Instance Method Summary (collapse)

Constructor Details

- (AlForm) initialize(*widgets)

constructor

Parameters:

  • widgets (Array)

    ウィジェットの配列



147
148
149
150
151
152
153
154
155
156
157
158
# File 'lib/al_form.rb', line 147

def initialize( *widgets )
  @widgets = {}
  @values = {}
  @validation_messages = {}
  @validation_messages_user_count = 0
  @method = "POST"
  @action = Alone::request_uri()
  @tag_attr = {}
  @flag_setvalue_done = false

  set_widgets( widgets )
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

- (Object) method_missing(name, *args)

ダイナミックローディング用フック



514
515
516
517
518
519
520
521
# File 'lib/al_form.rb', line 514

def method_missing( name, *args )
  if METHOD_LIST[ name ]
    require METHOD_LIST[ name ]
    __send__( name, *args )
  else
    raise NoMethodError, "undefined method `#{name}' for AlForm"
  end
end

Instance Attribute Details

- (String) action

Returns HTMLフォームのactionアトリビュート

Returns:

  • (String)

    HTMLフォームのactionアトリビュート



133
134
135
# File 'lib/al_form.rb', line 133

def action
  @action
end

- (Boolean) flag_setvalue_done

Returns 値のセットが終わっているかのフラグ(バリデーション前)

Returns:

  • (Boolean)

    値のセットが終わっているかのフラグ(バリデーション前)



139
140
141
# File 'lib/al_form.rb', line 139

def flag_setvalue_done
  @flag_setvalue_done
end

- (String) method

Returns HTMLフォームのmethodアトリビュート “GET” or “POST”

Returns:

  • (String)

    HTMLフォームのmethodアトリビュート “GET” or “POST”



130
131
132
# File 'lib/al_form.rb', line 130

def method
  @method
end

- (Hash) tag_attr

Returns HTMLタグ生成時の追加アトリビュート

Returns:

  • (Hash)

    HTMLタグ生成時の追加アトリビュート



136
137
138
# File 'lib/al_form.rb', line 136

def tag_attr
  @tag_attr
end

- (Hash) validation_messages (readonly)

Returns バリデーションメッセージ。キーがウィジェット名のシンボル、値がメッセージ文字列

Returns:

  • (Hash)

    バリデーションメッセージ。キーがウィジェット名のシンボル、値がメッセージ文字列



127
128
129
# File 'lib/al_form.rb', line 127

def validation_messages
  @validation_messages
end

- (Hash) values (readonly)

Returns バリデーションを通過したリクエストの値

Returns:

  • (Hash)

    バリデーションを通過したリクエストの値



124
125
126
# File 'lib/al_form.rb', line 124

def values
  @values
end

- (Hash) widgets (readonly)

Returns このインスタンスが保持するウィジェット。キーがウィジェット名のシンボル、値がウィジェットのインスタンス

Returns:

  • (Hash)

    このインスタンスが保持するウィジェット。キーがウィジェット名のシンボル、値がウィジェットのインスタンス



121
122
123
# File 'lib/al_form.rb', line 121

def widgets
  @widgets
end

Class Method Details

+ (Object) fetch_request_multipart

(AlForm) POSTリクエストの取り込み / multipart



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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# File 'lib/al_form/multipart.rb', line 18

def self.fetch_request_multipart()
  req = {}

  #
  # extract boundary
  #
  boundary = nil
  ENV['CONTENT_TYPE'].split( /\s?;\s/ ).each do |a|
    if /\s*([^=]+)(=([^\s]*))?/ =~ a
      if $1 == 'boundary'
        boundary = '--' + $3
      end
    end
  end
  return if ! boundary

  boundary.force_encoding( Encoding::ASCII_8BIT )

  #
  # process post data
  # STRATEGY:
  #  ステートマシンを使って解析する
  #  ステートは、NONE -> HEADER -> CONTENT_START -> CONTENT_NEXT と遷移する
  #
  STDIN.set_encoding( "ASCII-8BIT" )          # TODO: ruby1.9 only
  remain_bytes = ENV['CONTENT_LENGTH'].to_i
  content = {}
  file = nil
  state = :STATE_NONE
  while remain_bytes > 0 && text = STDIN.gets do
    remain_bytes -= text.length

    #
    # check boundary
    #
    if text.start_with?( boundary )
      state = :STATE_HEADER
      next  if ! content[:name]

      key = content[:name].to_sym
      content[:data_body].force_encoding( AL_CHARSET )
      content[:data_body].chomp!

      case req[key]
      when NilClass
        req[key] = file ? content : content[:data_body]

      when String
        req[key] = [ req[key], content[:data_body] ]

      when Array
        req[key] << content[:data_body]
      end

      if file
        file.flush
        if file.size >= 2
          file.truncate( file.size - 2 )        # -2 is CR,LF
        end
        content[:size] = file.size
        file.close
      end

      content = {}
      file = nil
      next
    end

    #
    # process each content
    #
    case state
    when :STATE_HEADER
      case text.chop
      when /^Content-Disposition:(.+)$/i
        $1.split( ';' ).each do |a|
          if / *([^=]+)(="(.*)")?/ =~ a
            if (content[$1.to_sym] = $3) != nil
              content[$1.to_sym].force_encoding( AL_CHARSET )
            end
          end
        end
        
      when /^Content-Type: *([^ ]+)$/i
        content[:content_type] = $1

      when ''                         # data region starts at next line
        state = :STATE_CONTENT_START
      end
      

    when :STATE_CONTENT_START
      if content[:filename]           # this is input type="file" tag
        uplfile = UploadedFile.new( self )
        content[:tmp_name] = uplfile.path
        file = uplfile.file
        file.write( text )
        content[:data_body] = ''
      else
        content[:data_body] = text    # this is other input tag
      end
      state = :STATE_CONTENT_NEXT
      

    when :STATE_CONTENT_NEXT
      if file
        file.write( text )
      else
        content[:data_body] << text
      end
    end

  end  # end of all read

  @@request_post = req
end

+ (Object, NilClass) get_parameter(w)

単一パラメータの取得/使い捨てミニフォーム機能

Examples:

id = AlForm.get_parameter( AlText.new( 'id', :validator=>/^d+$/ ) )

Parameters:

  • w (AlWidget)

    取得するパラメータを表すウィジェット

Returns:

  • (Object)

    取得値。データタイプは、Widgetによって変わる。

  • (NilClass)

    取得できなかった(エラー)の場合。



96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/al_form.rb', line 96

def self.get_parameter( w )
  case ENV["REQUEST_METHOD"]
  when "GET"
    AlForm.prefetch_request_get()
    value = @@request_get[w.name.to_sym]
  when "POST"
    AlForm.prefetch_request_post()
    value = @@request_post[w.name.to_sym]
  else
    raise "method error. need GET or POST."
  end

  if value
    # GET/POSTされている。フィルタをかけてウィジェットに渡した結果を返す。
    w.set_value( w.filter ? eval( w.filter ) : value )
    return w.validate() ? w.value : nil
  else
    # ウィジェットの初期値を返す。
    return w.value
  end
end

+ (Object) prefetch_request_get

GETリクエストのキャッシュへの取り込み



37
38
39
40
41
42
# File 'lib/al_form.rb', line 37

def self.prefetch_request_get()
  return if ! @@request_get.empty?
  return if ! ENV["QUERY_STRING"]

  @@request_get = parse_urlencoded( ENV["QUERY_STRING"] )
end

+ (Object) prefetch_request_post

POSTリクエストのキャッシュへの取り込み



48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/al_form.rb', line 48

def self.prefetch_request_post()
  return if ! @@request_post.empty?

  # check request size
  if ENV["CONTENT_LENGTH"].to_i > AL_FORM_MAX_CONTENT_LENGTH
    @@flag_request_oversize = true
  end

  # proc request data.
  if ENV['CONTENT_TYPE'] && ENV['CONTENT_TYPE'].start_with?( "multipart/form-data" )
    require 'al_form/multipart'
    fetch_request_multipart()
  else
    @@request_post = parse_urlencoded( $stdin.read( ENV["CONTENT_LENGTH"].to_i ) )
  end
end

+ (Hash) request_get

Note:

渡された生データが入っているので、通常は使わない。

getter / request_get

Returns:

  • (Hash)

    GETリクエストのキャッシュ



72
73
74
# File 'lib/al_form.rb', line 72

def self.request_get()
  return @@request_get
end

+ (Hash) request_post

Note:

渡された生データが入っているので、通常は使わない。

getter / request_post

Returns:

  • (Hash)

    POSTリクエストのキャッシュ



83
84
85
# File 'lib/al_form.rb', line 83

def self.request_post()
  return @@request_post
end

Instance Method Details

- (Object) add_message(message)

Note:

ユーザプログラムから、任意のメッセージをセットできる。 バリデーション validate() を行う前にクリアされるので、注意する。

メッセージの追加

Parameters:

  • message (String)

    メッセージ



296
297
298
299
# File 'lib/al_form.rb', line 296

def add_message( message )
  @validation_messages["al_user#{@validation_messages_user_count}"] = message
  @validation_messages_user_count += 1
end

- (Object) add_widget(widget)

ウィジェット追加

Parameters:

  • widget (AlWidget)

    ウィジェット



194
195
196
# File 'lib/al_form.rb', line 194

def add_widget( widget )
  @widgets[ widget.name.to_sym ] = widget
end

- (Object) checked(name, value) Also known as: selected

Note:

チェックボックス、または、ラジオボタンの、checked属性を生成する。 htmlをべたに書く時にのみ使用する。

inputタグ中の checked 属性生成

Examples:

<input name=“radio1” type=“radio” value=“r1” <%= form.checked( :radio1, “r1” ) %> >

Parameters:

  • name (String, Symbol)

    ウィジェット識別名

  • value (String, Symbol)

    inputタグのvalue=“” と同じ値を指定する。



477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
# File 'lib/al_form.rb', line 477

def checked( name, value )
  widget = @widgets[ name.to_sym ]
  case widget
  when AlCheckboxes
    return (widget.value.include?( value.to_sym ) || widget.value.include?( value.to_s )) ? "checked": ""

  when AlOptions
    return (widget.value && widget.value.to_sym == value.to_sym) ? "selected": ""

  when AlRadios
    return (widget.value && widget.value.to_sym == value.to_sym) ? "checked": ""

  else
    raise "Object not match. needs AlCheckboxes, AlOptions or AlRadios"
  end
end

- (Object) delete_widget(name)

ウィジェット削除

Parameters:

  • name (String, Symbol)

    ウィジェット識別名



204
205
206
207
# File 'lib/al_form.rb', line 204

def delete_widget( name )
  @widgets.delete( name.to_sym )
  @values.delete( name.to_sym )
end

- (Boolean) fetch_request(method = nil)

GET/POSTリクエストの取り込み

Parameters:

  • method (String) (defaults to: nil)

    メソッド “GET” or “POST”

Returns:

  • (Boolean)

    成否



322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
# File 'lib/al_form.rb', line 322

def fetch_request( method = nil )
  #
  # リクエストを取得し、@@request_XXXにキャッシュする。
  #
  case method || ENV["REQUEST_METHOD"]
  when "GET"
    AlForm.prefetch_request_get()
    req = @@request_get

  when "POST"
    return false if ENV["REQUEST_METHOD"] != "POST"
    AlForm.prefetch_request_post()
    req = @@request_post

  else
    raise "method error. need GET or POST."
  end

  #
  # リクエストが正当なものか確認
  #
  if @@flag_request_oversize
    add_message( "サイズが大きすぎます。" )
    return false
  end
  return false  if req.empty?
  flag_exist = false
  @widgets.each_key do |k|
    break  if flag_exist = req.has_key?( k )
  end
  return false  if ! flag_exist

  #
  # 各ウィジェットに、値を設定
  #
  @widgets.each do |k,w|
    value = req[k] ? req[k] : ""
    w.set_value( w.filter ? eval( w.filter ) : value )
  end

  @flag_setvalue_done = true
  return true
end

- (Object) generate_form_template(arg = {})

簡易フォームテンプレートの生成 AlTemplateの使用を前提としたフォームのテンプレートを生成する。

Parameters:

  • arg (defaults to: {})

    引数ハッシュ

Options Hash (arg):

  • :use_table (Boolean)

    テーブルタグを利用した整形

  • :use_error_class (Boolean)

    バリデーションエラーの時、al-form-label-errorを出力するための動的コードを埋め込む



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
53
54
55
56
57
58
59
60
61
62
# File 'lib/al_form/generate_form_template.rb', line 21

def generate_form_template( arg = {} )
  flags = { :use_table=>true, :with_error_class=>true }
  flags.merge!( arg )

  r = "<%= header_section %>\n<title></title>\n\n"
  r << "<%= body_section %>\n\n"
  r << "<%= @form.get_messages_by_html() %>\n\n"
  r << %Q(<form method="<%= @form.method %>" action="<%= @form.action %>">\n)

  if flags[:use_table]
    r << %Q(<table class="al-form-table">\n)
    lines = 0
    @widgets.each do |k,w|
      lines += 1
      r << %Q(  <tr class="#{AL_LINE_EVEN_ODD[lines & 1]} #{w.name}\">\n)
      if flags[:with_error_class]
        r << %Q(    <td class="al-form-label<%= @form.validation_messages[:#{w.name}] ? "-error" : "" %>">#{w.label}</td>\n)
      else
        r << %Q(    <td class="al-form-label">#{w.label}</td>\n)
      end
      r << %Q(    <td class="al-form-value"><%= @form.make_tag(:#{w.name}) %></td>\n  </tr>\n\n)
    end
    r << "</table>\n"
    
  else
    lines = 0
    @widgets.each do |k,w|
      lines += 1
      r << %Q(  <div class="#{AL_LINE_EVEN_ODD[lines & 1]} #{w.name}\">\n)
      if flags[:with_error_class]
        r << %Q(    <span class="al-form-label<%= @form.validation_messages[:#{w.name}] ? "-error" : "" %>">#{w.label}</span>\n)
      else
        r << %Q(    <span class="al-form-label">#{w.label}</span>\n)
      end
      r << %Q(    <span class="al-form-value"><%= @form.make_tag(:#{w.name}) %></span>\n  </div>\n\n)
    end
  end

  r << "</form>\n"
  r << "\n<%= footer_section %>"
  return r
end

- (Object) generate_list_template(arg = {})

簡易リスト表示テンプレートの生成 AlTemplateの使用を前提とした一覧リスト表示形式のテンプレートを生成する。

Parameters:

  • arg (defaults to: {})

    引数ハッシュ

Options Hash (arg):

  • :use_table (Boolean)

    テーブルタグを利用した整形



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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/al_form/generate_list_template.rb', line 20

def generate_list_template( arg = {} )
  flags = { :use_table=>true }
  flags.merge!( arg )

  r = %Q(<%= header_section %>\n<title></title>\n\n)
  r << %Q(<%= body_section %>\n\n)

  r << %Q(<table class="al-list-table">\n)
  r << %Q(  <tr>\n)
  @widgets.each do |k,w|
    next if w.class == AlHidden || w.class == AlPassword || w.hidden || w.is_a?( AlButton )
    r << %Q(    <th>#{w.label}</th>\n)
  end
  r << %Q(    <th>&nbsp;</th>\n)
  r << %Q(  </tr>\n)

  r << %Q(  <% @datas.each do |d| %>\n)
  r << %Q(  <tr>\n)
  @widgets.each do |k,w|
    next if w.class == AlHidden || w.class == AlPassword || w.hidden || w.is_a?( AlButton )
    r << %Q(    <td><%= @form.widgets[:#{w.name}].make_value( d[:#{w.name}] ) %></td>\n)
  end

  r << %Q(    <td class="al-navigation">\n)
  r << %Q(      <a href="<%=h make_uri_key(d, :action=>"update") %>">変更</a>\n)
  r << %Q(      <a href="<%=h make_uri_key(d, :action=>"delete") %>">削除</a>\n)
  r << %Q(    </td>\n)

  r << %Q(  </tr>\n)
  r << %Q(  <% end %>\n)
  r << %Q(</table>\n)
  r << %Q(<hr>\n)


  r << %Q(  <div class="al-navigation">
  <% if @persist.get_previous_offset() %>
  <a href="<%=h make_uri( @request.merge({:offset=>@persist.get_previous_offset()}) ) %>">≪前ページ</a>
  <% else %>
  <span class="al-inactive">≪前ページ</span>
  <% end %>

  <% if @persist.get_next_offset() %>
  <a href="<%=h make_uri( @request.merge({:offset=>@persist.get_next_offset()}) ) %>">次ページ≫</a>
  <% else %>
  <span class="al-inactive">次ページ≫</span>
  <% end %>

  <a href="<%=h make_uri( :action=>"create" ) %>">新規登録</a>
</div>
)

  r << %Q(\n<%= footer_section %>)
  return r
end

- (Object) generate_sheet_template(arg = {})

簡易内容表示テンプレートの生成 AlTemplateの使用を前提とした単票形式表示のテンプレートを生成する。

Parameters:

  • arg (defaults to: {})

    引数ハッシュ

Options Hash (arg):

  • :use_table (Boolean)

    テーブルタグを利用した整形



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
53
54
55
56
# File 'lib/al_form/generate_sheet_template.rb', line 20

def generate_sheet_template( arg = {} )
  flags = { :use_table=>true }
  flags.merge!( arg )

  r = "<%= header_section %>\n<title></title>\n\n"
  r << "<%= body_section %>\n\n"

  if flags[:use_table]
    r << %Q(<table class="al-sheet-table">\n)
    lines = 0
    @widgets.each do |k,w|
      next if w.is_a?( AlButton )

      lines += 1
      r << %Q(  <tr class="#{AL_LINE_EVEN_ODD[lines & 1]} #{w.name}">\n)
      r << %Q(    <td class="al-sheet-label">#{w.label}</td>\n)
      r << %Q(    <td class="al-sheet-value"><%= @form.make_value(:#{w.name}) %></td>\n)
      r << %Q(  </tr>\n\n)
    end
    r << "</table>\n"
    
  else
    lines = 0
    @widgets.each do |k,w|
      next if w.is_a?( AlButton )

      lines += 1
      r << %Q(  <div class="#{AL_LINE_EVEN_ODD[lines & 1]} #{w.name}">\n)
      r << %Q(    <span class="al-sheet-label">#{w.label}</span>\n)
      r << %Q(    <span class="al-sheet-value"><%= form.make_value(:#{w.name} ) %></span>\n)
      r << %Q(  </div>\n\n)
    end
  end

  r << "\n<%= footer_section %>"
  return r
end

- (String) generate_sql_table(tname = "TABLENAME")

テーブル作成SQLのひな形作成

Parameters:

  • tname (String) (defaults to: "TABLENAME")

    テーブル名

Returns:

  • (String)

    SQL



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
# File 'lib/al_form/generate_sql_table.rb', line 19

def generate_sql_table( tname = "TABLENAME" )
  a = []
  @widgets.each do |k,w|
    case w
    when AlInteger
      c = "#{k} integer"
    when AlFloat
      c = "#{k} double precision"
    when AlTimestamp
      c = "#{k} timestamp"
    when AlDate
      c = "#{k} date"
    when AlTime
      c = "#{k} time"
    when AlButton, AlSubmit
      next
    else
      c = "#{k} text"
    end

    if w.required
      c << " not null"
    end
    a << c
  end
  return "create table #{tname} (#{a.join( ', ' )});"
end

- (String) get_messages_by_html

html形式でメッセージの取得

Returns:

  • (String)

    html形式でメッセージを返す



307
308
309
310
311
312
313
# File 'lib/al_form.rb', line 307

def get_messages_by_html()
  r = ""
  @validation_messages.each do |k,v|
    r << Alone::escape_html_br(v) << "<br>\n"
  end
  return r
end

- (Object) get_tainted_value(name) Also known as: -

Note:

alias - は、テンプレートで使われることを想定して定義した。 プログラム中では、使わない方が良いのではないか。

バリデーション前の値取得

Parameters:

  • name (String, Symbol)

    ウィジェット識別名

Returns:

  • (Object)



283
284
285
# File 'lib/al_form.rb', line 283

def get_tainted_value( name )
  return (w = @widgets[ name.to_sym ]) ? w.value : nil
end

- (Object) get_value(name) Also known as: []

Note:

バリデーション後の値を取得する。 値として何が返るかは、ウィジェットの種類によって変わるので、 詳しくは各ウィジェットを参照。

値取得

Parameters:

  • name (String, Symbol)

    ウィジェット識別名

Returns:

  • (Object)



269
270
271
# File 'lib/al_form.rb', line 269

def get_value( name )
  return @values[name.to_sym]
end

- (AlWidget) get_widget(name)

ウィジェットの取得

Parameters:

  • name (String, Symbol)

    ウィジェット識別名

Returns:



216
217
218
# File 'lib/al_form.rb', line 216

def get_widget( name )
  return @widgets[ name.to_sym ]
end

- (String) make_tag(name, arg = {})

Note:

指定された名前を持つウィジェットのタグを生成し返す。

HTMLタグの生成

Examples:

<%= form.make_tag( :text1 ) %>

Parameters:

  • name (String, Symbol)

    ウィジェット識別名

  • arg (Hash) (defaults to: {})

    htmlタグへ追加するアトリビュートを指定

Returns:

  • (String)

    htmlタグ



445
446
447
448
449
450
# File 'lib/al_form.rb', line 445

def make_tag( name, arg = {} )
  widget = @widgets[ name.to_sym ]
  raise %Q(No widget defined, named "#{name}".)  if ! widget

  return widget.make_tag( arg )
end

- (String) make_tiny_form(arg = {})

Note:

簡易フォームの自動生成

tableタグを使って、位置をそろえている。

Parameters:

  • arg (Hash) (defaults to: {})

    htmlタグへ追加するアトリビュートを指定

Returns:

  • (String)

    生成したHTML



21
22
23
24
25
26
27
# File 'lib/al_form/make_tiny_form.rb', line 21

def make_tiny_form( arg = {} )
  r = %Q(<form method="#{@method}" action="#{Alone::escape_html(@action)}")
  (@tag_attr.merge arg).each do |k,v|
    r << %Q( #{k}="#{Alone::escape_html(v)}")
  end
  return "#{r}>\n#{make_tiny_form_main()}</form>\n"
end

- (Object) make_tiny_form_main

Note:

簡易フォームの自動生成 メインメソッド

TODO: アプリケーションからこのメソッドが独自によばれることがなさそうなら

make_tiny_form()へ吸収合併を考えること。


37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/al_form/make_tiny_form.rb', line 37

def make_tiny_form_main()
  lines = 0
  r = %Q(<table class="al-form-table">\n)
  hidden = ""
  @widgets.each do |k,w|
    if w.hidden
      hidden << w.make_tag()
      next
    end

    lines += 1
    r << %Q(  <tr class="#{AL_LINE_EVEN_ODD[lines & 1]} #{w.name}">\n)
    if @validation_messages[ k ]
      r << %Q(    <td class="al-form-label-error">#{w.label}</td>\n)
    else
      r << %Q(    <td class="al-form-label">#{w.label}</td>\n)
    end
    r << %Q(    <td class="al-form-value">#{w.make_tag()}</td>\n  </tr>\n)
  end
  r << "</table>\n"
  if ! hidden.empty?
    r << "<div>#{hidden}</div>\n"
  end

  return r
end

- (String) make_tiny_sheet

Note:

簡易内容表示

tableタグを使って、位置をそろえている。

Returns:

  • (String)

    生成したHTML



20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/al_form/make_tiny_sheet.rb', line 20

def make_tiny_sheet()
  lines = 0
  r = %Q(<table class="al-sheet-table">\n)
  @widgets.each do |k,w|
    next if w.is_a?( AlButton ) || w.hidden

    lines += 1
    r << %Q(  <tr class="#{AL_LINE_EVEN_ODD[lines & 1]} #{w.name}">\n)
    r << %Q(    <td class="al-sheet-label">#{w.label}</td>\n)
    r << %Q(    <td class="al-sheet-value">#{w.make_value()}</td>\n  </tr>\n)
  end
  r << "</table>\n"

  return r
end

- (String) make_value(name)

Note:

make_tag()との対称性をもたせるために存在する。

HTML値の生成

Parameters:

  • name (String, Symbol)

    ウィジェット識別名

Returns:

  • (String)

    html文字列



460
461
462
463
464
465
# File 'lib/al_form.rb', line 460

def make_value( name )
  widget = @widgets[ name.to_sym ]
  raise %Q(No widget defined, named "#{name}".)  if ! widget

  return widget.make_value()
end

- (Object) set_value(name, value) Also known as: []=

Note:

受け付けるvalueは、ウィジェットの種類によって変わる。 詳しくは、各ウィジェットを参照。

値のセット

Parameters:

  • name (String, Symbol)

    ウィジェット識別名

  • value (String, Array)

    セットする値



229
230
231
232
233
# File 'lib/al_form.rb', line 229

def set_value( name, value )
  k = name.to_sym
  @widgets[k].set_value( value )
  @values[k] = @widgets[k].value      # valueは、Widgetごとの都合による加工がされているかもしれない
end

- (Object) set_values(values) Also known as: values=

Note:

nilを与えられた場合は、何も行わない。 それ以外の場合は、fetch_request()を呼び出したのと同様、 validate()の値自動取得が働かなくなるので注意する。

値の一括セット

Parameters:

  • values (Hash, NilClass)

    セットする値



245
246
247
248
249
250
251
252
253
254
255
256
# File 'lib/al_form.rb', line 245

def set_values( values )
  return if ! values
  raise "set_values() needs Hash parameter." if values.class != Hash

  values.each do |k,v|
    k = k.to_sym
    next  if ! @widgets[k]
    @widgets[k].set_value( v )
    @values[k] = @widgets[k].value      # valueは、Widgetごとの都合による加工がされているかもしれない
  end
  @flag_setvalue_done = true
end

- (Object) set_widgets(*widgets) Also known as: widgets=

ウィジェットのセット

Parameters:

  • widgets (Array)

    ウィジェットの配列



180
181
182
183
184
185
# File 'lib/al_form.rb', line 180

def set_widgets( *widgets )
  raise "Parameter type error. need Array."  if widgets.class != Array
  widgets.flatten.each do |w|
    @widgets[ w.name.to_sym ] = w
  end
end

- (Object) use_get_method(arg = {})

Note:

form method=“GET” と、AlControllerの仕組みを共存させるためのメソッド。

コントローラ使用時に、フォームでmethod=“GET”を使う

Parameters:

  • arg (Hash) (defaults to: {})

    a customizable set of options

Options Hash (arg):

  • :ctrl (String)

    コントローラ名

  • :action (String)

    アクション名



168
169
170
171
172
# File 'lib/al_form.rb', line 168

def use_get_method( arg = {} )
  @widgets[:ctrl] = AlHidden.new( "ctrl", :value=>(arg[:ctrl] || Alone::ctrl) );
  @widgets[:action] = AlHidden.new( "action", :value=>(arg[:action] || Alone::action) );
  @method = "GET"
end

- (Boolean) validate(names = nil)

Note:

引数を与えなければ、すべてのウィジェットについてバリデーションを実施する バリデーションが成功して、はじめて @values に使える値が用意される。

バリデーション

Parameters:

  • names (Array) (defaults to: nil)

    バリデーションするウィジェット名の配列

Returns:

  • (Boolean)

    成否



375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
# File 'lib/al_form.rb', line 375

def validate( names = nil )
  @validation_messages.clear

  #
  # リクエストの取得がまだ行われていないなら、自動で取得する
  #
  if ! @flag_setvalue_done
    return false  if ! fetch_request()
  end

  case names
  when NilClass
    #
    # すべてのウィジェットについてバリデーションを実施
    #
    @widgets.each do |k,w|
      next  if w.class == AlSubmit    # valueをとりたくないのでskip
      if w.validate()
        @values[k] = w.value
      else
        @validation_messages[k] = w.message
      end
    end

  when Array
    #
    # 選択的にバリデーションを実施
    #
    names.each do |k|
      k = k.to_sym
      w = @widgets[k]
      raise "Not found widget '#{k}'." if ! w
      next  if w.class == AlSubmit    # valueをとりたくないのでskip
      if w.validate()
        @values[k] = w.value
      else
        @validation_messages[k] = w.message
      end
    end

  when String, Symbol
    #
    # 一つだけバリデーションを実施
    #
    k = names.to_sym
    w = @widgets[k]
    if w.validate()
      @values[k] = w.value
    else
      @validation_messages[k] = w.message
    end

  else
    raise 'validate() needs an array, string or symbol argument.'

  end

  return @validation_messages.empty? ? true: false
end