基幹業務を Web化するにあたり 5250エミュレータ画面の機能を踏襲したいという要望がある。
HTMLインターフェース上では 5250とは別物と考えなくてはいけないのだが、長年5250画面に
慣れ親しんできたユーザーによっては妥当性検査やField-Exit, 機能キーなどの機能を
どうしてもWebでも実現させたいという希望がある。
5250機能を実現するJavaScript では米国誌 iSeriesNetwork でも紹介記事があるが
ここでは弊社が EnterpriseServer のフレーム・ワークとして開発した JavaScript5250を
紹介する。
JavaScript5250 は iSeriesNetwork での紹介記事よりも拡張された機能を持っている。
これらの機能はまた http://www.officequattro.com の
「ワーク・ショップ」の「受注入力」
というサンプルが公開されているので実際に動作を体験することもできる。
| alertmsg.js | ・・・ | エラー・メッセージの表示 |
| caret.js | ・・・ | キャレット(カーソル)の制御 |
| cookie.js | ・・・ | クッキーの操作 |
| fkey.js | ・・・ | 機能キーの処理 |
| login.js | ・・・ | ログイン操作 |
| rightadjust.js | ・・・ | 右寄せ |
| valckeck.js | ・・・ | 入力妥当性検査 |
| LOGIN.HTM | ・・・ | ログ・イン |
alertmsg(フォーム番号, エレメント番号)
<script language="JavaScript" src="/AS400-NET.USR/LIB5250/alertmsg.js"></script>
| フォーム番号 | ・・・ | エラー・メッセージ(ALERTMSG) が 組み込まれているフォーム番号の数字 |
| エレメント番号 | ・・・ | エラー・メッセージ(ALERTMSG) が 組み込まれているエレメント番号の数字 |
function alertmsg(m,n){
if (document.forms[m].elements[n].value == "########################################")
return(true);
else alert(document.forms[m].elements[n].value);
}
alertmsg は JavaScript の alertメソッドによってエラー・メッセージ
をダイアログBOX として表示します。
HTML でのエラー・メッセージは一般的にはエラー・メッセージを
埋め込んだHTMLを戻す方法が普及していますが、Windows-App
のようにダイアログによってエラー・メッセージを表示すれば視認性も
高まり、ユーザーによってよりわかりやすいものとなります。
alertmsg関数は フィールド:ALERTMSG (エラー・メッセージ) に
値が埋め込まれたときにだけalertメソッドでエラー・メッセージを
表示します。
ALERTMSG に値が埋め込まれていない場合は alertmsg関数は何も行わずに true を返して終了するだけです。
この機能によってCGI はエラーがあったときにだけ
CALLP SETFLD('ALERTMSG': '得意先コードの誤りです。')
のようにALERTMSGフィールドの値を SETFLDプロシージャーに
埋め込んでやれば、alertmsg関数によってエラー・メッセージが
表示されます。
つまりエラーが発生していないような状況であっても、
HTMLテンプレートにはつねにalertmsg関数が含まれているように
設定しておきます。
エラーの無いときはalertmsg関数もブラウザへHTMLテンプレートの
一部として送出されますが、ALERTMSGフィールドに値が
埋め込まれていないので、エラーは表示されることはありません。
エラーがある場合でもエラーが無い場合でも同じHTMLテンプレート
を使用することができることになります。
このことはHTMLテンプレートの扱いを簡単にすると同時に保守を容易にします。
HTMLテンプレートでは
<BODY OnLoad="alrtmsg(0,0)"> : <form name=FLAG> <FLD NAME=ALERTMSG><INPUT TYPE="HIDDEN" NAME="ERRMSG" VALUE=########################################></FLD> </form> : </BODY>
のようにしてALERTMSGフィールドを定義しておいてください。
この ALERTMSG が定義されている位置を
<BODY OnLoad="alrtmsg(0,0)">
のようにしてフォーム番号 (この場合は最初のフォームであるので、
、エレメント番号
その値は 0) (この場合はフォーム中の最初の
で指定します。
エレメントであるので、その値は 0)
フォーム番号とはHTML内に定義されている <form>...</form> の
0 から始まるフォームの順序番号のことです。
またエレメント番号とはフォームに含まれるオブジェクトで、
入力ボックスやコンボボックス、<INPUT ....>で指定される入力要素
の 0 から始まる順序番号のことです。
次の例をご覧下さい。このHTMLはそのままテンプレートとして
出力しても、メッセージは表示されませんが、CGI の中で
CALLP SETFLD('ALERTMSG': '得意先コードの誤りです。')
としてセットしてから出力すると
が表示されます。
<html> <head><title>alertmsgサンプル</title> <script language="JavaScript" src="../LIB5250/alertmsg.js"></script> </head> <body OnLoad="alertmsg(0,0)"> <center> <h1> alertmsgサンプル </h1> </center> <form> <p>フィールドALERTMSG に SETFLD で値を埋めて出力するとエラーが表示されます。</p> <FLD NAME=ALERTMSG><INPUT TYPE="HIDDEN" NAME="ERRMSG" VALUE=########################################></FLD> <input type="TEXT" width="30"> <br> <br><input type="button" onClick="MyScript(document.forms[0].elements[0])" name="click" value=" O K "> </form> </body> </html>
| カーソル位置に続く文字列の削除 | ・・・ | removeAfterCursor(エレメント) |
| 入力欄をフォーカス | ・・・ | setFocus(フォーム, エレメント) |
| フォーカスと同時に文字列を選択状態にセット | ・・・ | setSelectFocus(フォーム, エレメント) |
<script language="JScript" type="text/jscript" src="/AS400-NET.USR/LIB5250/caret.js"></script>
| フォーム | ・・・ | 入力欄のあるフォーム |
| エレメント | ・・・ | 入力欄のあるフォーム・エレメント |
<!--
// removeAfterCursor : カーソル位置に続く文字列の削除
function removeAfterCursor(elem)
{
if ( elem.isTextEdit )
elem.caretPos = document.selection.createRange();
if ( elem.isTextEdit && elem.caretPos ){
var bookmark = unescape( "%u0002" );
var orig = elem.value;
var caretPos = elem.caretPos;
caretPos.text = bookmark;
var i = elem.value.search( bookmark );
elem.value = orig;
if ( i!=-1 ) elem.value = orig.substring(0, i);
}
}
// setFocus : 入力欄のフォーカス
function setFocus(f,e){
document.forms[f].elements[e].focus();
}
// setSelectFocus : フォーカスと同時に文字列を選択状態にセット
function setSelectFocus(f,e){
document.forms[f].elements[e].focus();
document.forms[f].elements[e].select();
}
// -->
caret.js はカーソル制御のための機能を提供します。
最初に caret.js の組み込み指定は language が JavaScript
ではなく JScript になっていることにご注意ください。
JScript とは Microsoft社が IE (InternetExploror) で
提供している JavaScript の拡張版です。
JavaScript ではカーソルの位置を検出することができませんので
JScript を使用しています。
よって carret.jsは IE以外のブラウザでは使用することはできません。
removeAfterCursor関数(カーソル位置に続く文字列の削除)
removeAfterCursor関数は入力のためのテキスト・ボックスに
カーソル(キャッレット)がある場合、そのカーソル以降の文字列をすべて削除します。
これは5250エミュレータにおける入力欄での Field-Exitキー
操作を実現 するものです。
RemoveAfterCursor の引数には
RemoveAfterCursor(document.forms[0].elements[0]);
のようにしてエレメント・オブジェクトを指定します。
次の HTML の例はテキスト・ボックスが表示されるだけの
HTML ですが、何か文字列を入力して文字列の途中に
カーソルをセットしてから Enterキーを押すとカーソルに続く
後続の文字列がすべて消去されます。
-------------------------------------------------------------------------------------------
<html>
<head><title>TEST</title>
<script language="JScript" type="text/jscript" src="/AS400-NET.USR/LIB5250/caret.js"></script>
<script language="JavaScript">
<!--
window.document.onkeydown = doKeys;
function doKeys( key ){
var k = window.event.keyCode;
if ( k == 13 ) {
RemoveAfterCursor(document.forms[0].elements[0]);
return false;
}
return true;
}
// -->
</script>
</head>
<body>
<form>
<input type="TEXT" width="30">
<br>
<br><input type="button" onClick="MyScript(document.forms[0].elements[0])" name="click" value=" O K ">
</form>
</body>
</html>
-------------------------------------------------------------------------------------------
setFocus関数 (入力欄のフォーカス)
setFocus関数は HTMLが最初に表示されたときに明示的に
カーソルをセットしてフォーカスされた状態にします。
【 例 】
setFocus(document.forms[0].elements[0]);
setSelectFocus関数(フォーカスと同時に文字列を選択状態にセット)
setSelectFocus関数は入力欄をフォーカスするだけではなく、
入力欄の文字列を選択状態にセットします。
【 例 】
setSelectFocus(document.forms[0].elements[0]);
| フォームに入力された内容のクッキーへの保存 | ・・・ | setcookie() |
| クッキーの読み取りとフォームへの入力 | ・・・ | getcookie() |
<script language="JavaScript" src="/AS400-NET.USR/LIB5250/cookie.js"></script>
なし
<!--
cookieArray = new Array();
function setcookie(){
cookieArray[0] = document.forms[0].elements[0].value;
cookieArray[1] = document.forms[0].elements[1].value;
cookieArray[2] = document.forms[0].elements[2].value;
cookieArray[3] = document.forms[0].elements[3].value;
cookieArray[4] = document.forms[0].elements[4].checked;
cookieArray[5] = document.forms[0].elements[5].value;
exp=new Date();
exp.setTime(exp.getTime()+1000*60*60*24*3650);
checkstrings = escape(cookieArray[0]);
for (i=1;i < cookieArray.length;i++){
checkstrings += "%00" + escape(cookieArray[i]);
}
document.cookie = "as400_net_com=" + checkstrings + "; expires=" + exp.toGMTString();
}
function getcookie(){
cookielength = document.cookie.length;
cookieArray = document.cookie.split("; ");
checkstrings = "";
i = 0;
while (cookieArray[i]){
if (cookieArray[i].substr(0,14) == "as400_net_com="){
checkstrings = cookieArray[i].substr(14,cookieArray[i].length);
break;
}
i++;
}
cookieArray = checkstrings.split("%00");
if (cookieArray[0]) document.forms[0].elements[0].value = unescape(cookieArray[0]);
if (cookieArray[1]) document.forms[0].elements[1].value = unescape(cookieArray[1]);
if (cookieArray[3]) document.forms[0].elements[3].value = unescape(cookieArray[3]);
if (cookieArray[4] == "true") {document.forms[0].elements[4].checked = true;
document.forms[0].elements[2].value = unescape(cookieArray[2])};
else {document.forms[0].elements[4].checked = false;
document.forms[0].elements[2].value = "";}
if (cookieArray[5]) document.forms[0].elements[5].value = unescape(cookieArray[5]);
}
// -->
クッキーとはWebサーバーからブラウザーを通じて、訪問者のPCに
一時的にデータを書き込んで保存させるしくみ(または保存された
データそのもの)を指します。
クッキーを使用すると、訪問者が入力した情報などが記録され、
次回以降そのサイトを訪問した際は、記録された情報をもとに
ページが表示されます。
例えば掲示板やショッピングカート等で多く利用されており、掲示板
では投稿する際に名前やメールアドレスなどの固定情報を
初回訪問時にクッキーとして保存し、再訪問時にこの情報を初期値
として自動表示させる、というものです。
訪問者としては、入力の手間が省けて効率的といえます。
ブラウザーを通じてPCに格納されたクッキーは次の場所で確認する
ことができます。
(Windows2000/XP環境でのInternetExplorerの場合)
\Documents and Settings\ログオン名\Local Settings\Temporary Internet Files\MyCookie \Documents and Settings\ログオン名\Cookies\MyCookie.txt
あるいはInternetExplorerの [ツール]−[インターネット オプション]−
「全般」タブのインターネット一時ファイル−「設定」ボタン−
「ファイルの表示」でも確認できます。
クッキーの中身はこのようになっています。
as400_net_com 192.168.1.1%00QUSER%00%00CONSOLE%00false%000080 192.168.1.1/AS400-NET.USR/PROJECT/LOGIN/ 1088 2041707776 30347869 3262962256 29613614 *
クッキーは便利な反面、危険性も孕んでいます。例えば、一台の
PCを複数のユーザーが同じアカウントで使用する場合、クッキーに
記録された情報が共有される事になります。
また、クッキーをセットしたサーバー以外のサーバーから、そのクッキー
に記録された情報を読み出す事は、基本的には出来ないように
なっているのですが、絶対的な保証はありません。
従って『クレジットカードやパスワードなどの大切な情報はクッキーに
保存しないようにする』といった心構えも必要かも知れません。
なお、InternetExplorer でクッキーに関する設定をする場合は次の
手順で行ないます。
クッキーを受け入れる場合は、【 自動 Cookie 処理を上書きする】 チェックボックスを
クリックして、チェックを入れます。
そのほかの項目は下記の通りです。
| [ファースト パーティ] | ・・・ | 現在表示している Webページ |
| [サード パーティ] | ・・・ | 現在表示している Webページ以外の Webページ |
| 【 受け入れる 】 | ・・・ | クッキーが常にコンピュータに保存されます |
| 【 ブロックする 】 | ・・・ | クッキーはコンピュータに保存されません |
| 【 ダイアログを表示する 】 | ・・・ | クッキーをコンピュータに保存するかどうかの 確認メッセージが表示されます |
| 【 常にセッション Cookie を許可する 】 | ・・・ | InternetExplorer が終了するとコンピュータから削除 される一時的なクッキーが、常にコンピュータに 保存されるようになります |
ユーザーがログ・イン画面として汎用的に使用できるように
EnterpriseServer で提供されている LOGIN.HTM もクッキーを
利用しています。
LOGIN.HTMには ホスト、ユーザー、パスワード、端末名、パスワード
の保存、PORT番号 といった入力欄がありますが、ログインの都度、
毎回それらを入力していたのでは手間も時間もかかります。
そこで最新の入力情報をクッキーに保存しておき、次のログイン時に
その情報をあらかじめ入力欄にセットすることで、ログイン操作を
効率よく行なえるようにするわけです。
従って、ブラウザ側ではクッキーを受け入れる設定になっていることを
確認してください。(初期状態は「受け入れる」設定です)
なおクッキーの制御はすべて cookie.js に記述した JavaScript で
行なっています。その内容は次の通りです。
グローバル変数:cookieArray
クッキーの操作に使用する配列です。
グローバル変数として定義することで、後述のsetcookie関数、
getcookie関数で共用します。
setcookie関数
<form> : <input type="button" value=" O K " onClick="javascript:setcookie();signin();"> <input type="button" value="キャンセル" onClick="javascript:window.close();"> : </form>
setcookie関数はログインする際、LOGIN.HTMの「OK」ボタンを
クリックしたときに実行されます。
そしてLOGIN.HTMのフォームに入力された最新の情報を
クッキーに保存します。
cookieArray[0] = document.forms[0].elements[0].value; cookieArray[1] = document.forms[0].elements[1].value; cookieArray[2] = document.forms[0].elements[2].value; cookieArray[3] = document.forms[0].elements[3].value; cookieArray[4] = document.forms[0].elements[4].checked; cookieArray[5] = document.forms[0].elements[5].value;
cookieArray[0]〜[5]はグローバル変数で定義した配列です。
LOGIN.HTMの6つのエレメントの内容が次のように、それぞれ
代入されます。
cookieArray[0] ・・・ ホスト(IPアドレス) cookieArray[1] ・・・ ユーザー名 cookieArray[2] ・・・ パスワード cookieArray[3] ・・・ 端末名 cookieArray[4] ・・・ 「パスワードの保存」フラグ(真偽値) cookieArray[5] ・・・ PORT
exp=new Date(); exp.setTime(exp.getTime()+1000*60*60*24*3650);
クッキーの有効期限(現在から3650日後)を設定します。
なおJavaScriptの時間単位は1/1000秒ですので、計算式は
補正(1000)×秒(60)×分(60)×時(24)×日(3650日)
となります。
checkstrings = escape(cookieArray[0]);
for (i=1;i < cookieArray.length;i++){
checkstrings += "%00" + escape(cookieArray[i]);
}
このループで、変数checkstringsに、ESCAPEされた配列
cookieArray の値を "%00"で区切って連結します。
%00はヌル文字をESCAPEしたもので、フォームの入力には
まず使用されないため、区切り記号の利用に適しています。
document.cookie = "as400_net_com=" + checkstrings + "; expires=" + exp.toGMTString();
上記で定義したcheckstrings(データ)、有効期限に加え、
クッキーを呼び出す際のために、"as400_net_com"という名前
を付けてクッキー情報を書き込みます。
getcookie関数
呼び出し元となるLOGIN.HTMでは次のように、getcookie関数
の実行を設定しています。
<body bgcolor="#000000" onLoad="javascript:getcookie(); alertpop(1,0); setFocus(0,0);">
これによりLOGIN.HTMがブラウザに読み込まれたら直ちに実行
されることになります。
cookielength = document.cookie.length;
cookieArray = document.cookie.split("; ");
setcookie関数がまず行なうことは、前記setcookie関数で
クッキーの保存時に指定した、"as400_net_com"の文字列
から始まるクッキーを選別するための作業です。
checkstrings = "";
checkstringsの中身をブランクに設定します。
これは後に行なう checkstrings.split("%00") の際に、エラーを
防ぐための対応です。
i = 0;
while (cookieArray[i]){
if (cookieArray[i].substr(0,14) == "as400_net_com="){
checkstrings = cookieArray[i].substr(14,cookieArray[i].length);
break;
}
i++;
}
このループで cookieArray に対して、最初の14文字が
「as400_net_com=」で始まっているか否かをチェックし、
「as400_net_com=」で始まっているものが見つかったら、
そこに含まれる内容を取り出して checkstrings に代入します。
代入され次第、break でループを終了させます。
これで目的のクッキーの選別と、そこに含まれる前回の
ログイン情報の抽出までが完了したことになります。
cookieArray = checkstrings.split("%00");
配列 cookieArray に抽出した文字列を"%00"で区切った
ものを代入します。
if (cookieArray[0]) document.forms[0].elements[0].value = unescape(cookieArray[0]);
if (cookieArray[1]) document.forms[0].elements[1].value = unescape(cookieArray[1]);
if (cookieArray[3]) document.forms[0].elements[3].value = unescape(cookieArray[3]);
if (cookieArray[4] == "true") {document.forms[0].elements[4].checked = true;
document.forms[0].elements[2].value = unescape(cookieArray[2])};
else {document.forms[0].elements[4].checked = false;
document.forms[0].elements[2].value = "";}
if (cookieArray[5]) document.forms[0].elements[5].value = unescape(cookieArray[5]);
文字列をUNESCAPEしたものをフォームに書き込みます。
(ブランクの文字列があった場合は何も行ないません)
これでクッキーに保存されていた情報(最新のログイン時の
入力内容)がすべてフォームの入力欄にセットされることに
なります。
ただし cookieArray[4] つまり「パスワードの保存」フラグが
true(真)でない場合に限り、
document.forms[0].elements[2].value
fkey(キー・イベント)
<script language="JavaScript" src="/AS400-NET.USR/LIB5250/fkey.js"></script>
| キー・イベント | ・・・ | windowsオブジェクトのキー・イベントを処理する。 |
<!--
window.document.onkeydown = fkey;
window.onhelp = disableHelp;
// fkey : 機能キーの処理... form[0] の変数 CMD にCTRL, F1, ... F24 を入れてsubmit する。
function fkey(key)
{
var CMD;
var k = window.event.keyCode;
if ( k == 13 ) return false;//EnterキーにはSUBMIT動作はさせない。
if ( k == 17 ){//実行キー
CMD = "CTRL";
document.forms[0].CMD.value = CMD;
document.forms[0].submit();
}//実行キー
if ( k > 111 && k < 136 ){//機能キー
switch ( k ){
case 112: CMD = "F1"; break; //F1
case 113: CMD = "F2"; break; //F2
case 114: CMD = "F3"; break; //F3
case 115: CMD = "F4"; break; //F4
case 116: CMD = "F5"; break; //F5
case 117: CMD = "F6"; break; //F6
case 118: CMD = "F7"; break; //F7
case 119: CMD = "F8"; break; //F8
case 120: CMD = "F9"; break; //F9
case 121: CMD = "F10"; break;//F10
case 122: CMD = "F11"; break;//F11
case 123: CMD = "F12"; break;//F12
case 124: CMD = "F13"; break;//F13
case 125: CMD = "F14"; break;//F14
case 126: CMD = "F15"; break;//F15
case 127: CMD = "F16"; break;//F16
case 128: CMD = "F17"; break;//F17
case 129: CMD = "F18"; break;//F18
case 130: CMD = "F19"; break;//F19
case 131: CMD = "F20"; break;//F20
case 132: CMD = "F21"; break;//F21
case 133: CMD = "F22"; break;//F22
case 134: CMD = "F23"; break;//F23
case 135: CMD = "F24"; break;//F24
}
document.forms[0].CMD.value = CMD;
document.forms[0].submit();
}//機能キー
}
// -->
fkey.js は実行キー(Ctrlキー)や機能キー(F1 - F24) が押された
ことを検知してCMD という名前で定義されている変数に押された
機能キーの種類を保管してSUBMIT を行います。
5250エミュレータ画面での典型的な機能キー操作を
HTMLインターフェース上で実現するための機能です。
最初のformの最初のエレメントとして
<input type="hidden" name="CMD">
のように CMD という名前の項目を組み込んでおく必要があります。
CGI では
----------------------------------------------------------------------------
CSR EVAL VALUE = CGIPARM('CMD ')
CSR MOVEL VALUE CMD 4
C*( 実行キー )
CSR CMD IFEQ 'CTRL'
:
CSR END
C*( F3 = 終了 )
CSR CMD IFEQ 'F3 '
:
CSR END
----------------------------------------------------------------------------
のようにしてCMD のフィールド値によって、どの機能キーが操作員に
よって押されたのかを判断することができます。
次は fkey.js を組み込んだHTMLの例を示しています。
fkey.js の中の関数自体は明示的に呼び出す必要はありません。
---------------------------------------------------------------------------- <html> <head><title>fkeyサンプル</title> <script language="JavaScript" src="../LIB5250/fkey.js"></script> </head> <body> <center> <h1> fkeyサンプル </h1> </center> <form> <p>実行キー(Ctrl) や機能キーによってSUBMIT することができます。</p> <input type="hidden" name="CMD"> <input type="TEXT" width="30"> <br> <br><input type="button" onClick="MyScript(document.forms[0].elements[0])" name="click" value=" O K "> </form> </body> </html> ----------------------------------------------------------------------------
| ログインPOPUP画面の表示 | ・・・ | popuplogin(POPUP表示するファイルのURL,POPUP画面の名称, POPUP画面の幅, POPUP画面の高さ, スクロールバーの有無) |
| ログイン実行のメインルーチン | ・・・ | signin() |
| ログイン実行のサブルーチン (親ウィンドウのフォームをサブミットして ログインPOPUP画面を閉じる) | ・・・ | loginparent() |
| ログイン実行のサブルーチン (親ウィンドウのフォームをサブミットして ログインPOPUP画面を閉じる) | ・・・ | contlogin() |
<script language="JavaScript" src="/AS400-NET.USR/LIB5250/login.js"></script>
| POPUP表示するファイルのURL | ・・・ | POPUP表示するファイルのURLを親画面からの相対パス またはルートからの絶対パスで記述 |
| POPUP画面の名称 | ・・・ | 任意 |
| POPUP画面の幅 | ・・・ | ピクセル数で指定 |
| POPUP画面の高さ | ・・・ | ピクセル数で指定 |
| スクロールバーの有無 | ・・・ | yes, no より指定 |
<!--
function popuplogin(uri, win_name, popw, poph, scroll) {
var win_width = (screen.width - popw) / 2;
var win_height = (screen.height - poph) / 2;
var win_param = 'height='+poph+',width='+popw+',top='+win_height+',left='+win_width+',scrollbars='+scroll;
window.open(uri, win_name, win_param)
}
function signin(){
loginparent();
contlogin();
}
function loginparent(){
Adrs = document.forms[0].elements[0].value;
portnum = document.forms[0].PORT.value;
sndAdr = "http://" + Adrs + ":" + portnum + "/cgi-bin/LOGINPGM";
window.opener.document.forms[0].action = sndAdr
window.opener.document.forms[0].elements[0].value = document.forms[0].elements[1].value;
window.opener.document.forms[0].elements[1].value = document.forms[0].elements[2].value;
window.opener.document.forms[0].elements[2].value = document.forms[0].elements[3].value;
}
function contlogin(){
window.opener.document.forms[0].submit();
this.window.close();
}
// -->
login.js はログインに関する一連の処理
を行なうための関数を定義したものです。
ただし、POPUP画面に入力した内容をそのままサブミットすると
POPUPウィンドウ内に次の画面が表示されてしまいますので、
Aの内容はPOPUP画面に入力された情報を親画面に渡し、
親画面から実際のサブミット動作を行なう、という特殊なものに
なっています。
popuplogin関数
親画面で使用する関数で、POPUPログイン画面をディスプレイ
の中央に表示します。
JavaScript ではウィンドウの生成位置はディスプレイ左上端
(0,0)を基点に 生成するウィンドウの左上端までの距離を
left=Xピクセル、top=Yピクセルといった記述で指定します。
そのため生成するウィンドウの幅と高さを考慮に入れなくては
ならないうえ、ウィンドウを表示するディスプレイの解像度(画面の
大きさ)も実行環境によって異なるため、left、topに一律の値を
指定することはできません。
そこで次の方法で、常にPOPUP画面を画面中央に表示する
ためのleft、topの値を変数 win_width および win_height
として求めます。
var win_width = (screen.width - popw) / 2; var win_height = (screen.height - poph) / 2;
screen.width、screen.height はディスプレイ表示域の幅と高さ
をそれぞれ意味するもので、popw、poph は生成するウィンドウの
幅と高さです。
var win_param = 'height='+poph+',width='+popw+',top='+win_height+',left='+win_width+',scrollbars='+scroll; window.open(uri, win_name, win_param)
ここでウィンドウを生成するのですが、実際にその役割を
担っているのは
window.open("URL", "ウィンドウ名称", "各種パラメータ")
という関数です。
引数である各種パラメータには
| toolbar | [=yes|no] | ツールバーの表示/非表示 |
|---|---|---|
| location | [=yes|no] | ロケーションバーの表示/非表示 |
| directories | [=yes|no] | ディレクトリバーの表示/非表示 |
| status | [=yes|no] | ステータスバーの表示/非表示 |
| menubar | [=yes|no] | メニューバーの表示/非表示 |
| scrollbars | [=yes|no] | スクロールバーの表示/非表示 |
| resizable | [=yes|no] | ウィンドウサイズ変更の可否 |
| width | =Xpixels | ウィンドウの横幅 |
| height | =Ypixels | ウィンドウの高さ |
| left | =XXpixels | デスクトップ左端からの座標 |
| top | =YYpixels | デスクトップ上端からの座標 |
などがあります。
なお、ブラウザの種別やバージョンによって使用できるパラメータ
は異なりますのでご注意下さい。
(上記はInternetExplorer 5.0 以上で動作可能なもの)
このパラメータは "," 区切りで複数を指定することも可能です。
ちなみに「TOP_Window」という名称の320×240のウィンドウを
スクロールバー無しで表示する場合は次のようになります。
window.open("MyWin.html","TOP_Window","width=320,height=240,scrollbars=no")
注意していただきたいのが " " (ダブル・クォート)の位置です。
パラメータ部分全体で " " で括られており、複数の項目を
一括して扱っていることがわかります。従って、
var win_param =
はパラメータ部分を一括りにするための変数で、ここに先ほど
求めた画面中央にPOPUP画面を生成するための座標と
ウィンドウの幅、高さ、およびスクロールバーを表示しない指定
を代入しているわけです。
< LOGIN.HTM を呼び出す HTML の例 >
<form method="GET">
<input type="hidden" name="USER">
<input type="hidden" name="PASSWRD">
<input type="hidden" name="DSPID">
<input type="hidden" name="@TEMPLATE" value="/AS400-NET.USR/PROJECT/MENU/MENU.HTM">
</form>
<a href="javascript:popuplogin('/AS400-NET.USR/PROJECT/LOGIN/LOGIN.HTM','LOGINPOPUP','390','210','no')">
<font><b>ログインはこちらからどうぞ</b></font></a>
呼び出し元のHTMLにある「ログインはこちらから」のリンク部分を
クリックすると
popuplogin('/AS400-NET.USR/PROJECT/LOGIN/LOGIN.HTM','LOGINPOPUP','390','210','no')
が実行されることになります。
/AS400-NET.USR/PROJECT/LOGIN/LOGIN.HTMを、
LOGINPOPUPという名称の 幅390、高さ210のウィンドウで、
スクロールバーを表示しない設定で、画面中央に生成する、
という動作が行なわれるのです。
signin関数
signin関数はloginparent関数を実行した後にcontlogin関数を
実行します。
サブルーチン:loginparent関数
loginparent関数はログインPOPUP画面に入力された内容を
親画面のフォームに代入する、というものです。
< 親画面・例 >
<form method="GET">
<input type="hidden" name="USER">
<input type="hidden" name="PASSWRD">
<input type="hidden" name="DSPID">
<input type="hidden" name="@TEMPLATE" value="/AS400-NET.USR/PROJECT/MENU/MENU.HTM">
</form>
<a href="javascript:popuplogin('/AS400-NET.USR/PROJECT/LOGIN/LOGIN.HTM','LOGINPOPUP','390','210','no')">
<font><b>ログインはこちらからどうぞ</b></font></a>
上記のように親画面の <form> にはアクション先の明示が
ありません。これはログインPOPUP画面で入力したホスト欄の
IPアドレス、PORT欄のポート番号宛にサブミットする必要が
あるため、loginparent関数内部でアクションに関する処理も
行なっていることに依ります。
Adrs = document.forms[0].elements[0].value; portnum = document.forms[0].PORT.value; sndAdr = "http://" + Adrs + ":" + portnum + "/cgi-bin/LOGINPGM"; window.opener.document.forms[0].action = sndAdr
document.forms[0].elements[0].value がホスト欄の
IPアドレスで、document.forms[0].PORT.value がPORT欄の
ポート番号です。
http://" + Adrs + ":" + portnum としてIPアドレスと
ポート番号を組み合わせ、更に + "/cgi-bin/LOGINPGM"
にてプログラムへのパスを指定します。これを sndAdr という変数
に代入し、window.opener.document.forms[0].action つまり
ログインPOPUP画面の親画面にある、最初のフォームの
アクション先に指定します。
window.opener.document.forms[0].elements[0].value = document.forms[0].elements[1].value; window.opener.document.forms[0].elements[1].value = document.forms[0].elements[2].value; window.opener.document.forms[0].elements[2].value = document.forms[0].elements[3].value;
ログインPOPUP画面で入力したユーザー名、パスワード、
端末名を、それぞれ親画面の最初のフォームのエレメント[0]、
[1]、[2]に順番に代入します。
サブルーチン:contlogin関数
前記loginparent関数によって、ログインPOPUP画面で入力した
内容に従って必要な値が親画面のフォームに埋め込まれました
ので、これをサブミットします。
window.opener.document.forms[0].submit(); this.window.close();
親画面におけるサブミットが完了したらログインPOPUP画面
(this.window)を閉じます。
rightAdjust(フォーム, エレメント)
<script language="JavaScript" src="/AS400-NET.USR/LIB5250/rightadjust.js"></script>
| フォーム | ・・・ | 入力欄のあるフォーム |
| エレメント | ・・・ | 入力欄のあるフォーム・エレメント |
<!--
function rightAdjust( iForm, iElem )
{
if( window.event.keyCode != 13) return;
var obj = document.forms[iForm].elements[iElem];
obj.style.textAlign="right";
}
// -->
rightAdjust 関数は5250エミュレーター画面でのEnterキーによる
数字の右寄せを実現します。
処理の原理としては最初に右寄せを実現したいフィールドの
イベント・ハンドラとしてrightAdjust関数を割り当てておくと
Enterキーによる右寄せ機能が働くというものです。
次の例では最初だけ setHandler関数によってフォーム番号= 0
(最初のフォーム) の エレメント番号 = 0 (最初のエレメント) に
rightAdjust 関数を キー・ダウン(onkeydown) の関数として
ハンドラを割り当てています。
fkey.js を包含しているのは EnterキーによるSUBMIT動作を
抑えてしまうためです。
------------------------------------------------------------------------------------------
<html>
<head><title>rightadjustサンプル</title>
<script language="JavaScript" src="../LIB5250/rightadjust.js"></script>
<script language="JavaScript" src="../LIB5250/fkey.js"></script>
<script language="JavaScript">
<!--
window.document.onkeydown = fkey;
function setHandler(){
var i = 0;//form no
var j = 0;//element no
document.forms[i].elements[j].onkeydown=new Function("rightAdjust(" + i + "," + j + ")");
}
// -->
</script>
</head>
<body OnLoad="setHandler()">
<center>
<h1> rightadjust サンプル </h1>
</center>
<form>
<p>項目に数字を入力してEnterキーを押すと右寄せされます。</p>
<input type="TEXT" width="10">
------------------------------------------------------------------------------------------
| 半角英数記号チェック | ・・・ | isAlpha(エレメント) |
| 全角文字チェック | ・・・ | isKanji(エレメント) |
| 半角数字 | ・・・ | isNumeric(エレメント) |
| 半角整数 | ・・・ | isSuji(エレメント) |
| 半角カナチェック | ・・・ | isKana(エレメント) |
<script language="JScript" type="text/jscript" src="/AS400-NET.USR/LIB5250/valcheck.js"></script>
| エレメント | ・・・ | 入力欄のあるフォーム・エレメント |
<!--
// 半角英数記号チェック
function isAlpha( te ){
var newText = "";
for (i = 0; i < te.value.length; i++) {
ch = te.value.substring(i, i+1);
if (ch >= " " && ch <= "~") {
newText += ch;
}
}
return ShowDialog(newText,te,"半角英数入力","半角英数記号");
}
// 全角文字チェック
function isKanji( te ){
var newText = "";
for (i = 0; i < te.value.length; i++) {
ch = te.value.substring(i, i+1);
if (!(ch > " " && ch <= "~") && !(ch >= "ア" && ch <= "ン") && !(ch >= "ァ" && ch <= "ッ")
&& !(ch >= "。" && ch <= "゚")) {
newText += ch;
}
}
return ShowDialog(newText,te,"全角文字入力","全角文字(漢字、カナ、かな、A、記号)");
}
// 半角数字("0"〜"9" "-" "," "." " ")チェック
function isNumeric(te){
var newText = "";
for (i = 0; i < te.value.length; i++) {
ch = te.value.substring(i, i+1);
if (ch > "+" && ch < "/" || ch>="0" && ch <="9" || ch==" " ) {
newText += ch;
}
}
return ShowDialog(newText,te,"半角数字入力","半角数字");
}
// 半角整数(0〜9)チェック
function isSuji(te){
var newText = "";
for (i = 0; i < te.value.length; i++) {
ch = te.value.substring(i, i+1);
if (ch >= "0" && ch <= "9") {
newText += ch;
}
}
return ShowDialog(newText,te,"半角整数入力","半角整数(0〜9)");
}
// 半角カナチェック
function isKana(te){
var newText = "";
for (i = 0; i < te.value.length; i++) {
ch = te.value.substring(i, i+1);
if (ch >= "ア" && ch <= "ン" || ch >="ァ" && ch <="ッ" || ch >= "。" && ch <="゚" || ch==" " ) {
newText += ch;
}
}
return ShowDialog(newText,te,"半角カナ入力","半角カナ");
}
// ダイアログ表示
function ShowDialog(newText, te, Area,Text){
var checkText = te.value;
if (checkText != newText) {
//if (confirm(Area+"欄に不正な文字が入力されています。\n"+Text+"のみを入力してください。")) {
//window.status = Area + "欄に不正な文字が入力されています。\n"+Text+"のみを入力してください。";
alert(Area+"欄に不正な文字が入力されています。\n"+Text+"のみを入力してください。");
//te.focus();
te.value = newText;
return false;
//}
}
return true;
}
// -->
valcheck.js (入力妥当性検査)は5250エミュレーター画面と
同じような入力文字の妥当性検査の機能を提供します。
通常、HTML画面では措置を施さない限りにおいては、どのような
文字であっても検査されることなく入力されてしまいますが、
5250画面では例えば数字として定義されているフィールドには
数字以外の文字は入力することはできません。RPGプログラマーは
数字フィールドに対して数字でない文字が不正な文字として入力
されてしまうことについてまで想定して検査する必要はありません
でしたが、HTMLでは、すべての文字が入力可能になってしまいます
ので、JavaScriptで不正な文字が入力されないように防御する
必要があります。
ここで考慮が必要であるのはひとくちに数字とは言っても
数字= 0,1, ... 9
だけではなく、小数点やカンマ、マイナス符号も「数字」の一部として
認める必要があることです。
Windowsの世界では数字というと「数」しか入力できなくしてしまう
という非常に現実離れした考えで構成されています。
これはMicrosoft社の開発者がビジネスの適用業務の開発経験が
ほとんど無いからではではないかとも思えてしまいます。
5250画面の「数字」という概念をサポートしているのが
isNumeric関数です。
次の例のHTMLでは数字以外を入力してSUBMIT しようとすると
エラーとなる使用方法を示しています。
--------------------------------------------------------------------------------------------
<html>
<head><title>valcheckサンプル</title>
<script language="JavaScript" src="../LIB5250/valcheck.js"></script>
<script language="JavaScript">
<!--
function MyScript( elem ){
if(isNumeric(elem)) return false;
}
// -->
</script>
</head>
<body>
<center>
<h1> valcheckサンプル </h1>
</center>
<form>
<p>項目には数字以外を入力してSUBMITするとエラーになります。</p>
<input type="TEXT" width="30">
<br>
<br><input type="button" onClick="MyScript(document.forms[0].elements[0])" name="click" value=" O K ">
</form>
</body>
</html>
--------------------------------------------------------------------------------------------
LOGIN.HTM (ログ・イン) はユーザーがログ・イン画面として
汎用的に使用できるようにEnterprise Server で提供されている
HTML です。
LOGIN.HTM を表示してSUBMIT するとCGI: CGIBIN/LOGINPGM
が呼び出されて実行されます。
LOGIN.HTM は初期値として
| IPアドレス | = | 192.168.1.1 |
| ユーザー | = | QUSER |
| パスワード | = | QUSER |
| 端末ID | = | CONSOLE |
が埋め込まれていますので、ユーザーの仕様に合わせて修正して、
ご利用ください。
また、LOGIN.HTM のSUBMIT と同時に 次に表示すべきである
HTMLのフル・パス名を @TEMPLATEパラメータとして渡してやると
CGI: CGIBIN/LOGINPGM はログインが成功裡に完了すると
@TEMPLATEとして指定されたHTMLをオープンします。
@TEMPLATEで指定された次に表示するHTMLにもユーザー、
パスワード、端末ID が用意されていなければなりません。
LOGINPGM は次のHTMLテンプレートにも、これらの値を
埋め込みます。
また LOGIN.HTM はユーザーの入力値をクッキーに保存します。
つまり、これらの関係は次のようになります。
<form method="GET">
<input type="hidden" name="USER">
<input type="hidden" name="PASSWRD">
<input type="hidden" name="DSPID">
<input type="hidden" name="@TEMPLATE" value="/AS400-NET.USR/PROJECT/MENU/MENU.HTM">
</form>
<a href="javascript:popuplogin('/AS400-NET.USR/PROJECT/LOGIN/LOGIN.HTM','LOGINPOPUP','390','210','no')">
<font><b>ログインはこちらからどうぞ</b></font></a>
0001.00 H DATEDIT(*YMD/) COPYRIGHT('(C) OFFICE QUATTRO CO,.LTD JAPAN 2003-')
0002.00 F********** ログイン *************************************************
0003.00 F*
0004.00 F**********************************************************************
0005.00 /COPY ASNET.USR/QRPGLESRC,PROTOTYPE
0006.00 D SPCBIN DS
0007.00 D USER 1 10
0008.00 D PASSWRD 11 20
0009.00 D DSPID 21 30
0010.00 * 固定情報
0011.00 D MENU C CONST('/AS400-NET.USR/PROJECT-
0012.00 D /MENU/MENU.HTM')
0013.00 D BASEHTML C CONST('/AS400-NET.USR/PROJECT-
0014.00 D /LOGIN/INDEX.HTML')
0015.00 D ERRMSG C CONST(' ユーザーまたはパスワード
0016.00 D の誤りです。 ')
0017.00 D ERRFLD C CONST('*ERROR*')
0018.00 C*( 標準入力 )
0019.00 C EXSR STDIN
0020.00 C*( ログイン ... 仮想ユーザー環境を開始します。 )
0021.00 C*----------------------------------------------------+
0022.00 C* 指定したユーザー・プロフィールで JOB を開始する
0023.00 C*----------------------------------------------------+
0024.00 C EVAL RESULT = LOGIN(USER : PASSWRD: DSPID)
0025.00 C*( ログインが成功すればユーザー、パスワードをメニューに埋め込みます
0026.00 C RESULT IFEQ TRUE
0027.00 C CALLP OPENHTML(TEMPLATE)
0028.00 C CALLP SETFLD('$(USER)': USER)
0029.00 C CALLP SETFLD('$(PASSWRD)': PASSWRD)
0030.00 C CALLP SETFLD('$(DSPID)': DSPID)
0031.00 C ELSE
0032.00 C MOVEL BASEHTML TEMPLATE
0033.00 C CALLP OPENHTML(TEMPLATE)
0034.00 C CALLP SETFLD('ALERTMSG': ERRMSG)
0035.00 C END
0036.00 C CALLP WRITE
0037.00 C*( ログオフ ... 仮想ユーザー環境を終了します。 )
0038.00 C CALLB 'LOGOFF' 99
0039.00 C SETON LR
0040.00 C RETURN
0041.00 C******************************************************
0042.00 C STDIN BEGSR
0043.00 C******************************************************
0044.00 C*( HTML からの標準入力されたフィールド値の受け取り )
0045.00 C*( HTML からフィールド値の取得 )
0046.00 CSR EVAL USER = CGIPARM('USER ')
0047.00 CSR EVAL PASSWRD= CGIPARM('PASSWRD ')
0048.00 CSR EVAL DSPID = CGIPARM('DSPID ')
0049.00 CSR EVAL TEMPLATE = CGIPARM('@TEMPLATE ')
0050.00 CSR ENDSR