Delphi for PHPを使い倒す!

Delphi for PHPを使い倒す!(前編)

えっ、まだPHPでVisual開発してないの?

はやしつとむ
アナハイムテクノロジー株式会社

2009/10/7

cotorolsクラスの不具合の修正

 さて、実はここに大きな問題があります。例えば、Button1のJavaScriptイベントでEditコンポーネントに入力された値のバリデーションを行う場合、戻り値をfalseに設定してJavaScriptラッパーを抜けてしまうと、hiddenフィールドに値が設定されたままになってしまうのです。

 この状態で、ほかのボタンでsubmitが実行されると、本来キャンセルされたはずのButton1のPHPイベントもサーバ側で実行されてしまいます! なんてこったい。

●JavaScriptラッパーの不具合
JavaScriptタブ

 このあたりの機構は、Buttonなどのクラスの基底クラスとなるcontrolsクラスに実装されています。具体的には以下の個所になります。

●controls.inc.php(1303)
        protected function getJSWrapperFunction($event)
        {
                $res = "";
                if ($event != null)
                {
                        $funcName = $this->getJSWrapperFunctionName($event);

                        $res .= "function $funcName(event, hiddenfield, submitvalue, wrappedfunc)\n";
                        $res .= "{\n\n";
                        $res .= "var event = event || window.event;\n";

                        $res .= "submit1=true;\n";
                        $res .= "submit2=true;\n";

                        // Calls the user defined JS function first if it exists.
                        $res .= "if (typeof(wrappedfunc) == 'function') submit1=wrappedfunc(event);\n";

                        // Sets the hidden field value so later you will know which event was fired.
                        $res .= "hiddenfield.value = submitvalue;\n";

                        $res .= "form = hiddenfield.form;\n";

                        // Submits the form.
                        $res .= "if ((form) && (form.onsubmit) && (typeof(form.onsubmit) == 'function')) submit2=form.onsubmit();\n";
                        $res .= "if ((submit1) && (submit2)) form.submit();\n";

                        // Makes sure the event handler of the element does not handle
                        // the JS event again. (This might happen with a submit button.)
                        $res .= "return false;\n";

                        $res .= "\n}\n";
                        $res .= "\n";
                }
                return $res;
        }

 上記の不具合に対処するために、以下のように書き換えます。

        protected function getJSWrapperFunction($event)
        {
                $res = "\n";
                if ($event != null)
                {
                        $funcName = $this->getJSWrapperFunctionName($event);

                        $res .= "function $funcName(event, hiddenfield, submitvalue, wrappedfunc)\n";
                        $res .= "{\n\n";
                        $res .= "var event = event || window.event;\n";

                        $res .= "submit1=true;\n";
                        $res .= "submit2=true;\n";

                        // Calls the user defined JS function first if it exists.
                        $res .= "if (typeof(wrappedfunc) == 'function') submit1=wrappedfunc(event);\n";

                        $res .= "form = hiddenfield.form;\n";

                        // Submits the form.
                        $res .= "if ((form) && (form.onsubmit) && (typeof(form.onsubmit) == 'function')) submit2=form.onsubmit();\n";
                        $res .= "if ((submit1) && (submit2)){\n";

                        // Sets the hidden field value so later you will know which event was fired.
                        $res .= "  hiddenfield.value = submitvalue;\n";

                        $res .= "  form.submit();\n";
                        $res .= "}\n";

                        // Makes sure the event handler of the element does not handle
                        // the JS event again. (This might happen with a submit button.)
                        $res .= "return false;\n";

                        $res .= "\n}\n";
                        $res .= "\n";
                }
                return $res;
        }

 修正後のcontrols.inc.phpによるJavaScriptラッパーの出力は以下のようになります。

function Button1ClickWrapper(event, hiddenfield, submitvalue, wrappedfunc)
{

var event = event || window.event;
submit1=true;
submit2=true;
if (typeof(wrappedfunc) == 'function') submit1=wrappedfunc(event);
form = hiddenfield.form;
if ((form) && (form.onsubmit) && (typeof(form.onsubmit) == 'function')) submit2=form.onsubmit();
if ((submit1) && (submit2)){
  hiddenfield.value = submitvalue;
  form.submit();
}
return false;

}

 hiddenフィールドへの値の設定が、submit1とsubmit2の両方が成功したときに限定されているので、これなら途中でキャンセルが発生してもイベントが重複して発生することはありません。この不具合対応は作者のホセにも伝わっているのですが、残念なことにライブラリへの取り込みはまだされていていません。

●JavaScriptラッパーの修正
JavaScriptタブ

 さて今回は、Delphi for PHPの触りの部分だけを紹介しました。PHPにおけるビジュアル開発を可能にしたDelphi for PHPが、どのような機構でイベントを取り扱っているか分かっていただければ幸いです。

 次回は、データベースへの接続アプリケーションの作成の紹介し、それを通じてさらにVCLの中へ潜ってみたいと思います。こうご期待!

prev
3/3
 

Index
えっ、まだPHPでVisual開発してないの?
  Page1
Delphi for PHP 2.0ってどんな製品?
PHPでもビジュアル開発だ!
  Page2
JavaScriptイベント
Delphi for PHPのイベント機構
Page3
controlsクラスの不具合の修正

index 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の世界を体験してみよう
  Coding Edgeフォーラムフィード  2.01.00.91


Coding Edge フォーラム 新着記事
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

>

Coding Edge 記事ランキング

本日 月間