範囲選択はnoUiSliderできれいに
範囲指定に便利なスライダーをリッチにするJavaScriptライブラリ「noUiSlider」を紹介します。
通常、フォームでスライダーを使用する際「<input type=”range”>」を使用して設置します。inputタグによるフォーム部品は簡単に設置できる反面、ブラウザによって表示のされ方が異なったり、装飾に限度があります。
かといって一からすべて自身で作るのは合理的な選択とは言えません。
そこでおすすめなのが、今回紹介する「noUiSlider」です。
概要
noUiSliderはJavascriptによって制御された範囲選択のライブラリです。ライセンスはMITなので個人、商用など自由に利用可能です。
つまみ、範囲、メモリなどを指定することができます。
使い方
結構いろいろなことができるので、基本形から変化させるように紹介していきます。言葉のみ見るとパっとわからない例もあると思います。実際に使用を検討している場合はcodepenのモデルを動かしてみてください。
cssとjavascriptはcdnから読み込むかgithubからダウンロードしてください。
基本形
<div class="container"><div id="slider"></div></div>
const slider = document.getElementById('slider');noUiSlider.create(slider, {start: [20, 80], // 初期位置connect: true, // 選択点で囲まれている範囲を色付けrange: { // 最大値、最小値の設定'min': 0,'max': 100}});
HTML側では描画用のdiv要素を設置します。javascriptから選択しやすいようidで「slider」と振っています。
javascript側では特定の要素を選択とオプションを選択し、描画を行います。「noUiSlider」オブジェクトはjavascriptの読み込みでグローバルスコープとなっています。その中のcreate関数を使用することで、スライダーを作成できます。
スライダーは0-100の範囲で初期位置は20と80に設定しています。connectをtrueにすることでつまみとつまみをつなげることができます。
メモリを表示
noUiSlider.create(slider, {start: [20, 80], // 初期の範囲値connect: true, // 範囲を色付きのバーで結ぶrange: {'min': 0,'max': 100},tooltips: true, // ハンドル上にツールチップを表示pips: { // 特定の間隔で値のマーカーを追加mode: 'positions',values: [0, 25, 50, 75, 100],density: 4}});
tooltipsをtrueに設定しています。これでつまみ上にマウスを重ねると現在の値が表示されるようになります。
pipsはメモリを表示することができます。modeではpositionsを設定することで、スライダーの特定位置にマーカーを表示しています。valuesではマーカーを表示する位置をパーセントで指定しています。desnityは小さいメモリの感覚を指定することができます。(例では4なので、4%ずつメモリを設置しています。)
イベントの取得
const slider = document.getElementById('slider');const valueElement = document.getElementById('slider-value');const consoleBox = document.getElementById('console');noUiSlider.create(slider, {start: [50],range: {'min': 0,'max': 100}});slider.noUiSlider.on('slide', function (values, handle) {valueElement.innerHTML = values[handle];});slider.noUiSlider.on('change', function (values, handle) {consoleBox.insertAdjacentHTML( 'beforeEnd', `<p style="color: red;">値変更: ${values[handle]}</p>`);});slider.noUiSlider.on('start', function (values, handle) {consoleBox.insertAdjacentHTML( 'beforeEnd', `<p style="color: blue;">つまみ掴んだ</p>`);});slider.noUiSlider.on('end', function (values, handle) {consoleBox.insertAdjacentHTML( 'beforeEnd', `<p style="color: green;">つまみ離した</p>`);});
noUiSliderのイベントは要素.noUiSlider.onの形で取得できます。
上の例では「change」「start」「end」のイベントが発火した際に<div id=”console”></div>内に表示するよう設定しています。
- change・・・値が変わると発火します。つまみを動かしてもスライダ-ー上をクリックしても発火します。
- start・・・つまみを掴んだ際に発火します。
- end・・・つまみを話した際に発火します。
フォーマット
noUiSlider.create(slider, {start: [5000],range: {'min': 0,'max': 10000},format: {to: function (value) {return Math.round(value).toLocaleString(); // コンマ区切りの数値形式にフォーマット},from: function (value) {return Number(value.replace(/,/g, '')); // 数値に変換する際にコンマを削除}}});
数値の形式が小数点下二桁がデフォルトとなっています。少数を扱わない場合は小数点以下はいらないですし、4桁以上の場合は見やすくするためにコンマをあった方が良いです。上記ではそれを実現しています。
toは表示する際のフォーマット、fromは表示からnoUiSliderで処理する際のフォーマットという感じです。表示する際はコンマ区切りにし、noUiSliderで保持する値はコンマがない形にフォーマットしてます。
まとめ
デフォルトのrangeより快適に使用できることが確認できたのではないでしょうか。実際のフォームで使用する際はinput hiddenなどにスライダーイベントを関連付けて値を保存するとバックエンドでも処理しやすくなります。
また、スライダーの各パーツはCSSで変更可能です。(評価を入力させたい時は★に変えたりということが可能です。)