絞り込み検索機能の作り方
記載方法はES6です
実行ではES6のバージョンを落として実行しています。
*メモレベル
コード
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 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 |
export class FixdSelect { constructor(obj) { this.$item = $(obj.item); this.$inputItem = $(obj.inputItem);//チェックボックス this.$radioBtn = $(obj.radioBtn);//ラジオボタン this.$clearBtn = $(obj.clearBtn);//クリアボタン this.checkList = []; this.name = ''; this.TIMEOUT = 250; this.VISIBLE_CLASS = '-visible';//表示 this.DATA_LABEL = 'label'; this.DATA_ITEM = 'item'; this.searchType = $(obj.searchType);//orもしくわandを選択 }; addActive() { this.$item.removeClass(this.VISIBLE_CLASS); // 一旦消す setTimeout(() => { let i = 0; let result = []; let itemLength = this.$item.length; let visibleItems = []; let item; let resultArrayCheck; let searchType = this.searchType; while(itemLength > i){ let check = true; const $_me = this.$item.eq(i); result = $_me.data(this.DATA_ITEM); $.each(this.checkList, function(index, value) { resultArrayCheck = $.inArray(value,result); if(searchType == "or"){ //or回路 check = false; if(resultArrayCheck == -1){ //該当なし }else{ //該当あり check = true; return false; }; }else{ // and回路 if(resultArrayCheck == -1){ //該当なし check = false; return false; }else{ //該当あり }; };//and/orの終了 }); // DOMアクセス if (check) { $_me.css({ display: "block" }); visibleItems.push($_me); }else{ $_me.css({ display: "none" }); }; i++; };//whleの終了 //cssとの非同期処理との兼ね合いで時間をとってからクラスをつける setTimeout(() => { visibleItems.forEach($elm => { $elm.addClass(this.VISIBLE_CLASS); }); }, 200); }, this.TIMEOUT); }; arrayCheck(){ //配列に重複コンテンツが存在するかをチェックして存在すれば消し、存在しなければ追加 let listResult = true; listResult = $.inArray(this.name,this.checkList); if(listResult == -1){ //該当なし this.checkList.push(this.name); }else{ //該当あり this.checkList = this.checkList.filter(n => n !== this.name);//該当するitemを省いて配列を生成 }; } init() { this.$item.addClass(this.VISIBLE_CLASS); //チェックボックスのイベント this.$inputItem.change((e) => { this.name = $(e.currentTarget).data(this.DATA_LABEL);//チェックされたチェックボックス全てのdata-nameの値を取得 this.arrayCheck();//チェック配列の操作 this.addActive();//絞り込み処理 });//チェックボックスの終了 //ラジオボタンのイベント this.$radioBtn.change((e) => { let name = $(e.currentTarget).attr('name'); let $names = $('input[name="'+name+'"]'); let nameLength = $names.length; let i = 0; while(nameLength > i){ let $_nameMe = $names.eq(i).data(this.DATA_LABEL); this.checkList = this.checkList.filter(n => n !== $_nameMe); i++; }; this.checkList.push($(e.currentTarget).data(this.DATA_LABEL)); this.addActive();//絞り込み処理 });//ラジオボタンイベントの終了 //選択をクリアボタンが押された場合 this.$clearBtn.click(() => { $('input[type="checkbox"]').prop('checked', false);//全てのチェックを外す $('.js-search-radio').prop('checked', false);//全てのチェックを外す this.checkList = [];//配列をリセット this.addActive();//絞り込み処理 }); };//initの終了 }; |
使い方
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 |
/*--使い方---------------------------------------- 【1:ファイルの読み込み】 import { FixdSelect } from './ui/select'; ./ui/select.jsファイルのSelectを呼び出す 【2:インスタンス化】 const fixdSelect = new FixdSelect({ item: => 絞り込み対象のアイテム clearBtn: => 絞り込みをリセットするボタン inputItem: => 絞り込みボタン(チェックボックス) radioBtn: => 絞り込みボタン(ラジオボタン) searchType: => 絞り込みタイプ }); ***例*** item:'.js-item__content', clearBtn:'.js-clear', inputItem:'.js-search-input', radioBtn:'.js-search-radio', searchType:'and' 【3:実行】 fixdSelect.init(); htmlの注意 絞り込みタイプのdata-labelはtype-orもしくはtype-andとすること -------------------------------------------------*/ |
今回の実装のポイント
配列に任意の値が存在するか調べる方法
- array.indexOf(value)
- $.inArray(value,array)
- ループと条件分岐の組み合わせ
array.indexOf(value)
1 |
array.indexOf(value) |
valueに存在するか確かめたい値をいれることでarrayにその値が存在するかを調べることができる。
値が存在しない場合は-1返す
値が存在する場合は存在する場所のインデックス番号を返す
例
1 2 3 4 5 6 7 8 9 10 11 |
let array = ['color',50,'padding'], value1 = 'color', value2 = 50, value3 = 'font'; result1 = array.indexOf(value1); result2 = array.indexOf(value2); result3 = array.indexOf(value3); console.log(result1);//0 console.log(result2);//1 console.log(result3);//-1 |
*****注意点*****
配列をオブジェクトにするとエラーとなる
1 |
let array = {'color',50,'padding'};//エラー |
$.inArray(value,array)
1 |
$.inArray(value,array) |
valueに存在するか確かめたい値をいれることでarrayにその値が存在するかを調べることができる。
値が存在しない場合は-1返す
値が存在する場合は存在する場所のインデックス番号を返す
例
1 2 3 4 5 6 7 8 9 10 11 |
let array = ['color','50','padding'], value1 = 'color', value2 = '50', value3 = 'font'; result1 = $.inArray(value1,array); result2 = $.inArray(value2,array); result3 = $.inArray(value3,array); console.log(result1);//0 console.log(result2);//1 console.log(result3);//-1 |
*****注意点*****
配列をオブジェクトにするとエラーとなる
ループと条件分岐の組み合わせ
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 |
window.onload = function () { var array = ['color','50','padding'], value1 = 'color'; value2 = '50'; value3 = 'font'; arrayCheck(array,value1); arrayCheck(array,value2); arrayCheck(array,value3); }; function arrayCheck(array,value) { var check = false; for( index in array ) { if(array[index] == value){ check = true; }; }; if(check){ return console.log("存在する"); }else{ return console.log("存在しない"); } } |
*****注意点*****
配列が0のときには作動しないので0の時も動いて欲しい場合は以下のように記載する。
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 |
window.onload = function () { var array = ['color','50','padding'], array2 = [], value1 = 'color'; arrayCheck(array,value1); arrayCheck(array2,value1); }; function arrayCheck(array,value) { var check = false; if(array.length){ for( index in array ) { if(array[index] == value){ check = true; }; }; if(check){ return console.log("存在する"); }else{ return console.log("存在しない"); } }else{ return console.log("配列が存在しない場合の処理"); } }; |
応用すれば個数を数えることもできる
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 |
window.onload = function () { var array = ['color','color','padding'], array2 = [], value1 = 'color'; arrayCheck(array,value1); arrayCheck(array2,value1); }; function arrayCheck(array,value) { var check = false, i = 0; if(array.length){ for( index in array ) { if(array[index] == value){ check = true; i++; }; }; if(check){ return console.log(i+"個存在する"); }else{ return console.log("存在しない"); } }else{ return console.log("配列が存在しない場合の処理"); } } |
配列から任意の値をとりのぞきたい時
jqueryを使用するなら以下の方法で任意の値を取り除いて配列を作り直した方が早い。
1 |
list = list.filter(n => n !== value); |
listからvalueの値を除き、listに配列を作り直す。
.changeでチェックボックスの変化を監視し、変化があったボックスの値を参照したい時
1 2 3 |
$('チェックボックス全体を取得').change((e) => { $(e.currentTarget) }); |
チェックボックス全てに付与したクラスやinput:checkboxを使ってチェクボックスの変化を監視し、変化があればe.currentTargetにそのオブジェクトが入る。
cssとの非同期処理の関係でsetTimeoutを使う
絞り込みのアニメーションを以下のような挙動にしたい。
流れは
要素を下方向にスライドさせながら徐々に透明化させる
↓
要素の存在自体を消す
↓
絞り込んだ要素を存在させて高さは保持するようにするが見た目には見えない+選択不可にする
↓
要素が下から上方向にスライドしながら徐々に可視化させる
scss
1 2 3 4 5 6 7 8 9 10 11 |
.p-hoge { visibility: hidden; opacity: 0; transform: translate(0px, 20px); transition: all 0.25s; &.-visible { visibility: visible; opacity: 1; transform: translate(0, 0); } } |
jsから表示させたい要素に-visibleクラスをつけることで実現させている。
-visibleクラスを外せば元に戻るという仕組み。
だが、これでは表示したくない要素の存在を消すことができないので、jsからcssを操作して表示したくない要素にdisplay:none;をつけている。(表示したい要素にはblockをつける)
わざわざjsからつける理由はsetTimeoutを使ってタイミングをずらしたいから。
jsの処理とcssの処理は同期していないのでそれぞれが独立して動く。なので、もし、タイミングをずらさずに処理をしてしまうと、css上でのdisplay:none;の処理が完了する前に-visible処理が始まってしまう。
-visibleにはアニメーションがついてるが、displayの処理が完了すると、アニメーションが強制終了してしまうらしい。
コメント