会社で使ってるツールでselectの中身(dropdown)が大量に出てくるページがあって、
毎度探すのが辛いので調べました。
で「CHROMEに追加」すれば各ページ内のselectがフィルタできるようになります。
ただ、どのページでも使えるかどうかは怪しいですね。
単純にoptionを絞り込んでるのでselectedIndexで管理するようにjavascript組まれてたらNGだし、
動的に生成されたselectには適用できない動作している気がします。
あと、多くselectが配置されているページでの利用は少し辛いです。
なので試しに遊びで自作してみました。
自作するのに参考にしたページは下記です。
http://qiita.com/suin/items/5e1aa942e654bce442f7
ファイル構成
├icons
│├icon16.png
│├icon48.png
│└icon128.png
├manifest.json
└selectbox-filter.js
iconはいい感じに作ってください。
manifest.json
{
"name": "Select options filter",
"version": "0.0.1",
"manifest_version": 2,
"description": "selectをCtrl+Clickするとフィルタモードになります",
"icons": {
"16": "icons/icon16.png",
"48": "icons/icon48.png",
"128": "icons/icon128.png"
},
"content_scripts": [
{
"matches": [
"<all_urls>"
],
"js": [
"selectbox-filter.js"
]
}
],
"web_accessible_resources": [
"icons/icon16.png"
],
"permissions": [
"<all_urls>"
]
}
content_scriptsに書くとページ操作できるみたいです。
web_accessible_resourcesに記載すると、chrome.extension.getURL()でのURLが使える様子です。
selectbox-filter.js
(function() {
'use strict';
let input = document.createElement('input');
input.setAttribute('placeholder', 'enter filter keyword');
input.style.backgroundImage = 'url("' + chrome.extension.getURL('/icons/icon16.png') + '")';
input.style.backgroundRepeat = 'no-repeat';
input.style.backgroundPosition = 'right';
let select;
//documentのclickにイベント登録
document.addEventListener('click', function(e) {
if (e.ctrlKey && e.target.tagName.toLowerCase() === 'select') {//Ctrl+Click かつ selectがClickされた場合フィルタモード開始
select = e.target;
input.value = '';
select.parentElement.insertBefore(input, select);
input.focus();
}
});
input.addEventListener('keyup', function() {
let value = input.value;
let options = select.getElementsByTagName('option');
let match = value ? function(option) {
return option.textContent.indexOf(value) > -1;
} : function(option) {
return true;
};
let dispOpt = [];
for (var i = 0; i < options.length; i++) {
if (match(options[i])) {
options[i].style.display = '';//displayでフィルタ制御
dispOpt.push(i);
} else {
options[i].style.display = 'none';//displayでフィルタ制御
}
if (options[i].textContent === value) {//完全一致があったなら選択させる
select.selectedIndex = i;
}
}
if (dispOpt.length === 1) {//フィルタした結果が1件なら選択させる
select.selectedIndex = dispOpt[0];
}
});
})();
動作
selectをCtrl押しながらClickするとフィルタ用のinputが横に出てきて、入力すると、selectの中身が絞られます。
左から、通常→Ctrl+Clickしたあと→入力した後のselectの状態
やりたかったこと
- displayでフィルタするのでselectedIndexを汚さない(はず)
- 一つのselectに対してだけinputを表示するのでページが大きく崩れない。
- documentのクリックイベントで制御するので追加で配置されたselectでも動作する。
入手
作成したものをwebstoreに公開しました。
https://chrome.google.com/webstore/detail/select-box-filter/ohgdgoglcbcfofphmmnkkdbpffklhjgh
ソースはgithubにあげています。
https://github.com/ota-meshi/chromeextension_selectbox_filter