« Select Option の代替品(1) | メイン | Select Option の代替品(3) »

2021年11月 4日 (木)

Select Option の代替品(2)

・JavaScript その1

【インデント調整のために全角スペースを使用しています】


<script language="JavaScript">

var selectedCode = ''; // 送信元ページから受け取ったパラメータ

TestParam の値var codeIDList =

 [ [222, 'アイルランド'], [278, 'アメリカ'], [242, 'イギリス'],

 [223, 'イタリア'], [207, 'オーストリア'], [230, 'オランダ'],

 [218, 'ギリシャ'], [238, 'スペイン'], [212, 'チェコ'],

 [213, 'デンマーク'], [217, 'ドイツ'], [113, '日本'],

 [231, 'ノルウェー'], [220, 'ハンガリー'], [216, 'フランス'],

 [208, 'ベルギー'], [232, 'ポーランド']

];

// selectedCode の値とオプションリスト内での行番号、キャプションの対応表。

// 配列の要素番号が行番号、[x][0] は selectedCode の値、

//[x][1] は対応するキャプションで、MySelect に表示する文字列、オプションリスト内で強調表示する行を得るために使用する。

// 受信した selectedCode を用いて [x][0] を検索し、一致したものの要素番号と [x][1] の文字列を使用する。

var initialSelection = -1; 選択されtものの行番号。

-1 は「何も選択されていない」を表す。

//

//  <body onload=... で実行する function   処理内容は

// イベントハンドラの登録、Html パラメータ TestParam の受信、

// codeIDList を用いて対応するオプションリスト内での行番号、キャプションを得る

//

function onLoadFunction(){

// イベントハンドラの登録。

 document.addEventListener('auxclick',    closeMyOption, {capture:true}); 

 document.addEventListener('scroll', closeMyOption, {capture:true}); 

 document.addEventListener('keydown', closeMyOption, {capture:true});

 document.addEventListener('mousedown', mouseDownHandler,{capture:true});

// 呼出元ページからのパラメータの受信

 var urlStr = document.location.search; // URL を得る。

 initialSelection = -1; // 行番号、初期化

 if((urlStr != null) && (urlStr.length != 0)){ // URL があるならば

// パラメータ値を得る・・・これは「手抜き」です。パラメータは TestParam だけなので

// パラメータ名を無視して = の後を取得しています

  var eqPos = document.location.search.indexOf('=');

  selectedCode = urlStr.substring(eqPos + 1);

  if(selectedCode != ''){ // パラメータがあるならば

   for(var i=0; i<codeIDList.length; i++){ // codeIDList 内を検索し

    if(codeIDList[i][0] == selectedCode){

     initialSelection = i; // 行番号を得る。

     var mySelectElement = document.getElementById('MySelT0');

// mySelect のキャプション表示 text のエレメントを取得し、キャプションを書き込む。

     mySelectElement.value = codeIDList[i][1]; break;

    }

   } 

  }

 }

}


// オプションリスト表示中の場合には

var activeMySelect=null; // mySelect の id

var activeMyOption=null; // myOption の id

// が格納される。非表示の時はいずれも null。オプションリストが表示されているかの判断に使用する。

var selectedItems=null; // String[][]

  // [0]:mySelect の id

  // [1]:選択されている行の番号

  // オプションの行が選択された状態で再びオプションリスト表示する時

  // 強調表示すべき行を得るために使用する


var normalHeight=20;  <li> の高さ(次回説明)

//
// オプションリストを表示する。mySelect をクリックした時に呼ばれる

// @param mySelectID MySelect の id

// @param mySelectTextID MySelect 内のキャプション表示領域の id

// @param myOptionID オプションリストの id

// @param myUlID オプションリストの <ul> の id

// @param numOptions オプションリストの行数 <li> の数

//

