JavaScript | 1 日 90 分 × 7 日アプリ学習:ミニ総合アプリ(初級編)

JavaScript
スポンサーリンク

3日目のゴールと今日やること

3日目のテーマは
「ミニ総合アプリを“検索・絞り込み・強調表示”ができるアプリに進化させる」
ことです。

1日目:入力 → 一覧 → 削除
2日目:ID 管理・オブジェクト化・条件分岐(強調表示)

そして 3日目は、次のステップに進みます。

入力
一覧
削除
条件分岐(検索・絞り込み・強調表示の応用)

これらを組み合わせて、
「ちょっとした実用アプリ」に近づけていきます。


入力データを「検索できる」ようにする

検索欄を追加する

HTML に検索欄を追加します。

<input type="text" id="searchInput" placeholder="検索ワードを入力">

JavaScript で検索欄を取得します。

const searchInput = document.getElementById("searchInput");
JavaScript

検索欄が入力されるたびに一覧を再描画します。

searchInput.addEventListener("input", () => {
  renderList();
});
JavaScript

深掘り:検索は「配列を絞り込む」だけで実現できる

検索機能は難しそうに見えますが、
実は filter を使うだけ で作れます。

検索ワードを含むものだけを表示する仕組みです。


一覧表示を「検索対応」に書き換える

検索ワードを使って絞り込む

function renderList() {
  listArea.innerHTML = "";

  const keyword = searchInput.value.trim();

  const filteredItems = items.filter((item) => {
    return item.text.includes(keyword);
  });

  if (filteredItems.length === 0) {
    message.textContent = "該当するデータがありません。";
    return;
  } else {
    message.textContent = "";
  }

  filteredItems.forEach((item) => {
    const row = document.createElement("div");
    row.textContent = item.text;

    const deleteButton = document.createElement("button");
    deleteButton.textContent = "削除";

    deleteButton.addEventListener("click", () => {
      deleteItem(item.id);
    });

    row.appendChild(deleteButton);
    listArea.appendChild(row);
  });
}
JavaScript

深掘り:filter の本質

filter は
「条件に合うものだけを残した新しい配列を返す」
というメソッドです。

検索機能はこの filter と
includes() の組み合わせで成立します。


条件分岐を応用して「検索ワードを強調表示」する

強調表示の仕組み

検索ワードが含まれている部分だけ
色を変えて表示することができます。

function highlight(text, keyword) {
  if (keyword === "") return text;
  return text.replace(keyword, `【${keyword}】`);
}
JavaScript

一覧表示で使います。

row.textContent = "";
row.innerHTML = highlight(item.text, keyword);
JavaScript

深掘り:replace を使った簡易ハイライト

replace は
「文字列の一部を別の文字列に置き換える」
というメソッドです。

今回は
検索ワード → 【検索ワード】
に置き換えることで、
簡易的なハイライトを実現しています。


削除機能を「検索状態でも正しく動く」ようにする

削除は items 配列を直接操作する

検索結果は filteredItems ですが、
削除するのは items の中身です。

function deleteItem(id) {
  const newItems = items.filter((item) => item.id !== id);
  items.length = 0;
  newItems.forEach((i) => items.push(i));
  renderList();
}
JavaScript

深掘り:検索結果と本体配列を混同しない

検索結果はあくまで「表示用の一時的な配列」です。
本体の items を書き換えることで、
検索状態でも削除が正しく動きます。


条件分岐をさらに応用して「優先度フィルタ」を追加する

優先度を追加する

入力時に優先度を選べるようにします。

<select id="prioritySelect">
  <option value="通常">通常</option>
  <option value="重要">重要</option>
</select>

追加時にオブジェクトへ保存します。

const priority = document.getElementById("prioritySelect").value;

const newItem = {
  id: nextId,
  text: text,
  priority: priority
};
JavaScript

優先度で絞り込む条件分岐

const filteredItems = items.filter((item) => {
  const matchText = item.text.includes(keyword);
  const matchPriority = priorityFilter === "すべて" || item.priority === priorityFilter;
  return matchText && matchPriority;
});
JavaScript

深掘り:条件分岐は「複数条件を組み合わせる」ことで強くなる

検索ワード
優先度
文字の含有
ID の一致

これらを組み合わせることで、
アプリは一気に“実用的”になります。


3日目の完成コード(要点まとめ)

let nextId = 1;
const items = [];

const input = document.getElementById("itemInput");
const addButton = document.getElementById("addButton");
const listArea = document.getElementById("listArea");
const message = document.getElementById("message");
const searchInput = document.getElementById("searchInput");

addButton.addEventListener("click", () => {
  const text = input.value.trim();
  if (text === "") return;

  const newItem = {
    id: nextId,
    text: text
  };

  items.push(newItem);
  nextId += 1;

  input.value = "";
  renderList();
});

searchInput.addEventListener("input", () => {
  renderList();
});

function renderList() {
  listArea.innerHTML = "";

  const keyword = searchInput.value.trim();

  const filteredItems = items.filter((item) => {
    return item.text.includes(keyword);
  });

  if (filteredItems.length === 0) {
    message.textContent = "該当するデータがありません。";
    return;
  } else {
    message.textContent = "";
  }

  filteredItems.forEach((item) => {
    const row = document.createElement("div");
    row.innerHTML = highlight(item.text, keyword);

    const deleteButton = document.createElement("button");
    deleteButton.textContent = "削除";

    deleteButton.addEventListener("click", () => {
      deleteItem(item.id);
    });

    row.appendChild(deleteButton);
    listArea.appendChild(row);
  });
}

function highlight(text, keyword) {
  if (keyword === "") return text;
  return text.replace(keyword, `【${keyword}】`);
}

function deleteItem(id) {
  const newItems = items.filter((item) => item.id !== id);
  items.length = 0;
  newItems.forEach((i) => items.push(i));
  renderList();
}

renderList();
JavaScript

今日いちばん深く理解してほしいこと

filter と includes の組み合わせが「検索機能の核」

検索は難しくありません。
配列を filter で絞り込み、
文字列を includes で判定するだけです。

条件分岐は「状態に応じて UI を変える」ための道具

検索ワード
優先度
件数
文字の含有

これらを if 文で組み合わせることで、
アプリはどんどん賢くなります。


4日目へのつなぎ

4日目はさらに進んで、

入力項目を増やす
編集機能を追加する
並び替え(ソート)を実装する
条件分岐を複数組み合わせて高度な絞り込みを作る

という、“本格的なミニアプリ”に進化させていきます。

ここまで来たあなたは、
もう立派に「配列 × 条件分岐 × DOM 操作」を使いこなせています。

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