フォームの利用

ユーザーからのデータを受け取るには、フォームを利用します。フォームの使い方を学びましょう。

簡単なフォーム

まず最初に簡単なフォームを作成してみましょう。テキストボックス、ラジオボタン、テキストエリアに値を入力してもらって、受け取って表示するプログラムを作成してみます。

use Mojolicious::Lite;

# トップページ
get '/' => sub {
  my $self = shift;
  
  $self->render('index');
};

# データを受け取って処理
post '/' => sub {
  my $self = shift;
  
  # パラメーターの取得
  my $name = $self->param('name');
  my $private = $self->param('private');
  my $message = $self->param('message');

  # メッセージがない場合はトップページを表示
  unless (length $message) {
    $self->render('index', error => 'Message is empty');
    return;
  }
  # フラッシュに保存
  $self->flash(name => $name);
  $self->flash(private => $private);
  $self->flash(message => $message);
  
  $self->redirect_to('/');
};

app->start;

__DATA__

@@ index.html.ep
<%
  my $error = stash('error');
%>

% if ($error) {
  <div style="color:red">
    <%= $error %>
  </div>
% }

<form action="<%= url_for %>" method="post" style="border:1px solid gray">
  <b>Form</b><br>
  <b>Name:</b> <%= text_field 'name' %><br>
  <b>Private:</b> Yes<%= radio_button private => 1 %> / No <%= radio_button private => 0, checked => 'checked' %><br>
  <b>Message:</b><br>
  <%= text_area 'message', style => "width:400px; height:100px" %><br>
  <input type="submit" value="Post">
</form>

<div>
  <b>Name</b>: <%= flash('name') // '' %><br>
  <b>Private</b>: <%= flash('private') // '' %><br>
  <b>Message</b>: <%= flash('message') // '' %>
</div>

このプログラムを実行して、フォームに値を入力してPostボタンを押すと、画面に入力した内容が表示されます。画面の下の部分は次のように表示されると思います。

Name: kimoto
Private: 0
Message: Hello

このプログラムはサンプルのプログラムです。本来ならばユーザーから受け取ったデータは、データベースに保存します。まだデータベースについては解説していませんので、データを保存せずに、そのまま表示するプログラムにしています。

プログラムの各部分を解説します。

# トップページ
get '/' => sub {
  my $self = shift;
  
  $self->render('index');
};

これはトップページを表示するルーティングの記述です。いつもどおりの記述です。このページにフォームを記述します。

フォームの記述

フォームは以下のようになっています。

<form action="<%= url_for %>" method="post" style="border:1px solid gray">
  <b>Form</b><br>
  <b>Name:</b> <%= text_field 'name' %><br>
  <b>Private:</b> Yes<%= radio_button private => 1 %> / No <%= radio_button private => 0, checked => 'checked' %><br>
  <b>Message:</b><br>
  <%= text_area 'message', style => "width:400px; height:100px" %><br>
  <input type="submit" value="Post">
</form>

formタグの中にはactionmethodstyleという属性がありますね。style属性はスタイルシートを設定するもので、フォームを囲む枠を設定しています。

フォームでデータを送信するときには、一般的にはmethodにpostを指定します。postを指定すれば、どんなに大きなデータであっても送信することができます。getを指定した場合は、フォームの値はURLのクエリ文字列として送信されますが、postを指定した場合は、HTTPボディと呼ばれる部分に記述されて、送信されます。

actionには処理をするURLを指定します。今回は同一のURLにしました。同一のURLにしておくと簡単です。

フォームの部品を使う部分でtext_fieldヘルパー、radio_buttonヘルパー、strong>text_areaヘルパーを使用しています。

  <b>Name:</b> <%= text_field 'name' %><br>
  <b>Private:</b> Yes<%= radio_button private => 1 %> / No <%= radio_button private => 0 %><br>
  <b>Message:</b><br>
  <%= text_area 'message', style => "width:400px; height:100px" %><br>

これらは、タグヘルパーと呼ばれます。利用可能なタグヘルパーについては「「Mojoliciousのタグヘルパーの一覧」を見てください。

タグヘルパーは、以下のような実際のタグに展開されます。

<form action="/" method="post" style="border:1px solid gray">
  <b>Form</b><br>
  <b>Name:</b> <input name="name" type="text" /><br>
  <b>Private:</b> Yes<input name="private" type="radio" value="1" /> / No <input name="private" type="radio" value="0" /><br>
  <b>Message:</b><br>
  <textarea name="message" style="width:400px; height:100px"></textarea><br>
  <input type="submit" value="Post">
</form>

タグヘルパーを使うと便利な一番の理由は、フォームを送信した後でも、フォームの値を復元してくれることです。

今回は、メッセージが入力されていない場合は、エラーメッセージを表示するようにしているのですけれど、その場合にでも、フォームの値が保存されます。

フォームの処理

次にフォームを処理する部分です。フォームではmethodにpostを指定しました。このリクエストはpost関数を使って、受け取ることができます。

# データを受け取って処理
post '/' => sub { ... };

では、処理を見ていきましょう。まずフォームから渡された値をパラメーターとして受け取っています。paramメソッドは、HTTPのGETメソッドであっても、POSTメソッドであっても、どちらでも値を受け取ることができます。

# パラメーターの取得
my $name = $self->param('name');
my $private = $self->param('private');
my $message = $self->param('message');

次にメッセージがない場合は、処理をエラーにしています。スタッシュのerrorという値を設定して、indexを描画します。途中で処理を抜けたい場合は、returnを返しましょう。

  # メッセージがない場合はトップページを表示
  unless (length $message) {
    $self->render('index', error => 'Message is empty');
    return;
  }

本来ならば、データベースなどにデータを保存するのですが、今回はまだデータベースの処理について書いていませんので、フラッシュに保存しています。

フラッシュとは、クライアントサイドに保存されるデータで、次の画面の遷移のときまで保存されるデータです。flashメソッドで設定と取得を行うことができます。フラッシュについては、セッションを解説するときに、詳しく解説します。

  # フラッシュに保存
  $self->flash(name => $name);
  $self->flash(private => $private);
  $self->flash(message => $message);

最後にリダイレクトを行って、最初のページを表示します。

  $self->redirect_to('/');

このようにフォームを使うとユーザーのデータを受け取ることができます。

関連情報