function dispMyOption(mySelectID, mySelectTextID, myOptionID, myUlID, numOptions){

 var myOptionElement = document.getElementById(myOptionID);

 var ulElement = document.getElementById(myUlID);

 if(activeMyOption != null){ // オプションリスト表示中ならば

  myOptionElement.style.display='none'; // 表示を終わる。

  activeMyOption=null; // これはオプションリスト表示中に

  activeMySelect=null; // mySelect がクリックされた場合の処理である。

  return;

 }

 var selectedNo = -2; // 現在選択されている行

// -2:情報がない -1:選択された行はない。 0以上:選択されている行番号

 if(selectedItems == null){ // 情報格納領域がない場合は

  selectedItems = new Array(0); // 作成する

 }

 for(var i=0; i<selectedItems.length; i++){ // 処理中の mySelect の情報が

  if(selectedItems[i][0] == mySelectID){ // 存在するかを調べる

   selectedNo = selectedItems[i][1]; // 存在する場合、それが現在の選択行である

   break;

  }

 }

 if(selectedNo == -2){ // 情報がない場合

  selectedNo = initialSelection; // パラメータで受取った値を現在の選択行とし

  var workArray = new Array(2); // それを selectedItems に保存する。

  workArray[0] = mySelectID;

  workArray[1] = selectedNo;

  selectedItems.push(workArray);

 }

 var optionRows = ulElement.children; // <ul> 以下の子要素(<li>)を得る。

 for(var i=0; i<optionRows.length; i++){ // 各 <li> に対して

  optionRows[i].style.backgroundColor=''; // 背景色なしとする。

 }

 if(selectedNo != -1){ // 現在の選択行がある場合

  var selectedRow = optionRows[selectedNo]; // その行の背景色を

  selectedRow.style.backgroundColor='aquamarine'; // 「選択色」とする。  }

// 処理に必用なエレメントを得る

 var mySelectTextElement = document.getElementById(mySelectTextID);

 var mySelectTextRect = mySelectTextElement.getBoundingClientRect();

 var mySelectElement = document.getElementById(mySelectID);

// mySelect エレメントの上端、下端、左端の座標、幅を得る

// オプションリストの表示サイズ、表示位置の決定に使用する。

 var mySelectRect = mySelectElement.getBoundingClientRect();

 var mySelectTop = mySelectTextRect.top; // 上端

 var mySelectBottom = mySelectTextRect.bottom; // 下端

 var mySelectLeft = mySelectRect.left; // 左端

 var mySelectWidth = mySelectRect.width; // 幅

 var myOptionLiHeight=normalHeight + 20; // <li> の高さ(次回説明)

 var myOptionTotlaHeight=myOptionLiHeight * numOptions;// オプションリスト全体の(全行表示した場合の)高さ

 var windowHeight=window.innerHeight; // window の高さ

 var upperMatgin=mySelectTop; // mySelect 上側の余地

 var lowerMargin=windowHeight-mySelectBottom; // mySelect 下側の余地

 var dispAbove=false; // true:オプションリストは mySelect の上側に表示する

 var numRows = 0; // 表示すべき行数

//

// 表示位置、オプションリストの大きさ(高さ)を得る

//

 if((upperMatgin < myOptionTotlaHeight) && (lowerMargin < myOptionTotlaHeight)){

// 全体の高さが上下いずれの余地よりも大きい場合、高さの調節が必用

  dispAbove = lowerMargin < upperMatgin; // 余地の大きい側に表示する。

  var margine; // 表示に使える余地

  if(dispAbove){

   margin = upperMatgin;

  }else{

   margin = lowerMargin;

  }

  numRows = Math.floor(margin / myOptionLiHeight); // 表示行数

  myOptionTotlaHeight = myOptionLiHeight * numRows; // 表示高さ

 }else{

  dispAbove = lowerMargin < myOptionTotlaHeight; // 高さの表示不要。表示位置を得る。

 }

 ulElement.style.height = myOptionTotlaHeight; // <ul> に高さをセット

 ulElement.style.width = mySelectWidth; // <ul> に幅をセット

 if(dispAbove){ // 表示位置(Y座標)をセットする。

  myOptionElement.style.top = mySelectTop - myOptionTotlaHeight;

 }else{

  myOptionElement.style.top = mySelectBottom;

 }

 myOptionElement.style.left = mySelectLeft; // 表示位置(X座標)

 var listElement=document.getElementById(myOptionID);

 listElement.style.display='block'; // 表示する

 for(var i=0; i<optionRows.length; i++){

  optionRows[i].style.height=normalHeight; // <li> の高さをセットする

 }

// 選択された行がオプションリストの先頭でない場合、その行が表示の中ほどになるように

// (リストの最後ならば下端になるように)スクロール量(行数)を決定する。

 var scrollRows = 0; // スクロール量(行数)

 if(selectedNo != 0){ // 先頭ではない場合

  var maxScrollRows = numOptions - numRows; // 可能な最大スクロール量

  var scrollOffset = Math.floor(numRows / 2); // 中ほどとするためのオフセット

  scrollRows = selectedNo - scrollOffset; // 実際のスクロール量

  if(scrollRows < 0){ // 負数になったら「0」とする

   scrollRows = 0;

  }else{

   if(maxScrollRows < scrollRows){ // 可能な最大スクロール量を越えたら

    scrollRows = maxScrollRows; // 可能な最大量とする

   } // (下端に選択行が表示される)

  }

 }

 ulElement.scrollTop=scrollRows * myOptionLiHeight;

 activeMyOption=myOptionID; activeMySelect=mySelectID;

}


今回はここまで。

このブログ入力ソフト、ソースコードを書くには不適当だね、改行やインデントが無視されたりする。当たり前か・・・。

【後でUpする予定のサンプルの html は,表示の乱れなんか気にせずに「生」のものを書きこみます。コメントも削除します。

コメント

コメントを投稿