====== 入力フォームを使う ====== ウェブアプリでブラウザに入力フォームを表示し、ユーザーの入力値を受け取るアプリケーションを作成します。 Aloneでは、ブラウザからフォームからの入力データを受け取る時、フォームマネージャを経由してデータを受け取ります。 詳細は、「[[alform:start|AlForm フォームマネージャ]]」を参照してください。 ここでは、テキストと数字の入力ができるフォームを表示し、入力結果を表示するだけのアプリケーションを作成してみます。 {{:prog_cgi:form_form1.png?nolink&400|}} コントローラには、2つのアクションを定義します。フォームを表示するためのアクションと、フォームに入力されたデータを受け取るためのアクションです。 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種類用意します。 <%= header_section %> <%= body_section %> <%= @form.get_messages_by_html() %> <%= @form.make_tiny_form() %> <%= footer_section %> <%= header_section %> <%= body_section %> text1: <%=h @form[:text1] %>
integer1: <%=h @form[:integer1] %>
<%= 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
text1
integer1
{{:prog_cgi:form_form1.png?nolink|}} ==== ブラウザからのデータ受取り ==== submit1ボタンをクリックすると、ブラウザはサーバへデータを送信します。 ブラウザから送られてきたデータは、validate()メソッドを使ったバリデーションが成功して初めて使うことができるようになります。 validate()メソッドは失敗するとfalseを返すので、ifで成功と失敗を場合分けるようにします。 def action_confirm() if @form.validate() AlTemplate.run( 'confirm.rhtml' ) # 成功の場合 else AlTemplate.run( 'index.rhtml' )   # 失敗の場合 end end バリデーションが失敗する原因としては、数値入力欄に数字以外の文字を入れた場合などです。\\ バリデーションが成功すると、ハッシュと同じ型式 @form[:名前] で、送信されたデータを使うことができます。 このプログラムでは、フォームに入力され送信されてきたデータを画面にそのまま表示するだけです。 {{:prog_cgi:form_confirm1.png?nolink|}} 値の参照は、@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 {{:prog_cgi:form_html5.png?nolink|}} ====== その他の機能 ====== == 表の簡易生成 == フォームの自動生成と同じように、表示についても定型的な表として生成する機能を備えています。 以下のようにして使います。 <%= @form.make_tiny_sheet() %> {{:prog_cgi:form_confirm2.png?nolink|}} == ラベル == 表示のわかりやすさのために、ラベルを付与することができます。 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 {{:prog_cgi:form_form2.png?nolink|}} ====== POSTとGET ====== フォームで使われるメソッドには POSTとGETがあり、デフォルトでPOSTメソッドが使われます。
通常のデータ登録などの場合はPOSTが適切ですが、検索するためのフォームなど、入力値がコンテンツの変更を伴わない場合には、GETメソッドを使う方が良い場合があります。 GETが使われる場合、 action="index.rb?ctrl=XXXX&action=YYYY" と記述していても、URLパラメータ(?以降)が消されてしまい、フォーム入力データで上書きされるため、結果としてルーティング用パラメータ ctrl, action がAloneへ渡らず、正常に動作できません。 (これは、ブラウザがそのように動作しているということですが、HTMLの仕様かどうかまでは調査しきれていません。) そのため、フォームでGETを使う場合、ひと工夫必要になります。 ===== 独自のテンプレート(フォーム)を使う場合 ===== テンプレート中に以下の例を参考に hiddenで ctrlと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.make_tag(:ctrl) %> <%= @form.make_tag(:action) %>