【フォーム】ラジオボタンとチェックボックスで複合的に絞り込み検索

ラジオボタンとチェックボックスを使って複合的にコンテンツの絞り込み検索をします。絞り込み検索の条件はラジオボタンとチェックボックスのvalue属性と、コンテンツのdivタグのカスタムデータ属性の一致です。

htmlのコードは下記になります。
ラジオボタンとチェックボックスにはname属性とvalue属性を設定します。name属性はラジオボタンとチェックボックスでそれぞれ、kindとcatで固定します。ラジオボタンの「全て」の項目のみvalue=””にします。
表示するコンテンツのdivタグ側にはラジオボタンとチェックボックスのname属性に対応したカスタムデータ属性を設定します。今回はdata-kind=”あ~わ行名”、data-cat=”カテゴリ名”とします。

<div class="search-box mb">
	<span class="search-box_title">あ~わ行:</span>
	<label><input type="radio" name="kind" value="">全て</label>
	<label><input type="radio" name="kind" value="kind01">あ~さ行</label>
	<label><input type="radio" name="kind" value="kind02">た~は行</label>
	<label><input type="radio" name="kind" value="kind03">ま~わ行</label>
</div>
<div class="search-box">
	<span class="search-box_title">カテゴリ:</span>
	<label><input type="checkbox" name="cat" value="cat01">アコーディオンメニュー</label>
	<label><input type="checkbox" name="cat" value="cat02">カレンダー</label>
	<label><input type="checkbox" name="cat" value="cat03">タブメニュー</label>
	<label><input type="checkbox" name="cat" value="cat04">ツールチップ</label>
	<label><input type="checkbox" name="cat" value="cat05">フェーダー</label>
	<label><input type="checkbox" name="cat" value="cat06">フォーム</label>
	<label><input type="checkbox" name="cat" value="cat07">マウスオーバー</label>
	<label><input type="checkbox" name="cat" value="cat08">モーダルウィンドウ</label>
	<label><input type="checkbox" name="cat" value="cat09">レスポンシブ</label>
</div>
<div class="cat_image_all">
	<div class="cat_image" data-kind="kind03" data-cat="cat08">
		<a href="/modal/modal-pattern05/">
		<img src="modal-pattern05.png" alt="">
		<p class="page_title">【モーダルウィンドウ】jquery.magnific-popup.jsを利用してYouTubeの動画を再生</p>
		</a>
	</div>
	<div class="cat_image" data-kind="kind02" data-cat="cat05">
		<a href="/fade/fade-pattern11/">
		<img src="fade-pattern11.png" alt="">
		<p class="page_title">【フェーダー】左から右へカーテンを開くように画像を順番に表示</p>
		</a>
	</div>
	<div class="cat_image" data-kind="kind03" data-cat="cat08">
		<a href="/modal/modal-pattern04/">
		<img src="modal-pattern04.png" alt="">
		<p class="page_title">【モーダルウィンドウ】プラグインを利用してhtml内のソースを表示【jquery.magnific-popup.js】</p>
		</a>
	</div>
</div>

続いてCSSのコードです。
コンテンツはフレックスボックスで横並びにします。また、コンテンツのdivタグにクラス名is-hideが付与された時のみ、display: noneにします。

.search-box_title{
	font-weight: bold;
}
.search-box label {
	cursor: pointer;
	display: inline-block;
	margin-right: 10px;
	line-height: 16px;
}
.search-box input[type="radio"] {
	width: 16px;
	height: 16px;
	margin: -2px 5px 0 0;
	padding: 0;
	box-sizing: border-box;
	vertical-align: middle;
}
.search-box input[type="checkbox"] {
	width: 16px;
	height: 16px;
	margin: -2px 5px 0 0;
	padding: 0;
	box-sizing: border-box;
	vertical-align: middle;
}
.cat_image_all {
	display: flex;
	flex-wrap: wrap;
	justify-content: space-between;
	max-width: 680px;
	margin: 3em auto 0;
}
.cat_image {
	width: 48%;
	max-width: 320px;
	margin: 0 0 2em;
}
.cat_image.is-hide {
	display: none;
}
.cat_image a {
	display: block;
	color: #444;
}
.cat_image a:hover {
	text-decoration: underline;
}

最後にjQueryのコードです。
ラジオボタンまたはチェックボックスがクリックされた時の動作になります。
まず関数search_filterを呼び出します。関数search_filterでは一度コンテンツのdivタグ全てからクラス名is-hideを削除して、全てのコンテンツを表示状態にします。
次にコンテンツの絞り込みの処理ですが、クラス名search-boxの数だけ繰り返します。つまりラジオボタン、チェックボックスの順番で処理します。まずラジオボタンのname属性を関数selected_itemsへ渡し、チェックされている項目のvalue属性を配列searchDataへ格納して戻します。そして配列searchDataにデータがない場合、もしくは配列の1番目のデータが空の場合、continueで繰り返し処理のforを抜けて次のチェックボックスの処理へ移ります。つまり全てのコンテンツの表示状態を維持します。
それ以外の場合は配列searchDataとコンテンツのdivタグのカスタムデータ属性を比較して、一致しない場合のみコンテンツのdivタグにクラス名is-hideを付与して非表示にします。カスタムデータ属性はdataメソッドを利用して取得し、配列とカスタムデータ属性の比較はindexOfを利用します。チェックボックスの処理もラジオボタンの処理と同様です。

var searchBox = '.search-box';
var searchItem = '.search-box input';
var listItem = '.cat_image';
var hideClass = 'is-hide';

$(function() {
	$(searchItem).on('change', function() {
		search_filter();
	});
});

function search_filter() {
	$(listItem).removeClass(hideClass);
	for (var i = 0; i < $(searchBox).length; i++) {
		var name = $(searchBox).eq(i).find('input').attr('name');
		var searchData = selected_items(name);
		if(searchData.length === 0 || searchData[0] === '') {
			continue;
		}
		for (var j = 0; j < $(listItem).length; j++) {
			var itemData = $(listItem).eq(j).data(name);
			if(searchData.indexOf(itemData) === -1) {
				$(listItem).eq(j).addClass(hideClass);
			}
		}
	}
}

function selected_items(name) {
	var searchData = [];
	$('input[name=' + name + ']:checked').each(function() {
		searchData.push($(this).val());
	});
	return searchData;
}

タイトルとURLをコピーしました