javascriptとcssでつくる複合検索

javascriptとcssでつくる複合検索

javascript と css で複合検索機能をつくりました。

デモでは、色と形という2種類の選択肢を用意。
色・形の中からふたつ以上選択した場合はor検索、掛け合わせの場合はand検索となるようにしました。

デモ

選択する方の選択肢と、選択される側の要素にクラスを設定しておき、同じクラスかどうかを判別し、ソートを実現しています。

ソースコードと解説

html

<dl id="color">
	<dt>色を選択</dt>
	<dd><input type="checkbox" class="orange"> オレンジ</dd>
	<dd><input type="checkbox" class="pink"> ピンク</dd>
	<dd><input type="checkbox" class="blue"> ブルー</dd>
	<dd><input type="checkbox" class="green"> グリーン</dd>
</dl>
<dl id="shape">
	<dt>形を選択</dt>
	<dd><input type="checkbox" class="circle"> 丸</dd>
	<dd><input type="checkbox" class="rect"> 四角</dd>
</dl>
<ul id="contents">
	<li class="orange circle"></li>
	<li class="green rect"></li>
	<li class="orange rect"></li>
	<li class="green circle"></li>
	<li class="pink circle"></li>
	<li class="blue rect"></li>
	<li class="pink rect"></li>
	<li class="blue circle"></li>
	<li class="orange circle"></li>
	<li class="green rect"></li>
	<li class="orange rect"></li>
	<li class="green circle"></li>
	<li class="pink circle"></li>
	<li class="blue rect"></li>
	<li class="pink rect"></li>
	<li class="blue circle"></li>
	<li class="orange circle"></li>
	<li class="green rect"></li>
	<li class="orange rect"></li>
	<li class="green circle"></li>
	<li class="pink circle"></li>
	<li class="blue rect"></li>
	<li class="pink rect"></li>
	<li class="blue circle"></li>
	<li class="orange circle"></li>
	<li class="green rect"></li>
	<li class="orange rect"></li>
	<li class="green circle"></li>
	<li class="pink circle"></li>
	<li class="blue rect"></li>
	<li class="pink rect"></li>
	<li class="blue circle"></li>
</ul>

色と形の選択肢を input タグで用意。
それぞれクラス名をつけておきます。
選択される側の要素にも、該当するクラス名をつけておきます。

css

dl dt {
	font-weight: bold;
}
dl dd {
	display: inline-block;
}

li {
	list-style: none;
	display: inline-block;
	width: 150px;
	height: 150px;
}
.orange { background-color: orange; }
.pink { background-color: pink; }
.green { background-color: greenyellow; }
.blue { background-color: skyblue; }
.circle { border-radius: 50%;}

.hidden {
	display: none;
}

.hidden クラスを用意。
選択されなかったものに、このクラスを付与することで非表示にし、ソートを実現させています。

javascript

var contents = document.querySelectorAll('#contents li'); // 要素の取得
var color = document.querySelectorAll('#color input'); // 色選択のボタンを取得
var shape = document.querySelectorAll('#shape input'); // 形選択のボタンを取得
var colorList = []; // 選択された色のクラスを入れるための配列
var shapeList = []; // 選択された形のクラスを入れるための配列

// ソートの関数
var andOrSort = function () {
	
	// 配列colorListを一旦空にし、
	colorList = [];
	// チェックがついている色のクラスを入れる
	for (var j = 0; j < color.length; j++) {
		if (color[j].checked === true) {
			colorList.push(color[j].className);
		}
	}
	
	// 配列shapeListを一旦空にし、
	shapeList = [];
	// チェックがついている形のクラスを入れる
	for (var j = 0; j < shape.length; j++) {
		if (shape[j].checked === true) {
			shapeList.push(shape[j].className);
		}
	}

	// 色・形どちらにもチェックが付いていた場合
	if (colorList.length != 0 && shapeList.length != 0) {
		
		// 一旦全部を非表示にし、
		for (var i = 0; i < contents.length; i++) {
			contents[i].classList.add('hidden'); // hiddenクラスを付与することで非表示に
		}
		
		// 選択された色と形がクラス名に含まれる場合、表示させる
		for (var i = 0; i < colorList.length; i++) { // 選択された色の分ループ回し、
			for (var j = 0; j < shapeList.length; j++) { // その中でさらに、選択された形の分ループを回す
				for (var k = 0; k < contents.length; k++) { // 要素全部ループ回し
					// 色・形のどちらもがクラスに含まれる場合、表示
					if(contents[k].classList.contains(colorList[i])&&contents[k].classList.contains(shapeList[j])) {
						contents[k].classList.remove('hidden'); // hiddenクラスを削除することで表示
					}
				}
			}
		}
	}
	// 色にだけチェックがついている場合
	else if (colorList.length !=0 && shapeList.length === 0) {
		
		// 一旦全部を非表示にし、
		for (var i = 0; i < contents.length; i++) {
			contents[i].classList.add('hidden'); // hiddenクラスを付与することで非表示に
		}
		// 選択された色のものだけを表示
		for (var i = 0; i < colorList.length; i++) { // チェックされた色の分ループ回し
			for (var j = 0; j < contents.length; j++) { // プログラムの数分ループ
				// チェックされた色のクラスが含まれていたら、表示
				if(contents[j].classList.contains(colorList[i])) {
					contents[j].classList.remove('hidden'); // hiddenクラスを削除して、表示に
				}
			}
		}
	}
	// 形にだけチェックが付いている場合
	else if (colorList.length === 0 && shapeList.length != 0) {
		
		// 一旦全部を非表示にし、
		for (var i = 0; i < contents.length; i++) {
			contents[i].classList.add('hidden'); // hiddenクラスを付与することで非表示に
		}
		
		// 選択された形のものだけを表示
		for (var i = 0; i < shapeList.length; i++) { // チェックされた形の数分ループ回し
			for (var j = 0; j < contents.length; j++) { // プログラムの数分ループ
				// チェックされた形のクラスがふくまれていたら、表示
				if(contents[j].classList.contains(shapeList[i])) {
					contents[j].classList.remove('hidden'); // hiddenクラスを削除して、表示
				}
			}
		}
	}
	// どちらもチェックが付いていない場合
	else {
		// すべてを表示
		for (var i = 0; i < contents.length; i++) {
			contents[i].classList.remove('hidden'); // hiddenクラスを削除して、表示
		}
	}
}

// 色の選択があったとき
for (var i = 0; i < color.length; i++) {
	color[i].addEventListener('click', function () {
		andOrSort();
	});
}

// 形の選択があったとき
for (var i = 0; i < shape.length; i++) {
	shape[i].addEventListener('click', function () {
		andOrSort();
	});
}

色・形どちらかの inputタグがクリックされたら発動。
選択されている(checkedになっている)色・形を洗い出します。
一旦全部の要素に .hidden を付与し、非表示に。
そして選択されているもののクラス名がついているものから .hidden クラスを外して表示させます。
色・形のどちらにもチェックがついている場合、色だけにチェックがついている場合、形だけにチェックがついている場合、どちらにもチェックが付いていない場合で、処理を分けています。