はじめに
Delphi for PHPは、Windows向けビジュアル開発ツールとして定評のあるDelphiの開発スタイル、つまり、コンポーネントをドラッグ&ドロップ操作で配置し、プロパティとイベントを設定して開発するスタイルで、PHPによるWebアプリケーションを開発できるツールです。
Delphi for PHPの基本的な使い方を紹介する3回シリーズの第2回では、画面のレイアウトや制御、複数のページにまたがる処理などに挑戦してみましょう。
これまでの記事
コンポーネントのいろいろ
Delphi for PHPに搭載されているコンポーネントフレームワークVCL for PHPには、さまざまな部品が用意されています。ここでは、よく使うコンポーネントについて簡単に紹介することにしましょう。
Label
ページに表示するテキストです。テキストは、Captionプロパティで設定します。Font.Size、Font.Color、Font.Familyなどのプロパティで表示するテキストのフォントを変更できます。テキストには、Linkプロパティを使って、ハイパーリンクを設定することもできます。
Labelのテキストには、HTML形式のテキストを指定することもできます。つまり、複雑なテキスト要素をLabelを使って表現することも可能です。
Edit
入力ボックスです。入力文字は、Textプロパティで設定/取得できます。MaxLengthプロパティで、最大入力文字数の設定も可能です。なお、パスワード入力用に使用する(入力文字をマスクする)場合には、IsPasswordプロパティをtrueに設定します。
Memo
複数行のテキスト入力にはMemoを使います。入力された複数行のテキストへは、Textプロパティでアクセスできますが、各行に個別にアクセスするには、Linesプロパティを使います。例えば、LabelにMemoの2行目のだけを表示するには、次のように記述します。
$this->Label1->Caption = $this->Memo1->Lines[1];
Button
ボタンです。ボタンをクリックしたときの動作は、OnClickイベントに記述します。
CheckBox
チェックボックスです。ボックスの横に表示されるテキストはCaptionプロパティで設定します。チェックされているかどうかはCheckedプロパティで調べます。
RadioGroup
グループ化されたラジオボタンです。グループのタイトルはCaptionプロパティで設定します。ここで設定したテキストは、グループを表す枠の上に表示されます。複数のラジオボタンはItemsプロパティで定義します。Object InspectorではString List editorを使って入力します。
選択されているボタンの順番は、ItemIndexプロパティで調べます。
ListBox
選択リストです。リスト項目はItemsプロパティで定義します。定義する項目にはkeyとvalueがありますが、keyが実際にフォームで保持される値、valueがリストに表示される文字列です。
ComboBox
ドロップダウン型の選択リストです。リスト項目はListBox同様、Itemsプロパティで定義します。
Panel
Panelの上には、他のコンポーネントを配置することができます。Panelには、色をつけたり枠線をつけて画面上の領域を表すこともできますが、色を付けずに、単純に複数のコンポーネントのレイアウトをグループ化して管理するために使うこともできます。
VCL for PHPのイベント
VCL for PHPの各コンポーネントには、さまざまなイベントが用意されています。しかし、イベントを使ってコードを記述する前に、PHPアプリケーションの実行のされ方を理解しておく必要があります。
例えば、Delphi for PHPで作成したページ「unit1」を表示しようとします。その場合、ブラウザには次のようにURLを入力します。
http://localhost:3569/unit1.php
このときサーバ(この場合では、localhost)にリクエストが送信され、unit1.phpが実行され、その結果のHTMLがクライアントに返され、ブラウザに表示されます。
ところで、VCL for PHPのイベントが実行されるタイミングは、太字の箇所「unit1.phpが実行され」というところです。つまり、HTMLに表示されたページに配置されたコンポーネントのイベントハンドラに設定されたコードが次に実行される可能性があるのは、再び「unit1.phpが実行され」るときです。例えば、ボタンをクリックしたときなどです。
注意しなければならないのは、ブラウザに表示されたHTML内で起こる動作は、VCL for PHPのイベントでは捕捉できないということです。例えば、マウスカーソルをテキストラベルの上に移動したとか、入力ボックスのテキストを変更したときなどの動作は捕捉しません。あくまでも、サーバにリクエストが飛んだときだけです。
では、ブラウザ上で起きる動作を細かく捕捉したいときは、どうすればいいのでしょうか。
JavaScriptイベント
Object Inspectorには、もう1つ、「JavaScript」というタブがあります。ここには、JavaScriptによって記述可能な、クライアントサイドで捕捉可能なイベントがリストされています。上に挙げた、マウスカーソルをテキストラベルの上に移動したとか、入力ボックスのテキストを変更したといった動作は、JavaScriptイベントによって捕捉できます。
典型的なJavaScriptイベントの使い方を、Timerコンポーネントで説明しましょう。
新規アプリケーションを作成し、フォーム上にEditコンポーネントを配置します。ここには現在の日付と時刻を表示するようにしますので、少し幅を大きめに変更します。
次に、Timerコンポーネントを配置します(Tool Paletteの「System」にあります)。このコンポーネントは実際にはページ上に表示されない非表示コンポーネントなので、アイコンだけが設計フォームに表示されます。
配置したTimerを選択して、Object Inspectorの「JavaScript Event」を表示します。
OnTimerイベントの値列をダブルクリックして、イベントハンドラを表示します。
function Timer1JSTimer($sender, $params) { ?> //Add your javascript code here <?php }
このイベントハンドラには、「Add your javascript code here」と書かれた箇所に、JavaScriptでコードを記述します。ちょっと特殊ですが、直前の?>
でPHPコードは終わり、<?php
から再開しています。この間に、記述したJavaScriptがクライアントサイドで実行されるのです。
ここに次のように記述します(太字箇所)。
function Timer1JSTimer($sender, $params) { ?> //Add your javascript code here document.getElementById('Edit1').value = "現在時刻は" + new Date() + "です"; <?php }
注意しなければならないのは、コードがPHPではないということです。そのため、Edit1へテキストを設定する操作も異なります。コンポーネントへは、以下のように、コンポーネントのNameプロパティをgetElementById()
に指定してアクセスします。
document.getElementById('Edit1')
このイベントハンドラを呼び出す頻度は、TimerのIntervalプロパティで設定します。デフォルトは1000(ミリ秒)なので、1秒ごとに呼び出され、表示を更新します。
別のページに移動するフォーム 1
これまで作ってきたアプリケーションは、1つのフォームだけでした。ボタンをクリックしても、同じフォームに戻ってしまいます。Webでデータ入力させるようなアプリケーションでは、項目を入力したら入力結果を表示したり、次のアクションに進んだりするものがほとんどです。
Delphi for PHPで実用的なアプリケーション作りに進んでいくために、別のページに移動するフォームの作り方をマスターしておきましょう。
最初のフォームの作成
ここでは、名前とEメールアドレスを入力するフォームを作成しましょう。JavaScriptイベントを使って、両方のフィールドにテキストが入力されないとボタンを押せないようにします。
新規アプリケーションを作成し、LabelとEdit、Buttonを次のように配置します。
それぞれ次のようにプロパティを設定します。
プロパティ | 値 |
Caption | 入力フォーム |
Encoding | Unicode(UTF-8) |
Name | RegForm |
プロパティ | 値 |
Caption | 名前 |
プロパティ | 値 |
Caption | Eメール |
プロパティ | 値 |
Name | edtName |
プロパティ | 値 |
Name | edtEmail |
プロパティ | 値 |
Caption | 登録 |
Name | btnSubmit |
出来上がったフォームのデザインは以下のとおりです。
ここまで完了したら、「File」-「Save As」メニューを実行し、作成したフォームに「regform.php」という名前をつけて保存します。
テキストが入力されたらボタンを押せるようにする
それでは、JavaScriptイベントを使って、テキストの入力状態に応じたボタンの有効/無効の変更を実装します。
まず、edtNameを選択してObject Inspectorの「JavaScript」ページを表示します。先ほどは、ダブルクリックしてメソッド名を決めてしまいましたが、今回はキーボードからタイプして指定します。OnChangeイベントを選択したら、値列には「checkText」と入力して[Enter]キーを押します。
function checkText($sender, $params) { ?> //Add your javascript code here <?php }
ここであえて名前を指定したのは、同じメソッドを別の場所でも使用するため、分かりやすい名前にしておいた方がよいだろうという判断からです。
表示されたイベントハンドラメソッドには、次のように記述します(太字箇所)。
function checkText($sender, $params) { ?> //Add your javascript code here document.getElementById('btnSubmit').disabled = (document.getElementById('edtName').value =='' || document.getElementById('edtEmail').value ==''); <?php }
次に、ObjectInspectorに戻り、同じedtNameのOnKeyUpイベントの値列をクリックします。そして、ドロップダウンリストからcheckTextを選択します。
再び設計画面に戻ってedtEmailを選択するか、ObjectInspectorの上部にあるドロップダウンリストからedtEmailを選択します。そして、JavaScriptイベントのOnChange、OnKeyUpそれぞれにcheckTextを設定します。
さらにフォームがロードされた際、ボタンの状態を正しく設定するためにフォームのJavaScriptイベントも設定します。フォーム全体(RegForm)を選択して、OnLoadイベントにcheckTextを設定します。
以上で、いずれのテキストボックスのテキストが変更されるか、キー入力されるかすると、内容をチェックするJavaScriptコードが働き、両方にテキストが入力されたときにだけボタンを有効にします。
別のページに移動するフォーム 2
別のフォームを作成する
次に、登録結果を表示するフォームを作成します。ここでは、データを実際に登録することはしませんが、受け取ったデータを画面に表示します。
メインメニューから、「File」-「New」-「Form」を選択してフォームを作成します。作成したフォームには、次のようにコンポーネントを配置します。
プロパティを以下のように設定します。
プロパティ | 値 |
Caption | 登録結果 |
Encoding | Unicode(UTF-8) |
Name | ResultForm |
プロパティ | 値 |
Caption | 登録結果 |
Font.Size | 16 |
Font.Weight | bold |
プロパティ | 値 |
Name | lblName |
プロパティ | 値 |
Name | lblEmail |
出来上がったフォームのデザインは以下のとおりです。
「File」-「Save As」メニューを実行し、このフォームを「resultform.php」という名前で保存します。
フォーム間でのデータのやりとり
通常は、入力フォームのOnClickイベントですぐにデータを登録してしまうかもしれません。しかし、そのデータを次のフォームに引継ぎ、確認を求めたり次のステップの入力を促したりするかもしれません。
ここでは、入力フォームregform.phpに戻って入力したデータを共有できるようにし、結果フォームを呼び出すコードを記述します。
設計画面でbtnSubmitを選択し、Object InspectorのOnClickイベントの値列をダブルクリックします。表示されたコードに以下を記述します(太字箇所)。
function btnSubmitClick($sender, $params) { $_SESSION['name'] = $this->edtName->Text; $_SESSION['email'] = $this->edtEmail->Text; redirect("resultform.php"); }
入力した情報はセッションに格納することで、別のフォームで共有することができます。最初の2行がセッションにデータを格納するコードです。redirectメソッドを使って、結果を表示するフォームを呼び出しています。
結果を表示するフォームの側では、セッションから情報を取り出し、ラベルに表示します。結果フォームresultform.phpを表示して、設計画面でフォーム全体ResultFormを選択します。Object InspectorでOnShowイベントを選択し、値列をダブルクリックします。
表示されたコードに、以下のように記述します(太字箇所)。
function ResultFormShow($sender, $params) { $this->lblName->Caption = '名前は ' . $_SESSION['name'] . ' です'; $this->lblEmail->Caption = 'メールアドレスは ' . $_SESSION['email'] . ' です'; }
以上でラベルに入力された情報を表示できます。プログラムを実行してみましょう。