2014/01/17

HTML:Selectタグ内のアイテムに絞込み検索をかける



 JavaScriptを使ってセレクトタグ内の項目のキーワードによる絞込み検索を行う例(IEの人は下の方のを見てみて)。
 上記検索ボックス内に「a」とか「DEF」とかを入れるとリストがそれを含む項目だけに絞られる。
 あるWebシステムを作っていたとき、「リストの内容が増えすぎているので検索がしたい」と言われた。本当は検索キーワードをサーバーに送り、SQLを発行し直して…、と作るのが普通な気がするけど、「う~む、その要望なら別にそこまでしなくても良いんだけどなぁ」と思ってブラウザの表示上だけで出来るように作ったものだ。Selectタグ内のOptionのスタイルを切り替えてるだけなので軽い。正規表現を使うのがポイントと言えばポイントだがJavaScriptのソースも簡単でちょっと残しておくといろんなとこに応用出来そうだと思ったので載せる。
 以下のソースコードでは簡単にOnChangeにしか登録してないがOnKeyUp、Onblurにも同様に登録すると上記のようなインクリメンタルサーチ的動作になるぞ。
<script language="javascript" type="text/javascript"> 
var TEST_OBJECT = {
   onSearchFieldChange : function(value){
      var selectBox = document.getElementById("my_select_list");
      var items = selectBox.children;
      if (value === "") {
         for(var i=items.length-1; i>=0; i--){
            items[i].style.display = "";
            items[i].selected = false;
         }
         return;
      }
 
      var reg = new RegExp(".*"+value+".*","i");
      for(var i=items.length-1; i>=0; i--){
         if ( items[i].textContent.match(reg) ){
            items[i].style.display = "";
         } else {
            items[i].style.display = "none";
         }
         items[i].selected = false;
      }
   }
}
</script> 
 
<input onchange="TEST_OBJECT.onSearchFieldChange(this.value);"  
       style="width: 140px;" /><br />
<select id="my_select_list" size="3" style="width: 140px;">
 <option value="a1">abcdefg</option>
 <option value="a2">hijklmn</option>
 <option value="a3">opqrstu</option>
</select> 
サンプルのようにonchangeだけだとエンターキーを押すかフォーカスを外すなどで変更が確定した時に処理される。このページのソースも参考に(しかし複数のイベントに登録してるのでちょこっと入力したら2回も3回も処理されていると思う。もう少し工夫すると良いかも)。
 基本的に上記ソースをコピペで動くがSelectタグのid="my_select_list"がページ内で被らないことが大事。idを変更したならJavaScriptのdocument.getElementById("my_select_list")のidも同じになるように変更すると良い。
 new RegExpの第2引数"i"は大文字小文字を区別しない検索になるような指定「ignoreCase」のことだ。

(記事内にJavaScriptを埋め込んで動作出来るのか試してみたら普通に動くようだ)
 さてIEではSelect内のOptionタグのStyleにdisplay:noneを付けても消えない。よってこのコードはIEは対応しない…。
 IEでリストから消すにはRemoveしないといけないが、Removeでは無くなって再度表示できなくなるので、その前にリスト内容のコピーを取っておく、などと対応すると複雑になる。
 「残念出来ない」と思ったら諦める前にユーザの要望をもう一度確認しよう。今回の場合、IEでも動作する以下のような対応もありうる。「ユーザの要望を聞いて最初に思い付いた対応」と「ユーザの要望」は違うので詰まったらユーザの要望まで戻るのだ。



はい。
正規表現なんか使わなくても「 if ( items[i].textContent.indexOf(value) !== -1 )」で同じ効果になると思います。すいませんw

0 件のコメント:

コメントを投稿