ユーザ用ツール

サイト用ツール


prog_cgi:入力フォームを使う

入力フォームを使う

ウェブアプリでブラウザに入力フォームを表示し、ユーザーの入力値を受け取るアプリケーションを作成します。 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&amp;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) %>
prog_cgi/入力フォームを使う.txt · 最終更新: 2019/03/15 17:36 by hirohito