このサンプルソースは、動的COMBOの作成を行っております。
まず、初回起動時に品種名のCOMBOを作成し、品種名COMBOで選択された品種コードに紐付く 商品データのCOMBOを動的に作成しております。
それでは下記サンプルソースで番号順に説明します。
<html> <head> <meta http-equiv="Content-Language" content="ja"> <meta http-equiv="Content-Type" content="text/html; charset=shift_jis"> <title>AJAXサンプル 動的コンボボックス生成</title> <STYLE TYPE="TEXT/CSS"> BODY{margin:15px;font-size:13px;background:#fff;text-align:center;} FORM{margin:0;} H1{font-size:26px; margin:10px 0px; color:#666;} HR{height:1px;filter:Alpha(opacity=100,finishOpacity=0,style=1,startX=90,finishX=100) Alpha(opacity=0,finishOpacity=100,style=1,startX=0,finishX=10);} INPUT{height:20px;border:1px solid #999;padding:2px;} .HAND{cursor:hand;filter:progid:DXImageTransform.Microsoft.Gradient(GradientType=0, StartColorStr=#EEEEEE, EndColorStr=#AAAAAA);} .SELECT1{width:100px;font-size:13px;} .SELECT2{width:170px;font-size:13px;} .MAIN{width:300px;height:80px;font-size:10pt;border:1px solid #999;border-collapse:collapse;margin:20px;} .MAIN TD{border-bottom:1px solid #ccc;background:#eee;padding:3px 10px;color:#444;} .MAIN TH{width:100px;border:1px solid #9ac;background:#cde9ff;color:#2e6692;} </STYLE> <script language="javascript"> /* 商品データ取得 */ B function getShnDta(obj){ // このコードでは リクエストしないようにしておく if(obj.value=="0000"){ return; } // Ajax リクエスト var reqUrl="/cgi-bin/AJX002SAM.PGM?"; reqUrl+="ID=CMB_HNSCOD"; reqUrl+="&EVENT=ONCHANGE"; reqUrl+="&RECORD=DSPHEAD"; reqUrl+="&SHSCOD="+obj.value; reqUrl+="&dummydate="+new Date().getTime(); new Ajax.Request(reqUrl, {method :"GET", onComplete:setShnDta}); } /* 取得した商品データを各表示領域にセットする */ E function setShnDta(httpObj){ var obj=httpObj.responseXML.documentElement; var len=obj.childNodes.length; // select options クリア E-1 document.getElementById("CMB_SHCODE").innerHTML=""; // データ有無存在チェック if(len==0){ alert("対象データが存在しません。"); return; } var cd=""; var nm=""; var nodeVal=""; for(var i=0;i<len;i++) { /* XMLエレメント node Name */ var nodeNm=obj.childNodes[i].nodeName; /* XMLエレメント node Obj */ var nodeObj=obj.getElementsByTagName(nodeNm).item(0).firstChild /* XMLエレメント node Value */ nodeVal=""; if(nodeObj==null){nodeVal="";}else{nodeVal=nodeObj.nodeValue;} if(nodeNm.match(/SHCODE/i)) { cd=nodeVal; } if(nodeNm.match(/SHNAME/i)) { nm=nodeVal; } if(cd!="" && nm!=""){ E-2 $('CMB_SHCODE').add(new Option(nm,cd)); cd=""; nm=""; } } } </script> </head> <body> <h1>AJAXサンプル 動的コンボボックス生成</h1> <hr> <ul> <li>品種プルダウンメニューを選択すると 動的に 商品プルダウンメニューが生成されます。</li> </ul> <form name="frmDsphead" method="GET" action="/cgi-bin/AJX002SAM.PGM"> <!-- イベントドリブン用 変数 --> <input type="hidden" name=ID> <input type="hidden" name=EVENT> <input type="hidden" name=RECORD value="DSPHEAD"> <table class="MAIN"> <tr> <th>品種名</th> <td> <!-- AJX002SAM の初回起動時に COMBO ADDITMでセットしている--> A <select name=CMB_HNSCOD id="CMB_HNSCOD" onChange="getShnDta(this);" alt="4A"> <option value="0000">▼品種コードを選択して下さい。</option> </select> </td> </tr> <tr> <th>商品名</th> <td> <select name=CMB_SHCODE id="CMB_SHCODE" alt="10A"> </select> </td> </tr> </table> <hr> <!-- コンボ DSPF の入出力属性 を O→B を考慮 --> <input type="hidden" name=HNSCOD id="HNSCOD" alt="4A"> <input type="hidden" name=SHSCOD id="SHSCOD" alt="4A"> </form> <input type="button" class="HAND" value="閉じる" onClick="clsApplication();"> <input type="hidden" name="ERRMSG" value=""> <input type="hidden" name="REVIMG" value=""> <input type="hidden" name="CURSOR" value=""> </body> <!-- JavaScript VBScript Lib--> <script type="text/javascript" src="/AS400-NET.USR/JS/RPG_SP.JS"></script> <script type="text/javascript" src="/AS400-NET.USR/JS/RPG_SP_CLCHK.JS"></script> <script type="text/javascript" src="/AS400-NET.USR/JS/RPG_SP_GUI_EV.JS"></script> <script type="text/javascript" src="/AS400-NET.USR/JS/PROTOTYPE.JS"></script> <script type="text/vbscript" src="/AS400-NET.USR/JS/CHKFORMAT.VBS"></script> <script type="text/vbscript" src="/AS400-NET.USR/JS/CHKLENGTH.VBS"></script> </html>
H NOMAIN BNDDIR('ASNET.COM/MAIN') DATEDIT(*YMD/) H THREAD(*CONCURRENT) F********** AJAX サンプル ***************************** F* AJX002SAM 言語 : RPG# VER 5.1 F********************************************************************** FAJX002SAMHCF E SPECIAL PGMNAME('ASNET.COM/HTMLDVR') F PLIST(HPARM) F INFDS(INFDSF) FHINSHU IF E K DISK EXTFILE(HINSHU_LIB) FSHOHINL1 IF E K DISK EXTFILE(SHOHIN_LIB) F********************************************************************** F* F* CRTWEBMOD QTEMP/AJX002SAM SRCFILE(ASNET.USR/QRPGLESRC) AUT(*ALL) F* CRTPGM CGIBIN/AJX002SAM MODULE(ASNET.COM/MAIN QTEMP/AJX002SAM) F* ACTGRP(*NEW) AUT(*ALL) F* /COPY ASNET.USR/QRPGLESRC,PROTOTYP5# /COPY ASNET.USR/QRPGLESRC,COMBOBOX5# /COPY ASNET.USR/QRPGLESRC,XML#5 D MK_SHNCMB PR D HTM_FILE S 10A INZ('AJX002SAMH') D HTM_LIB S 10A INZ('*LIBL ') D HINSHU_LIB S 24 INZ('QTRFIL/HINSHU') D SHOHIN_LIB S 24 INZ('QTRFIL/SHOHINL1') D HTM_DIR S 128A INZ('/AS400-NET.USR/PROJECT/- D AJX002SAM') D RSTAG_NM S 9A D FIELD S 12A D VALUE S 30A D TAG_I S 4 0 D D*( ファイル情報データ構造 ) D INFDSF DS D 512A D HTM_RECORD *RECORD D*( プログラム状況データ構造 ) D INFDSP SDS D 512A /COPY ASNET.USR/QRPGLESRC,HPARM C*------------------------------------------------------- C SETKEY KLIST C KFLD HNSCOD C SETKEY1 KLIST C KFLD SHSCOD C C*------------------------------------------------------- ********************************************************* P EVENT B EXPORT ********************************************************* D PI /FREE C ON_CHANGE('DSPHEAD':'CMB_HNSCOD': %PADDR(MK_SHNCMB)); /END-FREE P E ********************************************************* @ P BEGIN B EXPORT ********************************************************* * 初期画面を出力します。 D PI C READ DSPHEAD C DOW *IN50=*OFF C SETOFF 50 C READ HINSHU 50 C 50 CALLP SETEOF C 50 LEAVE C CALLP COMBO(ADDITM:'CMB_HNSCOD':HNSCOD:HNSNAM: C LAST) C END C WRITE DSPHEAD P E ********************************************************* D P MK_SHNCMB B EXPORT ********************************************************* * 品種コンボを選択した時に呼出します。 D PI C CALLP INZXML C EVAL RSTAG_NM = 'RESULT' + X'00' C CALLP BEGINXML(%ADDR(RSTAG_NM)) C C READ DSPHEAD 99 C MOVEL SHSCOD CMPVAL 4 C C SETKEY1 SETLL SHOHINL1 C DOU %EOF(SHOHINL1) C READ SHOHINL1 C SHSCOD IFEQ CMPVAL C C ADD 1 TAG_I C C EVAL FIELD = 'SHCODE'+%CHAR(TAG_I)+ X'00' C EVAL VALUE = SHCODE + X'00' C CALLP ADDXML5026(%ADDR(FIELD):%ADDR(VALUE)) C C EVAL FIELD = 'SHNAME' +%CHAR(TAG_I)+ X'00' C EVAL VALUE = SHNAME + X'00' C CALLP ADDXML5026(%ADDR(FIELD):%ADDR(VALUE)) C C ENDIF C END C C CALLP ENDXML(%ADDR(RSTAG_NM)) C**** XML Response を送出します。 **** C CALLP SENDXML P E ********************************************************* P END B EXPORT ********************************************************* * 最後の処理を記述します。 D PI C CLOSE AJX002SAMH C CLOSE HINSHU C CLOSE SHOHINL1 P E ***************** データの終わり **************************************
まず、初回起動時に @ の BEGINプロシージャ が呼び出されます。
ここでは、品種ファイルを全件読み込み COMBOプロシージャ を使用し 品種COMBO
を動的に作成しています。
A の HTML に CMB_HNSCOD という <SELECT>タグがあります。
この CMB_HNSCOD に COMBOプロシージャを使用し品種ファイルのデータを動的に
追加していきます。まず、これで初期画面が表示されます。
次に初期画面で 品種 COMBO で データを選択する とA の <select>タグに
JavaScript のイベントハンドラである onChangeハンドラ が記述してあります。
onChangeハンドラの右に ="getShnDta(this);" と記述してあるのが、
呼び出される JavaScript のメソッドになります。
それが B の getShnDta()メソッドになります。
このメソッド内で、実際に RPG#-CGI にリクエストする引数を設定し RPG#-CGI に
要求します。
この場合ですと AJX002SAM.pgm に渡す引数を以下のように
設定しています。
RPG# で必須になる ID( GUIコントロールのID名 )、EVENT( ONCHANGE )、RECORD( DSPHEAD )、そして 入力された 商品コードの値 を設定しています。
そして Ajax.Request を使用しリクエストします。
そして RPG#-CGI で リクエスト内容を判断し C の EVENTプロシージャの記述通り
DSPHEAD( RECORDで設定した値 ) 画面で CMB_HNSCOD( GUIコントロールの
ID名 ) が ON_CHANGE( EVENTで 設定した値 ) したという合図を受け
%PADDR() で記述しているプロシージャが実行されます。
new Ajax.Request(reqUrl, {method :"GET", onComplete:setShnDta});
この D の MK_SHNCMBプロシージャ で XMLレスポンスを生成し以下のような XML をクライントに送信します。
※ XML 生成方法は、解説書 / RPG#解説書 / GUIコントロールの制御 / XML を参照ください。
<?xml version="1.0" encoding="Shift_JIS" ?> <RESULT> <SHCODE1>NV-BS30S </SHCODE1> <SHNAME1>目次ビデオTEST@ </SHNAME1> <SHCODE2>NV-BS50S </SHCODE2> <SHNAME2>ビデオ画王 </SHNAME2> <SHCODE3>NV-CF1 </SHCODE3> <SHNAME3>Cカセット編集ビデオ </SHNAME3> <SHCODE4>NV-CF9 </SHCODE4> <SHNAME4>漢字テスト </SHNAME4> <SHCODE5>NV-F850 </SHCODE5> <SHNAME5>音声録画ビデオ </SHNAME5> <SHCODE6>NV-HK1 </SHCODE6> <SHNAME6>歌えるビデオ </SHNAME6> <SHCODE7>NV-H1T-S </SHCODE7> <SHNAME7>みんなのビデオ </SHNAME7> <SHCODE8>NV-SX10 </SHCODE8> <SHNAME8>ビデオ画王 </SHNAME8> <SHCODE9>NV-W1 </SHCODE9> <SHNAME9>世界放送方式ビデオ </SHNAME9> </RESULT>
<?xml version="1.0" encoding="Shift_JIS" ?> <RESULT> <EMSG>データが存在しません。 </EMSG> </RESULT>
ここから RPG#-CGI から JavaScript に戻ります。
B の Ajaxリクエストで以下のコードがありましたが、onComplete:setShnData と記述があります。
これはコールバック関数というものでクライントに制御が移れば、ここで定義した JavaScript のメソッドが呼び出されます。
new Ajax.Request(reqUrl, {method :"GET", onComplete:setShnDta});
ここでは E setShnDataメソッドが呼び出されることになります。
最後に RPG#-CGI より送信された XMLレスポンスを E で DOM解析し HTML の各表示領域に値を設定します。
E-1 で、まず対象の COMBO を以下のように初期化します。これは CMB_SHCODE の コントロールの<option>タグを空にしています。
document.getElementById("CMB_SHCODE").innerHTML="";
その後、E-2 で DOM解析した値を使用し、新しく <option>タグを生成しています。
CMB_SHCODEコントロール に new Option() で生成された <option>タグを add している。
このような流れになります。
$('CMB_SHCODE').add(new Option(nm,cd));