Ajax サンプル 動的コンボボックスの作成

動的コンボボックスの作成

このサンプルソースは、動的COMBOの作成を行っております。
まず、初回起動時に品種名のCOMBOを作成し、品種名COMBOで選択された品種コードに紐付く 商品データのCOMBOを動的に作成しております。

それでは下記サンプルソースで番号順に説明します。

■ 初期画面

サンプル画面

■ HTML サンプルソース
   <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>
					
■ RPG# サンプルソース
   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 のメソッドになります。

それが BgetShnDta()メソッドになります。
このメソッド内で、実際に 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});

この DMK_SHNCMBプロシージャ で XMLレスポンスを生成し以下のような XML をクライントに送信します。

※ XML 生成方法は、解説書 / RPG#解説書 / GUIコントロールの制御 / XML を参照ください。

該当データが存在した場合の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
<?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));

■ 表示画面サンプル

選択結果択