JavaScriptイベント
さて、先ほどの例ではButtonのOnClickイベントにイベントハンドラを割り当ててプログラムを記述しました。この場合の動作は、WebブラウザからWebサーバへHTTP POSTが送信されて、サーバ側でPHPプログラムが実行された結果が返って来るという流れになっています。
オブジェクトインスペクタの「イベント」タブの隣にある「JavaScript」タブに注目してください。先ほどのButtonを選択した後にこの「JavaScript」タブをみると、ここでもOnClickというイベントを割り当てられます。
では、JavaScriptタブのOnClickイベントをダブルクリックしてみましょう。IDEのコードエディタに以下のようなコードが追加されます。
function Button1JSClick($sender, $params) { ?> //Add your javascript code here <?php }
ここにJavaScriptを記述すると、Webブラウザ上でボタンをクリックした際にJavaScriptが実行されるようになります。
先ほどのPHPコードを関数ごと削除してから、同じようなコードをここに書いてみましょう。Button1のオブジェクトインスペクタでOnClickイベントも削除しておきます。また、Button1のButtonTypeプロパティもデフォルトのbtSubmitからbtNormalに変更しておきます。
function Button1JSClick($sender, $params) { ?> //Add your javascript code here var button1 = document.getElementById('Button1'); var label1 = document.getElementById('Label1'); label1.innerHTML = button1.value; <?php }
ちょっと冗長に書きましたが、元は同じCaptionでもJavaScriptでは違う要素として扱う必要があります。Lableはdivタグに、Buttonはinputタグに変換されています。HTMLのコードも見ておきましょう。
<html DIR=ltr > <head> <title>Unit1</title> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> <script type="text/javascript" src="/vcl-bin/js/common.js"></script> <script type="text/javascript">var Unit1=new Object(Object);</script> <script type="text/javascript"> <!-- function Button1JSClick(event) { var event = event || window.event; var params=null; //Add your javascript code here var button1 = document.getElementById('Button1'); var label1 = document.getElementById('Label1'); label1.innerHTML = button1.value; } --> </script> </head> <body style=" margin-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; " > <form style="margin-bottom: 0" id="Unit1" name="Unit1" method="post" action="/unit1.php"> <table width="800" style="height:600px" border="0" cellpadding="0" cellspacing="0" ><tr><td valign="top"> <div id="Button1_outer" style="Z-INDEX: 0; LEFT: 248px; WIDTH: 107px; POSITION: absolute; TOP: 152px; HEIGHT: 25px"> <input type="button" id="Button1" name="Button1" value="HelloWorld!" onclick="return Button1JSClick(event)" style=" font-family: Verdana; font-size: 10px; height:25px;width:107px;" tabindex="0" /> </div> <div id="Label1_outer" style="Z-INDEX: 1; LEFT: 248px; WIDTH: 107px; POSITION: absolute; TOP: 201px; HEIGHT: 13px"> <div id="Label1" style=" font-family: Verdana; font-size: 10px; " ></div> </div> </td></tr></table> </form></body> </html> <!-- Unit1 end -->
HTML上のinput要素のonclickイベントにButton1JSClick()イベントハンドラが設定されていることが分かります。先ほど変更したButton1のButtonTypeプロパティをbtSubmitのままにしておくと、input要素のtypeがsubmitになってしまうので、JavaScriptで書き換えたLabel1の値がすぐに書き換えられて元に戻ってしまうのです。
Delphi for PHPのイベント機構
ところで、このButtonコンポーネントにはPHPイベントとJavaScriptイベントの両方を割り当てられるようになっていますが、両方とも割り当てるとどうなるでしょうか。例えば、以下のようにしてみましょう。Button1のButtonTypeはbtSubmitに戻しておきます。
function Button1JSClick($sender, $params) { ?> //Add your javascript code here var button1 = document.getElementById('Button1'); alert(button1.value); return true; <?php } function Button1Click($sender, $params) { $this->Label1->Caption = $this->Button1->Caption; }
HTMLソースは以下のようになります。
<html DIR=ltr > <head> <title>Unit1</title> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> <script type="text/javascript" src="/vcl-bin/js/common.js"></script> <script type="text/javascript">var Unit1=new Object(Object);</script> <script type="text/javascript"> <!-- function Button1JSClick(event) { var event = event || window.event; var params=null; //Add your javascript code here var button1 = document.getElementById('Button1'); alert(button1.value); return true; } function Button1ClickWrapper(event, hiddenfield, submitvalue, wrappedfunc) { var event = event || window.event; submit1=true; submit2=true; if (typeof(wrappedfunc) == 'function') submit1=wrappedfunc(event); hiddenfield.value = submitvalue; form = hiddenfield.form; if ((form) && (form.onsubmit) && (typeof(form.onsubmit) == 'function')) submit2=form.onsubmit(); if ((submit1) && (submit2)) form.submit(); return false; } --> </script> </head> <body style=" margin-left: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; " > <form style="margin-bottom: 0" id="Unit1" name="Unit1" method="post" action="/unit1.php"><input type="hidden" id="Button1SubmitEvent" name="Button1SubmitEvent" value="" /> <table width="800" style="height:600px" border="0" cellpadding="0" cellspacing="0" ><tr><td valign="top"> <div id="Button1_outer" style="Z-INDEX: 0; LEFT: 248px; WIDTH: 107px; POSITION: absolute; TOP: 152px; HEIGHT: 25px"> <input type="submit" id="Button1" name="Button1" value="HelloWorld!" onclick="return Button1ClickWrapper(event, findObj('Button1SubmitEvent'), 'Button1_Button1Click', Button1JSClick)" style=" font-family: Verdana; font-size: 10px; height:25px;width:107px;" tabindex="0" /> </div> <div id="Label1_outer" style="Z-INDEX: 1; LEFT: 248px; WIDTH: 107px; POSITION: absolute; TOP: 201px; HEIGHT: 13px"> <div id="Label1" style=" font-family: Verdana; font-size: 10px; " >HelloWorld!</div> </div> </td></tr></table> </form></body> </html> <!-- Unit1 end -->
JavaScriptだけにイベントを割り当てたときと比較すると、Button1ClickWrapper()という関数が増えていることに気が付きます。この関数をJavaScriptラッパーと呼びます。この仕組みが、Buttonなどのイベントを制御する要の部分です。JavaScriptラッパーをひも解くと以下のようなことをしているのが分かります。
- input要素のonclickからevent、hiddenフィールド、submit値、wrapped関数の4つが渡されます
- wrapped関数、つまりButtonのJavaScriptイベントが設定されている場合、これを実行します
- JavaScriptイベントの実行結果がtrueの場合、Buttonのhiddenフィールドにsubmit値を設定します
- form変数にButtonのhiddenフィールドを含むformを設定します
- formが存在しformのonsubmitが設定されている場合、そのJavaScriptを実行します。これはPageのJavaScriptイベントです
- 先ほどのButtonのJavaScriptイベントがtrueを返し、formのonsubmitイベントもtrueを返した場合に、formをsubmitします
各JavaScriptイベントの戻り値がtrueでないとsubmitが実行されないので、先ほどのButton1のJavaScriptイベントでは最後にreturn true;としてtrueを返しているわけです。JavaScriptの場合、returnで値を指定しないと関数の戻り値はundefinedになりますから、falseと判定されてしまうためです。
2/3 |
Index | |
えっ、まだPHPでVisual開発してないの? | |
Page1 Delphi for PHP 2.0ってどんな製品? PHPでもビジュアル開発だ! |
|
Page2 JavaScriptイベント Delphi for PHPのイベント機構 |
|
Page3 controlsクラスの不具合の修正 |
Delphi for PHPを使い倒す! |
Coding Edgeお勧め記事 |
いまさらアルゴリズムを学ぶ意味 コーディングに役立つ! アルゴリズムの基本(1) コンピュータに「3の倍数と3の付く数字」を判断させるにはどうしたらいいか。発想力を鍛えよう |
|
Zope 3の魅力に迫る Zope 3とは何ぞや?(1) Pythonで書かれたWebアプリケーションフレームワーク「Zope 3」。ほかのソフトウェアとは一体何が違っているのか? |
|
貧弱環境プログラミングのススメ 柴田 淳のコーディング天国 高性能なIT機器に囲まれた環境でコンピュータの動作原理に触れることは可能だろうか。貧弱なPC上にビットマップの直線をどうやって引く? |
|
Haskellプログラミングの楽しみ方 のんびりHaskell(1) 関数型言語に分類されるHaskell。C言語などの手続き型言語とまったく異なるプログラミングの世界に踏み出してみよう |
|
ちょっと変わったLisp入門 Gaucheでメタプログラミング(1) Lispの一種であるScheme。いくつかある処理系の中でも気軽にスクリプトを書けるGaucheでLispの世界を体験してみよう |
|
- プログラムの実行はどのようにして行われるのか、Linuxカーネルのコードから探る (2017/7/20)
C言語の「Hello World!」プログラムで使われる、「printf()」「main()」関数の中身を、デバッガによる解析と逆アセンブル、ソースコード読解などのさまざまな側面から探る連載。最終回は、Linuxカーネルの中では、プログラムの起動時にはどのような処理が行われているのかを探る - エンジニアならC言語プログラムの終わりに呼び出されるexit()の中身分かってますよね? (2017/7/13)
C言語の「Hello World!」プログラムで使われる、「printf()」「main()」関数の中身を、デバッガによる解析と逆アセンブル、ソースコード読解などのさまざまな側面から探る連載。今回は、プログラムの終わりに呼び出されるexit()の中身を探る - VBAにおけるFileDialog操作の基本&ドライブの空き容量、ファイルのサイズやタイムスタンプの取得方法 (2017/7/10)
指定したドライブの空き容量、ファイルのタイムスタンプや属性を取得する方法、FileDialog/エクスプローラー操作の基本を紹介します - さらば残業! 面倒くさいエクセル業務を楽にする「Excel VBA」とは (2017/7/6)
日頃発生する“面倒くさい業務”。簡単なプログラミングで効率化できる可能性がある。本稿では、業務で使うことが多い「Microsoft Excel」で使えるVBAを紹介する。※ショートカットキー、アクセスキーの解説あり
|
|