久しぶりにブックマークレット
困りごと
うちの会社には、スーパーなレガシーシステムがありまして、、、
HTMLで作られているWebシステムなのですが、<select>
がめっちゃ長いんですよ。選択肢が50とか100とかあります。資格の名前とか事業所の一覧とか、似たような名前が多くて地獄です。
画面で入力する身としては、たまったもんじゃありません。目で見て選択するなんて無理です。
ということで、レガシーシステムに息を吹き込むブックマークレットを作りました。
使うもの
- Javascript
- jQuery
レガシーシステムが相手なので、jQueryで楽させてもらいます。
コード
こんな感じになりました。コメント入れて60行くらい。
さすがにレガシーといえど、jQueryを使ってコード書きました。
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
コードの説明
説明するほどのコードじゃないですけど、一応。
$('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にスクリプトを投げ込んでください。
ブックマークレット(スクリプト)を実行
画面内にあるセレクトの上に、テキストボックスが生まれる!
フィルタ実行
テキストに「都」を入れると「東京都」と「京都府」で2つの選択肢だけになるので、選びやすい。3/48表記は左がマッチした選択肢数、右が選択肢の総数です。テキストボックスから消すと全部元通りです。
まとめ
程よく汎用的に作ったので、たいていのサイトの選択肢<select>をハックできるはずです。一番上の選択肢を上手に判定する方法が見つからなかったけど。
気に入ったら、ブラウザのブックマークバーに登録してみてください。
参考資料
国の一覧はここを一覧を使わせていただきました。5年前の国名らしいので2020年だと変わってるかもしれません。
https://qiita.com/tao_s/items/32b90a2751bfbdd585ea