Class: AlForm

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

Overview

フォームクラス

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

Defined Under Namespace

Classes: UploadedFile

Constant Summary collapse

FILTER_STRIP =

:filter用、前後空文字削除フィルター

lambda { |s| s.strip!; s }
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

#initialize(*widgets) ⇒ AlForm

(AlForm) constructor

Parameters:

  • widgets (Array)

    ウィジェットの配列



156
157
158
159
160
161
162
163
164
165
166
167
# File 'lib/al_form.rb', line 156

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

#method_missing(name, *args) ⇒ Object

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



529
530
531
532
533
534
535
536
# File 'lib/al_form.rb', line 529

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

#actionString

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

Returns:

  • (String)

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



142
143
144
# File 'lib/al_form.rb', line 142

def action
  @action
end

#flag_setvalue_doneBoolean

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

Returns:

  • (Boolean)

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



148
149
150
# File 'lib/al_form.rb', line 148

def flag_setvalue_done
  @flag_setvalue_done
end

#methodString

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

Returns:

  • (String)

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



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

def method
  @method
end

#tag_attrHash

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

Returns:

  • (Hash)

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



145
146
147
# File 'lib/al_form.rb', line 145

def tag_attr
  @tag_attr
end

#validation_messagesHash (readonly)

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

Returns:

  • (Hash)

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



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

def validation_messages
  @validation_messages
end

#valuesHash (readonly)

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

Returns:

  • (Hash)

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



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

def values
  @values
end

#widgetsHash (readonly)

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

Returns:

  • (Hash)

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



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

def widgets
  @widgets
end

Class Method Details

.fetch_request_multipartObject

