4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

レガシーなウェブシステムのSELECTタグを使いやすくするJavascript(ブックマークレット)

Last updated at Posted at 2020-06-19

久しぶりにブックマークレット

困りごと

うちの会社には、スーパーなレガシーシステムがありまして、、、
HTMLで作られているWebシステムなのですが、<select>がめっちゃ長いんですよ。選択肢が50とか100とかあります。資格の名前とか事業所の一覧とか、似たような名前が多くて地獄です。

画面で入力する身としては、たまったもんじゃありません。目で見て選択するなんて無理です。

ということで、レガシーシステムに息を吹き込むブックマークレットを作りました。

使うもの

  • Javascript
  • jQuery

レガシーシステムが相手なので、jQueryで楽させてもらいます。

コード

こんな感じになりました。コメント入れて60行くらい。
さすがにレガシーといえど、jQueryを使ってコード書きました。

select-filter.js
void ((function (f) {
  if (window.jQuery && jQuery().jquery > '2.0') {
    console.log('use jquery');
    f(jQuery);
  } else {
    console.log('load jquery');
    var script = document.createElement('script');
    script.src = '//code.jquery.com/jquery-3.5.1.slim.min.js';
    script.onload = function () {
      var $ = jQuery.noConflict(true);
      f($);
    };
    document.body.appendChild(script);
  }
})(
  function ($, undefined) {
    $('select').each(function (i, select) {
      //selectにidが無ければ、nameから作り出す
      if (!select.id) {
        select.id = select.name + '_' + i;
      }

      let options = $(select).children('option').length;
      let text = `<input type="text" data-selectid="${select.id}" class="__ft">`;
      let badge = `<span id="${select.id}_hit">${options}</span>/<span>${options}</span>`;

      //textboxを突っ込む
      $(select).before(`${text}  ${badge} <br>`);
    });

    //追加したテキストボックス全てに適用するイベントハンドラ
    $('input.__ft').on('input', function (ev) {

      let selector = '#' + $(this).data('selectid');
      let selectid = $(selector).attr('id');
      console.log(selector);

      let txt = this.value;
      console.log(txt);

      //フィルタした瞬間に選択肢を元に戻すならコメントはずす
      // $(selector).prop("selectedIndex", 0);

      let hit = 0;
      $(selector).children('option').each(function (i, e) {
        if (isDefaultOption(e) || matchOption(e, txt)) {
          $(e).show();
          hit++;
        } else {
          $(e).hide();
        }
      });
      $(`span#${selectid}_hit`).text(hit);
    });

    //デフォルトオプションの判定(システムに合わせて適当に書き換える必要があるかも)
    function isDefaultOption(element) {
      return $(element).val() == '' || $(element).hasClass('default');
    }
    //表示する条件(半角全角の調整など必要なことをやるべし)
    function matchOption(element, input) {
      return $(element).text().indexOf(input) != -1;
    }
  }
))

コードはここにも置いてあります。
https://github.com/kanaxx/kanaxx.github.io/tree/master/bookmarklet/select-filter

コードの説明

:sunflower: 説明するほどのコードじゃないですけど、一応。

$('select')なので、画面にある全ての<select>が対象です。

<select>にidが振られていないようなレガシーシステムの場合のことも考えて、nameの値を元に<select>にidを追加しています。

テキストボックスの真下にある<select>のidをテキストボックスのdata-selectidとして仕込むことで関連を持たせ、class__ftクラスを割り当てる

__ftクラス全体にinputイベントハンドラを登録する

イベントハンドラでselectからoptionを探して、部分一致したものだけshow()する

実行

選択肢が多いページが必要だったので、自分で作りました。
https://kanaxx.github.io/bookmarklet/select-filter/index.html

F12でDevToolを開いて、Consoleにスクリプトを投げ込んでください。

image.png

初期表示はセレクトがあるだけ
image.png

長くてうんざり
image.png

ブックマークレット(スクリプト)を実行
画面内にあるセレクトの上に、テキストボックスが生まれる!
image.png

フィルタ実行
テキストに「都」を入れると「東京都」と「京都府」で2つの選択肢だけになるので、選びやすい。3/48表記は左がマッチした選択肢数、右が選択肢の総数です。テキストボックスから消すと全部元通りです。
image.png

まとめ

程よく汎用的に作ったので、たいていのサイトの選択肢<select>をハックできるはずです。一番上の選択肢を上手に判定する方法が見つからなかったけど。
気に入ったら、ブラウザのブックマークバーに登録してみてください。

参考資料

国の一覧はここを一覧を使わせていただきました。5年前の国名らしいので2020年だと変わってるかもしれません。
https://qiita.com/tao_s/items/32b90a2751bfbdd585ea

4
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?