ウィジェットの利用
Webアプリケーションでは、ユーザからデータを受け取るためのユーザインターフェース(UI)としてフォームを使います。フォームの実体はHTML文字列です。HTMLには文法や形式がありますので、フォームにも決まった形式やパターンがあります。
本書の第1章のサンプルプログラムでは、フォームを構成するHTML文字列をプログラムの中に埋め込んでいました。入力に誤りがあったときなど、フォームに前回入力した値を埋め込んで表示する必要があったからです。そのような処理を実現するためには、フォームをプログラムで動的に生成しなければなりません。
テンプレートエンジンを使うことによって、フォームを構成するHTMLをプログラムの中に埋め込む必要がなくなりました。同時に、入力ミスがあった項目の近くにエラーを表示するなどして、より効果的なUIを作れるようになりました。テンプレートエンジンを使うようになって、プログラムはスッキリしました。その代わり、テンプレートに条件分岐やループなど複雑なロジックを書くようになり、テンプレートが複雑になってしまっています。
WebアプリケーションのUIとなるフォームに求められる機能はたいてい似ています。たとえば、既存の値があればあらかじめ埋め込んで表示する。エラーがあればフォームの要素の近くに表示する、といった機能が求められるでしょうか。また、フォームを表現するためのHTML文字列にもパターンがあります。このようなパターンをうまく抽象化できれば、フォーム自体を部品化して、再利用しやすく実装できるかも知れません。
ここでは、Webアプリケーションで利用するフォームを効率的に扱う方法について考えてみたいと思います。
WebアプリケーションとCRUDフォーム
データベースと連携するWebアプリケーションでは、データを新規登録したり、更新するためにフォームを利用します。登録、更新に加え、データの削除をフォームを使って行うこともあるでしょう。また、データの内容を確認するためにデータの内容を表示することもあるはずです。
Webアプリケーションでデータベース上のデータを扱うときには、たいてい「新規登録」、「表示」、「更新」、「削除」が1セットになっています。このセットはCRUD(クラッド)と呼ばれています。Create(新規登録)、Read(読み込み/表示)、Update(更新)、Delete(削除)それぞれの頭文字を取った略語で、Webアプリケーションの開発でよく使われる用語です。
データの新規登録を行うフォームでは、どのような流れでデータの追加を行うべきかについて考えましょう。まずデータの入力に必要なフォームを、空の状態か、初期値が埋め込まれた状態で表示します。ユーザが項目を入力し、登録用のボタンを押すと、データがPOSTされます。Webアプリケーション側では、クエリとしてデータを受け取ります。
受け取ったデータをそのまま登録するわけにはいきません。Webのフォーム入力できる文字種などに制限がないので、もしかしたら不正な値が入力されているかもしれません。不正な値が登録されてしまうことを避けるため、バリデーションチェックを行う必要があります。 もし不正な値が見つかったら、入力に不備があることをユーザに分かりやすいように示しつつ、再度データを入力できるようにフォームを表示します。入力項目が複数あり、一部の入力値が正しかった場合には、以前に入力されていた値を再度表示します。正しいデータがPOSTされたら、データを登録します。
図01 新規登録の流れ
このように、Webブラウザから送るリクエストと、Webアプリケーションから送り返すレスポンスをうまく組み合わせて、正しいデータを登録できるような遷移を作ります。Webアプリケーションでは、リクエストとレスポンスは必ずペアになっている必要があるということを思い出してください。リクエストを受け取り、Webアプリケーション側で適切なレスポンスを返す、ということを繰り返しながら、データ登録の流れを作ります。
次に登録済みのデータを更新するための流れについて考えてみましょう。新規登録と違い、あらかじめ登録されているデータをフォームで編集するわけですから、表示するときにデータが埋まった状態でフォームを表示します。その後、バリデーションチェックをする過程は「新規登録」の流れと同じです。必要に応じてエラーなどを表示しながら、正しいデータがPOSTされたらデータを更新します。
このように、典型的なWebアプリケーションでは、データの登録と更新に、よく似た仕組みを持つ必要があります。処理の流れだけでなく、表示するフォームの内容もとても良く似たものになるはずです。同じ種類のデータを対象にしているわけですから、バリデーションチェックの内容も同じになるはずです。
この2つの共通した部分の多いフォームをうまく扱えれば、Webアプリケーションで利用するフォームの処理を楽にできるかもしれません。
フォーム処理の抽象化
Webのフォームは、入力用の項目の集まりである、と定義できます。入力用の項目にはいくつかの種類があります。テキスト入力フィールド、メニューやチェックボックス、ボタンなどが主な種類です。入力用の項目はHTML文字列で表現します。入力項目の種類ごとに、HTML文字列の書き方が異なります。このようにして見ると、フォームというのは入力項目を部品としてまとめたもの、と捕らえることができます。
項目に入力された値に関しては、Webアプリケーション側でバリデーションチェックをかける必要があります。どのようなバリデーションチェックを実行すべきかについては、項目ごとに決まる場合が多いはずです。同じテキスト入力フィールドでも、場合によっては数値を入力することもありますし、メールアドレスを入力することもあります。フォームの部品にバリデータを設定できれば便利なはずです。
図02 フォームは入力項目をHTMLの部品としてまとめたもの
フォームの項目ごとに、項目を表現するためのHTMLを出力する仕組みを備えて、いろいろなバリデータを登録できるような仕組みがあると、フォームの処理をうまく抽象化できそうです。
ウィジェットとは
アプリケーションで利用するユーザインターフェース(UI)をプログラミングの部品として抽象化したものをウィジェット(Widget)と呼びます。もともとは、GUIアプリケーションで利用するUIの部品を、クラスのような形で抽象化した仕組みを指してウィジェットと呼んでいました。「小物」という意味の英単語gadgetとwindowを合成してwidgetと名付けられた、という説もあるようです。
Webアプリケーションで利用するウィジェットは、フォームの構成要素をクラスなどの形式で抽象化したものを指します。ウィジェットの実装方法に特に決まった形があるわけではありません。実装によって、フォームの表示のみに特化していたり、バリデータを含めて登録できるものなどさまざまな形態があるようです。ユーザインターフェースをプログラムで利用しやすいように抽象化したものである、という意味においては、WebアプリケーションのウィジェットはGUIアプリで利用されているものの流れをくんでいると言えるでしょう。
Webアプリケーションで利用されるウィジェットを簡単に説明すると、テンプレートの部品の一種、ということになります。Webアプリケーションの出力に使うテンプレートにフォームを、プログラムを使って自動的に生成するために利用するのがウィジェットです。そのようにすることによって、フォームに相当するHTMLをテンプレートに直接書く必要がなくなります。