cotorolsクラスの不具合の修正
さて、実はここに大きな問題があります。例えば、Button1のJavaScriptイベントでEditコンポーネントに入力された値のバリデーションを行う場合、戻り値をfalseに設定してJavaScriptラッパーを抜けてしまうと、hiddenフィールドに値が設定されたままになってしまうのです。
この状態で、ほかのボタンでsubmitが実行されると、本来キャンセルされたはずのButton1のPHPイベントもサーバ側で実行されてしまいます! なんてこったい。
●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ラッパーの修正
さて今回は、Delphi for PHPの触りの部分だけを紹介しました。PHPにおけるビジュアル開発を可能にしたDelphi for PHPが、どのような機構でイベントを取り扱っているか分かっていただければ幸いです。
次回は、データベースへの接続アプリケーションの作成の紹介し、それを通じてさらにVCLの中へ潜ってみたいと思います。こうご期待!
3/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の世界を体験してみよう |
|
Coding Edge フォーラム 新着記事
- プログラムの実行はどのようにして行われるのか、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を紹介する。※ショートカットキー、アクセスキーの解説あり
|
|
>
Coding Edge 記事ランキング
本日
月間