(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

.get_parameter(w) ⇒ Object, NilClass

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

Examples:

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

Parameters:

  • w (AlWidget)

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

Returns:

  • (Object)

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

  • (NilClass)

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



106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'lib/al_form.rb', line 106

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( apply_filter( w.filter, value ))
    return w.validate() ? w.value : nil
  else
    # ウィジェットの初期値を返す。
    return w.value
  end
end

.prefetch_request_getObject

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



35
36
37
38
39
40
# File 'lib/al_form.rb', line 35

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

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

.prefetch_request_postObject

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



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.rb', line 46

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 multipart request data.
  if ENV["CONTENT_TYPE"] && ENV["CONTENT_TYPE"].start_with?("multipart/form-data")
    require "al_form/multipart"
    fetch_request_multipart()
    return
  end

  # read post data
  if ENV["CONTENT_LENGTH"]
    txt = $stdin.read( ENV["CONTENT_LENGTH"].to_i )
  else
    txt = $stdin.read()
  end

  if ENV["CONTENT_TYPE"].start_with?("application/x-www-form-urlencoded")
    @@request_post = parse_urlencoded( txt )
  else
    @@request_post[""] = txt
  end
end

.request_getHash

Note:

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

getter / request_get

Returns:

  • (Hash)

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



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

def self.request_get()
  return @@request_get
end

.request_postHash

Note:

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

getter / request_post

Returns:

  • (Hash)

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



93
94
95
# File 'lib/al_form.rb', line 93

def self.request_post()
  return @@request_post
end

Instance Method Details

#add_message(message) ⇒ Object

Note:

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

メッセージの追加

Parameters:

  • message (String)

    メッセージ



305
306
307
308
# File 'lib/al_form.rb', line 305

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

#add_widget(widget) ⇒ Object

ウィジェット追加

Parameters:

  • widget (AlWidget)

    ウィジェット



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

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

#checked(name, value) ⇒ Object 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=“” と同じ値を指定する。



492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
# File 'lib/al_form.rb', line 492

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

#delete_widget(name) ⇒ Object

ウィジェット削除

Parameters:

  • name (String, Symbol)

    ウィジェット識別名



213
214
215
216
# File 'lib/al_form.rb', line 213

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

#fetch_request(method = nil) ⇒ Boolean, String

Note:

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

POSTされたデータのタイプが application/x-www-form-urlencoded もしくは、 multipart/form-data ではない場合は、POSTデータそのものを返す。

Parameters:

  • method (String) (defaults to: nil)

    メソッド “GET” or “POST”

Returns:

  • (Boolean)

    成否

  • (String)

    POSTされたデータ(see note)



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
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
# File 'lib/al_form.rb', line 336

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 req[""]  if req[""]  # return posted string. e.g. JSON.

  flag_exist = false
  @widgets.each {|k,w|
    next if k == :ctrl || k == :action
    break if (flag_exist = req.has_key?(k))
  }
  return false  if !flag_exist

  #
  # 各ウィジェットに、値を設定
  #
  @widgets.each { |k,w|
    w.set_value( AlForm::apply_filter( w.filter, req[k] ? req[k] : "" ))
  }

  @flag_setvalue_done = true
  return true
end

#generate_form_template(arg = {}) ⇒ Object

簡易フォームテンプレートの生成 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
# 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)
    @widgets.each do |k,w|
      r << %Q(  <tr class="#{w.name}\">\n)
      if flags[:with_error_class]
        r << %Q(    <td class="al-form-label<%= @form.validation_messages[:#{w.name}] ? "-error" : "" %>">#{w.label}\n)
      else
        r << %Q(    <td class="al-form-label">#{w.label}\n)
      end
      r << %Q(    <td class="al-form-value"><%= @form.make_tag(:#{w.name}) %>\n  </tr>\n\n)
    end
    r << "</table>\n"

  else
    @widgets.each do |k,w|
      r << %Q(  <div class="#{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

#generate_list_template(arg = {}) ⇒ Object

簡易リスト表示テンプレートの生成 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
# 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}\n)
  end
  r << %Q(    <th>&nbsp;\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}] ) %>\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(  </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

#generate_sheet_template(arg = {}) ⇒ Object

簡易内容表示テンプレートの生成 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
# 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)
    @widgets.each do |k,w|
      next if w.is_a?( AlButton )

      r << %Q(  <tr class="#{w.name}">\n)
      r << %Q(    <td class="al-sheet-label">#{w.label}\n)
      r << %Q(    <td class="al-sheet-value"><%= @form.make_value(:#{w.name}) %>\n)
      r << %Q(  </tr>\n\n)
    end
    r << "</table>\n"

  else
    @widgets.each do |k,w|
      next if w.is_a?( AlButton )

      r << %Q(  <div class="#{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

#generate_sql_table(tname = "TABLENAME") ⇒ String

テーブル作成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

#get_messages_by_htmlString

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

Returns:

  • (String)

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



316
317
318
319
320
321
322
# File 'lib/al_form.rb', line 316

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

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

Note:

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

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

Parameters:

  • name (String, Symbol)

    ウィジェット識別名

Returns:

  • (Object)



292
293
294
# File 'lib/al_form.rb', line 292

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

#get_value(name) ⇒ Object Also known as: []

Note:

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

値取得

Parameters:

  • name (String, Symbol)

    ウィジェット識別名

Returns:

  • (Object)



278
279
280
# File 'lib/al_form.rb', line 278

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

#get_widget(name) ⇒ AlWidget

ウィジェットの取得

Parameters:

  • name (String, Symbol)

    ウィジェット識別名

Returns:



225
226
227
# File 'lib/al_form.rb', line 225

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

#make_tag(name, appendix_tag = {}) ⇒ String

Note:

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

(AlForm) HTMLタグの生成

Examples:

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

Parameters:

  • name (String, Symbol)

    ウィジェット識別名

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

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

Returns:

  • (String)

    htmlタグ



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

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

  return widget.make_tag( appendix_tag )
end

#make_tiny_form(appendix_tag = {}) ⇒ String

Note:

簡易フォームの自動生成

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

Parameters:

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

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

Returns:

  • (String)

    生成したHTML



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

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

#make_tiny_form_mainObject

Note:

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

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

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


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

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

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

  return r
end

#make_tiny_sheetString

Note:

簡易内容表示

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

Returns:

  • (String)

    生成したHTML



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

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

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

  return r
end

#make_value(name) ⇒ String

Note:

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

(AlForm) HTML値の生成

Parameters:

  • name (String, Symbol)

    ウィジェット識別名

Returns:

  • (String)

    html文字列



475
476
477
478
479
480
# File 'lib/al_form.rb', line 475

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

  return widget.make_value()
end

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

Note:

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

値のセット

Parameters:

  • name (String, Symbol)

    ウィジェット識別名

  • value (String, Array)

    セットする値



238
239
240
241
242
# File 'lib/al_form.rb', line 238

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

#set_values(values) ⇒ Object Also known as: values=

Note:

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

値の一括セット

Parameters:

  • values (Hash, NilClass)

    セットする値



254
255
256
257
258
259
260
261
262
263
264
265
# File 'lib/al_form.rb', line 254

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

#set_widgets(*widgets) ⇒ Object Also known as: widgets=

ウィジェットのセット

Parameters:

  • widgets (Array)

    ウィジェットの配列



189
190
191
192
193
194
# File 'lib/al_form.rb', line 189

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

#use_get_method(arg = {}) ⇒ Object

Note:

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

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

Parameters:

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

    a customizable set of options

Options Hash (arg):

  • :ctrl (String)

    コントローラ名

  • :action (String)

    アクション名



177
178
179
180
181
# File 'lib/al_form.rb', line 177

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

#validate(names = nil) ⇒ Boolean

Note:

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

バリデーション

Parameters:

  • names (Array) (defaults to: nil)

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

Returns:

  • (Boolean)

    成否



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
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
# File 'lib/al_form.rb', line 390

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?
end