ECサイトなどで価格の範囲を決めて商品を検索する機能があるとき、音量の調整や明るさの調整をするUIのようなデザインで作成されていることがありますね。
このような入力欄を「レンジスライダー」といいます。
レンジスライダーの実装には、input要素のtype属性「range」を利用することができます。
しかしそれだとハンドルが1つしかないため、「商品の最小価格・最大価格を決めて検索する」といった仕様には対応できません。
そこで、ハンドルが2つあるレンジスライダーでも簡単に実装できる、jQueryプラグイン「noUiSlider」をご紹介したいと思います。
本記事では、最小値・最大値をハンドルでもテキスト入力でも指定可能なレンジスライダーの作り方を解説します。
jQueryプラグイン「noUiSlider」のデモ
目次
jQueryプラグイン「noUiSlider」とは
noUiSliderは、jQueryをベースとしUI系の機能をまとめた「jQuery UI」から、レンジスライダー機能だけを取り出したようなスライダ―プラグインです。
範囲指定を自由かつ簡単に指定できるスライダーを実装出来ます。
特徴として、以下の2つが挙げられます。
多機能なのに軽い
レスポンシブデザイン対応
レンジスライダーを実装するだけなのに、入れただけで重くなってしまうのはいやですよね。
ですが、noUiSliderは多くの機能を持ちながら軽いので安心して使えます。
またレスポンシブも対応されています。
スマホ用に特別な記述をしなくても、スマホでもきちんと調整されているので手間が省けます。
この記事で実装するレンジスライダーのデモ
今回のカスタマイズ内容は、以下になります。
最小値・最大値をテキストで表示するようにする
入力した最小値・最大値をスライダーに反映させる
最小値・最大値をテキストではなく、インプット要素にしているのは2つ目のカスタマイズ内容に必要になってくるからです。
テキストでは数値を入力することが出来ないので、インプット要素で作成します。
今回の記事は、こちらの記事をベースにさせて頂き汎用的に使えるよう変更を加えました。
noUiSliderで最小値以下、最大値以上の場合にテキストフィールドの値を空にする
HTMLファイルの準備
今回は、ハンドルで選択した最小値・最大値の数値をinputに出力も出来るレンジスライダーを作成します。
HTMLの記述は以下になります。
レンジスライダー部分になる枠と数値を入力するinputを作成します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | <html> <head> <meta charset="utf-8" name="viewport" content="width=device-width, initial-scale=1"> <title>noUiSlider</title> <link rel="stylesheet" type="text/css" href="css/nouislider.min.css"> <link href="css/style.css" rel="stylesheet" media="all"> </head> <body> // レンジスライダー部分 <div class="noUiSlider-wrap standard"> <div class="inner-block"> <h1>デモスライダー</h1> <div class="text-wrap"> <input type="number" name="min" class="min-box" placeholder="最小値" value=""> <span>~</span> <input type="number" name="max" class="max-box" placeholder="最大値" value="" max="1000"> </div> <div class="range-slider"></div> </div> </div> <script src="js/jquery-3.6.0.min.js"></script> <script src="js/nouislider.min.js"></script> <script src="js/wNumb.js"></script> <script src="js/common.js"></script> </body> </html> |
HTMLを作った後
HTMLを作った直後はまだインプット要素しか表示されません。
jQueryファイルの準備
まずは公式サイトから、noUiSliderをダウンロードします。
「Download noUiSlider」をクリックするとダウンロードの説明ページに飛びます。
ページ下部にある「Download noUiSlider from Github」を押して頂いて、ダウンロードページに行くのでソースコードをダウンロードしてください。
jQueryプラグイン「noUiSlider」
ダウンロードが完了したら、以下のファイルをそれぞれCSSフォルダ・JSフォルダに入れ、読み込みます。
・distファイル > nouislider.min.css
・distファイル > nouislider.min.js
・documentationファイル > assetsファイル > wNumb.js
それぞれ、style.css・common.jsの前に記述してください。
1 2 3 4 5 6 | <link rel="stylesheet" type="text/css" href="css/nouislider.min.css"> <script src="js/nouislider.min.js"></script> <script src="js/wNumb.js"></script> |
noUiSlider実装の準備ができたら、実際にレンジスライダーを実装する記述を書いていきます。
内容は以下になります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | var $slider = $('.range-slider').get(0); //スライダー作成場所を指定 var $min = $('.min-box'); //最小値を入力するボックスを指定 var $max = $('.max-box'); //最大値を入力するボックスを指定 var minVal = 0; //スライダーの最小値 var maxVal = 1000; //スライダーの最大値 var gap = 100; // ハンドルの動きを100刻みで動かす //noUiSliderをセットする noUiSlider.create($slider, { start: [ minVal, maxVal ], // ハンドルの初期位置を最小値・最大値にする connect: true, step: gap, // ハンドルが一度で動く数値を指定(今回はgapを指定しているので100毎動く) range: { 'min': minVal, // スライダーの最小値を指定(minValに入っている、0が最大値) 'max': maxVal // スライダーの最大値を指定(maxValに入っている、1,000が最小値) }, pips: { // pipsを指定するとスライダーに目盛りが付く mode: 'steps', // 今回はstep毎に大きな目盛り付くので、stepに指定したgapの数値毎大きな目盛りが付く density: gap // 今回細かい目盛りは不要なので、gapを指定して100毎の目盛りにする } }); //noUiSliderイベント $slider.noUiSlider.on('update', function( values, handle ) { //現在の最小値・最大値を取得 var value = Math.floor(values[handle]); if ( handle ) { $max.get(0).value = value; //現在の最大値 } else { $min.get(0).value = value; //現在の最小値 } }); //最小値をinputにセット $min.get(0).on('change', function(){ $slider.noUiSlider.set([this.value, null]); }); //最大値をinputにセット $max.get(0).on('change', function(){ $slider.noUiSlider.set([null, this.value]); }); |
noUiSliderのjsを読み込んだ後
jQueryをあてたことで、レンジスライダーが表示されます。
デフォルトでも十分に使えるCSSが当たっています。
変数の宣言
それでは、順番にソースの内容をご紹介していきます。
まず変数を宣言します。
1 2 3 4 5 6 7 8 | var $slider = $('.range-slider').get(0); //スライダー作成場所を指定 var $min = $('.min-box'); //最小値を入力するボックスを指定 var $max = $('.max-box'); //最大値を入力するボックスを指定 var minVal = 0; //スライダーの最小値 var maxVal = 1000; //スライダーの最大値 var gap = 100; // ハンドルの動きを100刻みで動かす |
1 2 3 | var $slider = $('.range-slider').get(0); //スライダー作成場所を指定 |
スライダ―部分にするボックスを宣言します。
これが無いとレンジスライダーが実装出来ないので、必ず宣言します。
1 2 3 4 | var $min = $('.min-box'); //最小値を入力するボックスを指定 var $max = $('.max-box'); //最大値を入力するボックスを指定 |
最小値と最大値のテキストフィールドを宣言します。
レンジスライダーで選択した数値を入れ込むのに必要になります。
1 2 3 4 5 | var minVal = 0; //スライダーの最小値 var maxVal = 1000; //スライダーの最大値 var gap = 100; // ハンドルの動きを100刻みで動かす |
レンジスライダーの最小値と最大値を指定します。
今回の場合は、0~1,000の間のスライダーを作成するので、最小値に0、最大値に1,000を指定します。
変数gapは、スライダーの数値を100毎に選択させるために必要です。今回は100、200、300と選択するようにします。
端数(101など)を自由に決めたいときは、こちらは不要なので削除してください。
noUiSliderをセット
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | //noUiSliderをセットする noUiSlider.create($slider, { start: [ minVal, maxVal ], // ハンドルの初期位置を最小値・最大値にする connect: true, step: gap, // ハンドルが一度で動く数値を指定(今回はgapを指定しているので100毎動く) range: { 'min': minVal, // スライダーの最小値を指定(minValに入っている、0が最大値) 'max': maxVal // スライダーの最大値を指定(maxValに入っている、1,000が最小値) }, pips: { // pipsを指定するとスライダーに目盛りが付く mode: 'steps', // 今回はstep毎に大きな目盛り付くので、stepに指定したgapの数値毎大きな目盛りが付く density: gap // 今回細かい目盛りは不要なので、gapを指定して100毎の目盛りにする } }); |
それぞれの記述の意味は以下になります。
start | ハンドルの初期位置を指定する。 ハンドルを複数設定する場合は、[100,500]などと括弧で囲む必要がある。 |
---|---|
connect | ハンドル間の色の付け方を変更する。初期値はfales。 |
step | ハンドルが一度で動く数を指定する。 |
range | スライダーの最小値・最大値を指定する。 |
pips | スライダーに目盛りを付けるための設定をする。 |
mode | 指定した内容で大きな目盛りの付き方が変わる。 |
density | rangeで指定した範囲の何%ごとに小さな目盛りを振るか指定(デフォルトは1)。 |
今回、modeにはstepsを指定しましたが他にも以下のような種類があります。
steps | stepで指定した数ごとに目盛りを付ける。 |
---|---|
positions | valuesで指定した%ごとに目盛りを付ける。 例)values: [0, 25, 50, 75, 100] |
count | valuesで指定した数を元に均等に目盛りを付ける。 例)values: 6 |
values | valuesで指定した固定数で目盛りを付ける。 例)values: [50, 552, 4651, 4952, 5000, 7080, 9000] |
注意点として、positionsとcountは明確な固定数値で目盛りを付けないので、スライダーに指定している最小値・最大値によっては目盛りに端数が生まれることがあります。
なので、この2つには「stepped: true」を記載すべきです。
stepped | trueと付けることで端数が生まれた数値をそれに近い整数に調整してくれる 例)1813 ⇒ 2000 |
---|
noUiSliderのイベントをセット
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | //noUiSliderイベント $slider.noUiSlider.on('update', function( values, handle ) { //現在の最小値・最大値を取得 var value = Math.floor(values[handle]); if ( handle ) { $max.get(0).value = value; //現在の最大値 } else { $min.get(0).value = value; //現在の最小値 } }); |
レンジスライダーで指定した数値を、テキストボックスに入力する記述になります。
最大値のハンドルが動いた時は、$maxのvalueに数値を入れ込み、
最小値のハンドルが動いた時は、$minのvalueに数値を入れ込みます。
CSSで調整した後
CSSで以下のデザイン調整を行いました。
ハンドルを丸い形に変更・2本の線を非表示
最小値・最大値間の色をグラデーションに変更
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | .noUiSlider-wrap .inner-block { padding: 50px; } @media screen and (max-width:761px) { .noUiSlider-wrap .inner-block { padding: 26px; } } .noUiSlider-wrap .text-wrap { margin: 30px auto; } .noUi-horizontal .noUi-handle { width: 30px; height: 30px; border-radius: 100px; top: -8px; } .noUi-horizontal .noUi-handle::before, .noUi-horizontal .noUi-handle::after { content: none; } .noUi-connect { background: linear-gradient(90deg, rgba(34,193,195,1) 0%, rgba(253,187,45,1) 100%); } |
こちらで完成になります。
jQueryプラグイン「noUiSlider」のデモ
応用:ハンドルを4つにし、最小値・最大値の範囲をそれぞれ指定する
最小値・最大値を指定できるレンジスライダーを紹介しました。
左が最小値、右が最大値といったスライダーを作成致しましたが、少しアレンジするだけで違うスライダーを作ることが可能です。
次は応用編として、ハンドルを4に増やし、最小値の範囲と最大値の範囲をそれぞれ指定できるスライダーをご紹介したいと思います。
jQueryプラグイン「noUiSlider」のデモ
今回調整した記述
全体のソースはこちらです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | <html> <head> <meta charset="utf-8" name="viewport" content="width=device-width, initial-scale=1"> <title>noUiSlider</title> <link rel="stylesheet" type="text/css" href="css/nouislider.min.css"> <link href="css/style.css" rel="stylesheet" media="all"> </head> <body> <div class="noUiSlider-wrap inversion"> <div class="inner-block"> <h1>最小値・最大値の範囲をそれぞれ指定するデモスライダー</h1> <div class="text-wrap"> <input type="number" name="min" id="min-box" class="min-box" placeholder="最小値01" value=""> <span>~</span> <input type="number" name="max" id="max-box" class="max-box" placeholder="最大値01" value=""> </div> <div class="text-wrap"> <input type="number" name="min02" id="min-box02" class="min-box02" placeholder="最小値02" value=""> <span>~</span> <input type="number" name="max02" id="max-box02" class="max-box02" placeholder="最大値02" value=""> </div> <div class="range-slider inversion"></div> </div> </div> <script src="js/jquery-3.6.0.min.js"></script> <script src="js/nouislider.min.js"></script> <script src="js/wNumb.js"></script> <script src="js/common.js"></script> </body> </html> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | (function ($) { 'use strict'; var $slider = $('.range-slider').get(0); //スライダー作成場所を指定 var $min = $('.min-box'); //最小値を入力するボックスを指定 var $max = $('.max-box'); //最大値を入力するボックスを指定 var $min02 = $('.min-box02'); //最小値を入力するボックスを指定02 var $max02 = $('.max-box02'); //最大値を入力するボックスを指定 var minVal = 0; //スライダーの最小値 var maxVal = 1000; //スライダーの最大値 var gap = 100; // ハンドルの動きを100刻みで動かす //noUiSliderをセットする noUiSlider.create($slider, { start: [ minVal, 400, 600, maxVal ], // ハンドルの初期位置を最小値・最大値にする connect: [false, true, false, true, false], step: gap, // ハンドルが一度で動く数値を指定(今回はgapを指定しているので100毎動く) range: { 'min': minVal, // スライダーの最小値を指定(minValに入っている、0が最大値) 'max': maxVal // スライダーの最大値を指定(maxValに入っている、1,000が最小値) }, pips: { // pipsを指定するとスライダーに目盛りが付く mode: 'steps', // 今回はstep毎に大きな目盛り付くので、stepに指定したgapの数値毎大きな目盛りが付く density: gap // 今回細かい目盛りは不要なので、gapを指定して100毎の目盛りにする } }); // noUiSliderイベント $slider.noUiSlider.on("update", function (values, handle) { var slider_values = $slider.noUiSlider.get(); $min.get(0).value = parseInt(slider_values[0]); $max.get(0).value = parseInt(slider_values[1]); $min02.get(0).value = parseInt(slider_values[2]); $max02.get(0).value = parseInt(slider_values[3]); }); // 入力した最小値と同じ数値にスライダーを動かす_最小値の範囲 $min.on('change', function(){ $slider.noUiSlider.set([this.value, null, null, null]); }); $max.on('change', function(){ $slider.noUiSlider.set([null, this.value, null, null]); }); // 入力した最大値と同じ数値にスライダーを動かす_最大値の範囲 $min02.on('change', function(){ $slider.noUiSlider.set([null, null, this.value, null]); }); $max02.on('change', function(){ $slider.noUiSlider.set([null, null, null, this.value]); }); })(jQuery); |
HTMLとjsそれぞれ、調整した部分は以下になります。
HTMLファイル
1 2 3 4 5 6 7 8 9 10 11 12 | <div class="text-wrap"> <input type="number" name="min" id="min-box" class="min-box" placeholder="最小値01" value=""> <span>~</span> <input type="number" name="max" id="max-box" class="max-box" placeholder="最大値01" value=""> </div> <div class="text-wrap"> <input type="number" name="min02" id="min-box02" class="min-box02" placeholder="最小値02" value=""> <span>~</span> <input type="number" name="max02" id="max-box02" class="max-box02" placeholder="最大値02" value=""> </div> |
最小値の範囲用と最大値の範囲用のインプット要素を2つ用意します。
jsファイル
まず、増やしたインプット要素の変数を宣言し、「ハンドルの数」と「ハンドル間の色の付け方」を変更します。
1 2 3 4 5 6 7 8 9 | // 増やしたインプット要素の変数を宣言 var $min02 = $('.min-box02'); //最小値を入力するボックスを指定02 var $max02 = $('.max-box02'); // 「ハンドルの数」、「ハンドル間の色の付け方」の変更 start: [ minVal, 400, 600, maxVal ], // ハンドルの数 connect: [false, true, false, true, false], ハンドル間の色の付け方の指定 |
ハンドルをスライダーの最小値・400・600・最大値の位置に追加します。
最小値・400が最小値の範囲になり、600・最大値が最大値の範囲になります。
色はそれぞれの間につくように設定致しました。
次に、実際にスライダーの数値をそれぞれのインプット要素に追加する記述になります。
1 2 3 4 5 6 7 8 9 10 | // noUiSliderイベント $slider.noUiSlider.on("update", function (values, handle) { var slider_values = $slider.noUiSlider.get(); $min.get(0).value = parseInt(slider_values[0]); $max.get(0).value = parseInt(slider_values[1]); $min02.get(0).value = parseInt(slider_values[2]); $max02.get(0).value = parseInt(slider_values[3]); }); |
まずそれぞれのインプット要素の変数を宣言します。
その次に「slider_values」でハンドルのインデックス番号を選択できるようにします。
先程宣言したそれぞれのインプット要素のvalueに入力されるように「.value」を指定し、変数slider_valuesの該当するインデックス番号を指定します。
インデックス番号は0から始まるので、最小値の範囲の最小値がslider_values[0]になり、最小値の範囲の最大値にslider_values[1]が入ります。
最大値の範囲にも同じように設定すれば完了です。
また、入力した数値でスライダーを動かす記述も増やします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | // 入力した最小値と同じ数値にスライダーを動かす_最小値の範囲 $min.on('change', function(){ $slider.noUiSlider.set([this.value, null, null, null]); }); $max.on('change', function(){ $slider.noUiSlider.set([null, this.value, null, null]); }); // 入力した最大値と同じ数値にスライダーを動かす_最大値の範囲 $min02.on('change', function(){ $slider.noUiSlider.set([null, null, this.value, null]); }); $max02.on('change', function(){ $slider.noUiSlider.set([null, null, null, this.value]); }); |
「.set([null, null, null, this.value])」の位置が重要になります。
今回は4つのハンドルがあるので、setの中身の4つ必要になってきます。
「this.value」と指定した位置によって、インプット要素と連携させるハンドルが変わります。
最小値の範囲の最小値なら並びは「this.value, null, null, null」になります。
最大値の範囲の最大値なら並びは「null, null, null, this.value」になります。
これだけで4つのハンドルのスライダーの完成です。
まとめ
如何でしたでしょうか?
インプット要素に標準であるレンジスライダーだけではなく、noUiSliderを使えば難しそうに見えるレンジスライダーも簡単に実装することが可能になります。
今回ご紹介したのは、ハンドルが2つある最小値・最大値をテキスト入力でも指定可能なスライダーでしたが他にも様々なアレンジも可能なので、一つでも知っておくとデザインの幅が広がると思います。
noUiSliderのサイトでも様々なアレンジ方法をご紹介しているのでぜひ参考に見てみてください。
jQueryプラグイン「noUiSlider」
少しでも、見て頂いた方の助けになれば幸いです。
参考サイト
jQueryプラグイン「noUiSlider」
noUiSliderで最小値以下、最大値以上の場合にテキストフィールドの値を空にする