&pgid();

**目次 [#t3508b1b]

#contents

**CGI-Ajax [#e58ed3a8]

CGI::AjaxはHTMLページ上に発生したJavaScriptイベントをトリガーに非同期にperlのサブルーチンをコールすることを可能にします。このために、まず、下記のようにJavaScriptのファンクション名とPerlサブルーチンのリファレンスとをマッピングさせます。

 my $cjx = new CGI::Ajax( 'JSFUNC' => \&PERLFUNC );

JSFUNCはJavaScriptのファンクション名、PERLFUNCはJSFUNCにマッピングさせるPerlサブルーチンです。

次に、JSFUNCを起動するトリガー(JavaScriptイベント)をセットします。ここでは、onClickを例に示してみます。

 onClick="JSFUNC(['source1','source2'], ['dest1','dest2']);"

ここまでの記述によって、onClickイベント発生時にJSFUNCが起動され、JSFUNCにマッピングされたPerlのサブルーチン(PERLFUNC)がコールされます。

JSFUNCの引数

 ['source1','source2'], ['dest1','dest2']

のsource1、source2、dest1、dest2はHTMLページ内のinput、およびdivのidです。

  <input type=text id=source1 />
  <input type=text id=source2 />
  <div id=dest1></div>
  <div id=dest2></div>

引数は[]でかこまれたものが二つありますが、最初の[]は入力に相当し、二つ目の[]は出力に相当します。
つまり、

 onClick="JSFUNC(['source1','source2'], ['dest1','dest2']);"

と表記すると、JSFUNCへの入力としてsource1、source2が指し示すinputへの入力データを渡し、結果をdest1、dest2が指し示すdivに出力することになります。JSFUNCはPERLFUNCとマッピングされているため、source1、source2がPerlサブルーチン(PERLFUNC)の引数になり、Perlサブルーチン(PERLFUNC)の結果がdest1、dest2に返されることになります。

***もっともシンプルな例(一つの入力に一つの出力) [#bc04fe9f]

シンプルな例を示します。下のプログラムを適当な名前で保存し、ブラウザからCGIとして実行するとテキストボックスが表示されます。表示されるテキストボックスに文字列を入力すると(=JavaScriptのkeyupイベントが発生すると)、「[入力した文字列]が入力されました」と画面に非同期で表示します。


 #!/usr/bin/perl
 
 use strict;
 use CGI;
 use CGI::Ajax;
 use Jcode;
 
 my $cgi = new CGI;
 my $cjx = new CGI::Ajax( 'exported_func' => \&perl_func );
 
 print $cjx->build_html( $cgi, \&show_HTML );
 
 sub perl_func {
         my $input = shift;
         my $output = $input . "が入力されました";
         Jcode::convert(\$output, 'utf8', 'euc');
         return $output;
 }
 
 sub show_HTML {
         my $html = <<EOHTML;
         <html>
         <body>
           何か入力してください。
           <input type="text" name="val1" id="val1" onkeyup="exported_func( ['val1'], ['resultdiv'] );"/>
           <br/>
           <div id="resultdiv"></div>
         </body>
         </html>
 EOHTML
         Jcode::convert(\$html, 'utf8', 'euc');
         return $html;
 }

val1上でkeyupイベントが発生するとexported_funcが起動され、exported_func()にマッピングされたperl_func()がval1のvalueを引数にしてコールされます。perl_funcはval1のvalue(=$inputに格納)を「が入力されました」という文字列と結合して(=$outputに格納)、returnします。このリターンされた$outputがexported_func()の第2引数に指定されたresultdivが指し示すdivの値として返されます。

$cjx->build_html()はCGIオブジェクトと画面のHTMLを返すサブルーチンへのリファレンスを引数にとって、Ajaxコードを組み込んだHTMLの文字列を返します。

***複数の入力に複数の出力 [#f217c6df]

 onClick="JSFUNC(['source1','source2'], ['dest1','dest2']);"

のような複数の入出力に対応するには、Perlのサブルーチン(PERLFUNC)で複数の値を引数で受け取り、配列で値を返せばOKです。

 sub perl_func {
        my $source1 = shift;
        my $source2 = shift;
        my $output1 = "source1に" . $source1 . "が入力されました";
        my $output2 = "source2に" . $source2 . "が入力されました";
        Jcode::convert(\$output1, 'utf8', 'euc');
        Jcode::convert(\$output2, 'utf8', 'euc');
        return ($output1, $output2);
 }

例えば、上のようにサブルーチンを定義すると、$source1、$source2にそれぞれsource1、source2での入力値が格納され、$output1の値がdest1に、$output2の値がdest2に返されます。

***独自のJavaScriptファンクションにPerlサブルーチン(PERLFUNC)の返り値を渡す [#qa2cb716]

独自に定義したJavaScriptファンクションにPerlサブルーチン(PERLFUNC)の返り値を渡すこともできます。

  onClick="exported_func(['input1'],[js_process_func]);"

上のjs_process_funcが返り値を渡すJavaScriptファンクション名です。idを指定する時と異なり、'で括りません。('で括るとidとみなしてCGI::Ajaxは動作します)

Perlサブルーチン(PERLFUNC)が複数値(=配列)を返す場合はjs_process_func()の方でargumentsオブジェクトを利用して取得してあげる必要があります。

 function js_process_func () {
   var input1 = arguments[0];
   var input2 = arguments[1];
   // 自分でgetElementByIdで出力先を特定して値をセットする必要アリ
   document.getElementById('outputdiv').innerHTML = input1 + 'と' + input2;
 }

***外部のスクリプトにリクエストする [#j13f3c71]

外部のスクリプトにAjaxのリクエストを飛ばして実行させることも可能です。その為には、CGI::Ajaxのコンストラクタに指定するマッピングでPerlサブルーチンリファレンスではなく、対象スクリプトのURLを指定します。

  my $url = 'scripts/other_script.pl';
  my $cjx = new CGI::Ajax( 'external' => $url );

ページ側の記述はこれまでと同様です。

  onClick="external(['input1','input2'],['resultdiv']);"

外部スクリプト(scripts/other_script.pl)ではCGIオブジェクトのparamメソッドからargsキーを用いてinput1、input2の入力を取得できます。

 #!/usr/bin/perl
 # scripts/other_script.plの例
 
 use strict;
 use CGI;
 
 my $cgi = new CGI;
 my @input = $cgi->param('args');
 
 print $cgi->header();
 print "input length is " . @input . " . \n";

仮に上のスクリプトをscripts/other_script.plとすると、実行結果としてinput1、input2が共に入力されていれば「input length is 2 .」という文字列がresultdivに返されます。

***GET / POST の切り替え [#o9ff7151]

非同期通信を実行する時にリクエストに使うMethodをGET / POSTから選ぶことができます。

GETを使う時は

  onClick="exported_func(['input1'],['result1'], 'GET');"

POSTを使う時は

  onClick="exported_func(['input1'],['result1'], 'POST');"

というふうにJavaScriptファンクションの第3引数に指定します。

デフォルトではGETが使われます。

**参考 [#n347ad27]

-[[CGI-Ajax>http://search.cpan.org/~bct/CGI-Ajax-0.697/]]

トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS

アークウェブのサービスやソリューションはこちら