目次
入力フォームを使う
ウェブアプリでブラウザに入力フォームを表示し、ユーザーの入力値を受け取るアプリケーションを作成します。 Aloneでは、ブラウザからフォームからの入力データを受け取る時、フォームマネージャを経由してデータを受け取ります。 詳細は、「AlForm フォームマネージャ」を参照してください。
ここでは、テキストと数字の入力ができるフォームを表示し、入力結果を表示するだけのアプリケーションを作成してみます。
コントローラには、2つのアクションを定義します。フォームを表示するためのアクションと、フォームに入力されたデータを受け取るためのアクションです。
- main.rb
require 'alone' class FormController1 < AlController # constructor def initialize() @form = AlForm.new( AlText.new("text1"), AlInteger.new("integer1"), AlSubmit.new("submit1"), ) @form.action = Alone::make_uri( action:"confirm" ) end # デフォルトアクション def action_index() AlTemplate.run( 'index.rhtml' ) end # 確認画面 def action_confirm() if @form.validate() AlTemplate.run( 'confirm.rhtml' ) else AlTemplate.run( 'index.rhtml' ) end end end
テンプレートも、それぞれのアクション用に2種類用意します。
- index.rhtml
<%= header_section %> <%= body_section %> <%= @form.get_messages_by_html() %> <%= @form.make_tiny_form() %> <%= footer_section %>
- confirm.rhtml
<%= header_section %> <%= body_section %> text1: <%=h @form[:text1] %> <br> integer1: <%=h @form[:integer1] %> <br> <%= footer_section %>
解説
フォームオブジェクトの作成
AlForm.newによって、オブジェクトを作成します。
@form = AlForm.new(...)
この例ではコンストラクタ中で作成していますが、各アクション中で作成してもかまいません。
AlFormオブジェクトは複数のAlWidgetオブジェクトを内包します。
それぞれのAlWidgetオブジェクトがデータの名前 (name)、データタイプ(テキスト、数値、チェックボックス、ほか)などの属性を持ちます。
AlText.new( "text1" ), # テキストの入力を行う。名前は text1とする。 AlInteger.new( "integer1" ), # 整数の数値入力を行う。名前は integer1とする。
フォームオブジェクトからhtmlフォームの自動生成
主要機能とは少し離れるのですが、サンプルの簡単のため、ここではhtmlフォームの自動生成を使います。
フォームオブジェクトから定型的なhtmlフォームを自動生成する機能 make_tiny_form() があり、テンプレート内で使っています。
<%= @form.make_tiny_form() %>
自動生成されるhtml
<form method="POST" action="/index.rb?ctrl=form1&action=confirm"> <table class="al-form-table"> <tr class="text1"> <td class="al-form-label">text1</td> <td class="al-form-value"><input type="text" name="text1" id="text1" value=""></td> </tr> <tr class="integer1"> <td class="al-form-label">integer1</td> <td class="al-form-value"><input type="text" name="integer1" id="integer1" value=""></td> </tr> <tr class="submit1"> <td class="al-form-label"></td> <td class="al-form-value"><input type="submit" name="submit1" id="submit1" value="submit1"></td> </tr> </table> </form>
ブラウザからのデータ受取り
submit1ボタンをクリックすると、ブラウザはサーバへデータを送信します。 ブラウザから送られてきたデータは、validate()メソッドを使ったバリデーションが成功して初めて使うことができるようになります。 validate()メソッドは失敗するとfalseを返すので、ifで成功と失敗を場合分けるようにします。
def action_confirm() if @form.validate() AlTemplate.run( 'confirm.rhtml' ) # 成功の場合 else AlTemplate.run( 'index.rhtml' ) # 失敗の場合 end end
バリデーションが失敗する原因としては、数値入力欄に数字以外の文字を入れた場合などです。
バリデーションが成功すると、ハッシュと同じ型式 @form[:名前] で、送信されたデータを使うことができます。
このプログラムでは、フォームに入力され送信されてきたデータを画面にそのまま表示するだけです。
値の参照は、@form[:名前] で個別に参照できるほか、@form.values で、一つのHash値として扱うことも可能です。
val1 = @form.values p val1[:名前]
html5で追加されたtypeへの対応
html5では、inputタグのtypeアトリビュートが拡張されました。
Aloneのフォーム (AlWidget) では、tag_typeアトリビュートを使ってサポートしています。
(受け取るデータタイプを明確にする事が主目的のため、ウィジェットの種類を増やす方向での拡張はしていません)
サンプル
def initialize() @form = AlForm.new( AlInteger.new("number1", :tag_type=>"number"), AlInteger.new("range1", :tag_type=>"range"), AlDate.new("date1", :tag_type=>"date"), ) end
その他の機能
表の簡易生成
フォームの自動生成と同じように、表示についても定型的な表として生成する機能を備えています。 以下のようにして使います。
<%= @form.make_tiny_sheet() %>
ラベル
表示のわかりやすさのために、ラベルを付与することができます。
AlText.new("text1", :label=>"テキスト" )
初期値
各ウィジェットには、初期値が指定できます。
AlText.new("text1", :value=>"abc" )
必須入力
必須入力フラグをつけておくと、入力がなかった場合、バリデーションではじかれます。
AlText.new("text1", :required=>true ),
make_tagメソッド利用時の追加アトリビュート
htmlタグ生成時に、任意のアトリビュートを追加できます。
AlSubmit.new( "submit1", :value=>"決定", :tag_attr=> {:style=>"float: right;"} )
サンプル
def initialize() @form = AlForm.new( AlText.new( "text1", :label=>"テキスト", :value=>"abc", :required=>true ), AlInteger.new( "integer1", :label=>"整数", :value=>123 ), AlSubmit.new( "submit1", :value=>"決定", :tag_attr=> {:style=>"float: right;"} ) ) @form.action = Alone::make_uri( action:"confirm" ) end
POSTとGET
フォームで使われるメソッドには POSTとGETがあり、デフォルトでPOSTメソッドが使われます。
<form method="POST" action="...">
通常のデータ登録などの場合はPOSTが適切ですが、検索するためのフォームなど、入力値がコンテンツの変更を伴わない場合には、GETメソッドを使う方が良い場合があります。
GETが使われる場合、 action="index.rb?ctrl=XXXX&action=YYYY" と記述していても、URLパラメータ(?以降)が消されてしまい、フォーム入力データで上書きされるため、結果としてルーティング用パラメータ ctrl, action がAloneへ渡らず、正常に動作できません。 (これは、ブラウザがそのように動作しているということですが、HTMLの仕様かどうかまでは調査しきれていません。)
そのため、フォームでGETを使う場合、ひと工夫必要になります。
独自のテンプレート(フォーム)を使う場合
テンプレート中に以下の例を参考に hiddenで ctrlとactionを追加します。
<form name="form1" method="GET" action="<%=h make_uri() %>"> <input type="hidden" name="ctrl" value="<%=h Alone.ctrl %>"> <input type="hidden" name="action" value="ANY_ACTION">
フォームの自動生成を使う場合
use_get_method() メソッドを使いGETを使うことを指示すると、フォームオブジェクトにウィジェット ctrlとaction が追加されます。
@form = AlForm.new( ... ) @form.use_get_method( :action=>"ANY_ACTION" )
もしくは、自動生成しなくても、use_get_methodをウィジェット追加のためだけに使うことも考えられます。
@form = AlForm.new( ... ) @form.use_get_method( :action=>"ANY_ACTION" )
<form name="form1" method="GET" action="<%=h make_uri() %>"> <%= @form.make_tag(:ctrl) %> <%= @form.make_tag(:action) %>