概要
DBに登録されているスケジュールを全件取得し一覧表示。一覧表示されているスケジュールに対し、<input>
で入力したキーワードでスケジュールのタイトル、作成者に該当する スケジュールを表示し、該当しないスケジュールは非表示にする。
また、文字が入力されるたびに検索処理が走り、部分一致検索にてキーワードに該当するスケジュールを表示する。
完成イメージ
コード
index.html
//検索バー
<p>
<input type="text" id="serch_schedule" placeholder="キーワードで検索">
</p>
//検索対象のスケジュール
<ul id="display_schedule_area">
<li class="schedule" data-title="スケジュール1" data-author="田中さん">
<a href="#">
<dl>
<dt>6/6 19:40 〜 6/6 19:41<span>田中さん</span></dt>
<dd>スケジュール1</dd>
</dl>
</a>
</li>
<li class="schedule" data-title="スケジュール2" data-author="川島さん">
<a href="#">
<dl>
<dt>6/6 19:40 〜 6/6 19:41<span>川島さん</span></dt>
<dd>スケジュール2</dd>
</dl>
</a>
</li>
<li class="schedule" data-title="スケジュール3" data-author="西村さん">
<a href="#">
<dl>
<dt>6/6 19:40 〜 6/6 19:41<span>田中さん</span></dt>
<dd>スケジュール3</dd>
</dl>
</a>
</li>
//検索結果が0件の時に表示
<li class="no_schedule" data-title="" data-author="">検索したスケジュールは見つかりませんでした</li>
</ul>
main.js
document.getElementById("serch_schedule").addEventListener("input", searchSchedule);
const searchSchedule = (e) => {
const keyword = e.target.value;
const $schedules = document.querySelectorAll("#display_schedule_area > li");
const $no_schedule = document.querySelector(".no_schedule");
$no_schedule.style.display = "none";
if (keyword) {
$schedules.forEach(e => e.style.display = "none");
const filter = Array.from($schedules).filter(e => {
const schedule_title = e.dataset.title;
const schedule_author = e.dataset.author;
if (schedule_title.indexOf(keyword.toLowerCase()) !== -1 ||
schedule_title.indexOf(keyword.toUpperCase()) !== -1 ||
schedule_author.indexOf(keyword.toLowerCase()) !== -1 ||
schedule_author.indexOf(keyword.toUpperCase()) !== -1) {
return e;
}
});
filter.length === 0 ? $no_schedule.style.display = "block" : filter.forEach(e => e.style.display = "block");
} else {
$schedules.forEach(e => e.style.display = "block");
$no_schedule.style.display = "none";
}
}
解説
main.js
document.getElementById("serch_schedule").addEventListener("input", searchSchedule);
- 検索バーに文字が1文字入力されるたびに
searchSchedule
メソッドが実行される。
main.js
const keyword = e.target.value;
const $schedules = document.querySelectorAll("#display_schedule_area > li");
const $no_schedule = document.querySelector(".no_schedule");
$no_schedule.style.display = "none";
- 入力したキーワード、検索対象の
<li>
要素、検索結果が0件だった場合に表示する<li>
要素を変数に格納。 -
$no_schedule
は非表示にしておく。 - アロー関数において入力されたキーワード(
<input>
タグのvalue
)はthis
の参照先がwindowオブジェクトを参照するためthis.value
では取得できない
main.js
$schedules.forEach(e => e.style.display = "none");
- キーワードが入力されれば一旦検索対象の
<li>
要素は非表示にする(初期化)
main.js
const filter = Array.from($schedules).filter(e => {
const schedule_title = e.dataset.title;
const schedule_author = e.dataset.author;
if (schedule_title.indexOf(keyword.toLowerCase()) !== -1 ||
schedule_title.indexOf(keyword.toUpperCase()) !== -1 ||
schedule_author.indexOf(keyword.toLowerCase()) !== -1 ||
schedule_author.indexOf(keyword.toUpperCase()) !== -1) {
return e;
});
- NodeListの
$schedules
に対してfilter
メソッドを実行するとエラーになるので、Array.from($schedules)
で配列に変換後、filter
メソッドを実行。 -
indexOf
メソッドで条件に合致する<li>
要素を変数filter
に格納し、新たに配列を作成する。 -
toUpperCase
メソッドとtoLowerCase
メソッドで大文字、小文字どちらでもヒットするようになる。
main.js
filter.length === 0 ? $no_schedule.style.display = "block" : filter.forEach(e => e.style.display = "block");
- 配列
filter
が空でない場合はforEach
メソッドで順番に表示する。 - 配列が空の場合は0件用の
<li>
要素を表示する。