tiiti
@tiiti

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

filter()についてアドバイスを頂戴したいです。

filterについて

タスクを入力した瞬間からfilterをかけたいです。
スクリーンショット 2022-09-09 18.43.35.png

javascriptを使用して、簡単なTODOアプリを作成しております。
状態を「作業中」・「削除」にて管理しており、
filterを使ってラジオボタンでどこにチェックが入っているかによって、
TODOの表示、非表示に変化を付けています。

一度、入力してからラジオボタンを押せばタスクが振り分けられるのですが、タスクを入力し追加ボタンを押すとラジオボタン「完了」にチェックがあっても、全てのタスクが表示されてしまいます。
タスクを入力した瞬間からfilterが適用される処理をしたいです。
(ラジオボタン(完了)にチェックが入ってる場合、タスクを追加しても画面上には何も表示されないが、配列には追加されている)

ソースコード

const input = document.getElementById("addbutton");
const tbody = document.getElementById("tbody");
const radiowork = document.getElementById("radio-work");
const radiocomplete = document.getElementById("radio-complete");
const radioall = document.getElementById("radio-all");

const tasks = [];
const createStatusButton = (task) => {
  const button = document.createElement("button");
  button.innerText = task.status;
  button.style.backgroundColor = "lightgray";
  button.addEventListener("click", () => {
    const buttonStatus = button.innerText;
    console.log("変更前", task);

    if (buttonStatus === "作業中") {
      button.textContent = "完了";
      task.status = "完了";
    } else {
      button.textContent = "作業中";
      task.status = "作業中";
    }
    console.log("変更後", task);
  });
  return button;
};

const createdeleteButton = (index) => {
  const deletebutton = document.createElement("button");
  deletebutton.innerText = "削除";
  deletebutton.style.backgroundColor = "lightgray";
  deletebutton.addEventListener("click", () => {
    tasks.splice(index, 1);
    showTaskList(tasks);
  });
  return deletebutton;
};

const showTaskList = (filteredTasks) => {
  console.log("filteredTasks", filteredTasks);
  tbody.innerHTML = "";
  filteredTasks.forEach((task, index) => {
    const tr = document.createElement("tr");
    const td1 = document.createElement("td");
    td1.innerHTML = `${index}`;
    const td2 = document.createElement("td");
    td2.innerHTML = `${task.comment}`;
    const td3 = document.createElement("td");
    const td4 = document.createElement("td");
    tbody.appendChild(tr);
    tr.appendChild(td1);
    tr.appendChild(td2);
    tr.appendChild(td3);
    tr.appendChild(td4);
    td3.appendChild(createStatusButton(task));
    td4.appendChild(createdeleteButton(index));
  });
};

const tasksStatus = document.getElementById("statusradio");
const text = document.getElementById("tasks");

input.addEventListener("click", () => {
  const text = document.getElementById("tasks");
  if (text.value === "") {
    alert("タスクを入力してください");
  } else {
    tasks.push({
      comment: text.value,
      status: "作業中",
    });
    showTaskList(tasks);
  }
  text.value = "";
});

radiowork.addEventListener("change", () => {
  console.log(tasks); // ラジオボタン(作業中)がクリックされた時のタスクを表示
  const result = tasks.filter((task) => task.status === "作業中");
  console.log("result", result); // フィルターをかけた後のタスクのみをコンソールに出力
  showTaskList(result);
});

// ラジオボタン(完了)がクリックされた時
radiocomplete.addEventListener("change", () => {
  const result2 = tasks.filter((task) => task.status === "完了");
  console.log("result", result2);
  showTaskList(result2);
});

// ラジオボタン(完了)がクリックされた時
radioall.addEventListener("change", () => {
  showTaskList(tasks);
});

自分で試したこと

ボタンイベントでタスクを追加する際にif文でラジオボタンを取得し、
タスクを追加するタイミングでfilteerをかけようとしましたが、
タスクを入力しても「タスクを入力してください」のアラートが出てしまいます。
完了にチェックを入れていても入力したタスクが表示されてしまいます。

input.addEventListener("click", () => {
  const text = document.getElementById("tasks");
  if (text.value === "") {
    alert("タスクを入力してください");
  } else {
    tasks.push({
      comment: text.value,
      status: "作業中",
    });
    if (radiowork.checked) {
      const result = tasks.filter((task) => task.status === "作業中");
      showTaskList(result);
    } else if (radiocomplete.checked) {
      const result2 = tasks.filter((task) => task.status === "完了");
      showTaskList(result2);
    }
    text.value = "";
  }
});

0

1Answer

Comments

  1. @tiiti

    Questioner


    こちらです!
    よろしくお願いいたします!


    ```
    <!DOCTYPE html>
    <html lang="ja">
    <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link
    href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css"
    rel="stylesheet"
    />
    <title>JS課題3</title>
    </head>
    <body>
    <h1 class="text-4xl font-semibold font-serif">ToDoリスト</h1>
    <div class="mt-8" id="statusradio">
    <input
    type="radio"
    name="taskradio"
    id="radio-all"
    value="all"
    checked
    />すべて
    <input type="radio" name="taskradio" id="radio-work" value="work" />作業中
    <input
    type="radio"
    name="taskradio"
    id="radio-complete"
    value="complete"
    />完了
    </div>

    <table>
    <thead>
    <tr class="text-xl font-extrabold font-serif">
    <th class="px-1">ID</th>
    <th class="px-1">コメント</th>
    <th class="px-1">状態</th>
    </tr>
    </thead>

    <tbody id="tbody" name="tbody"></tbody>
    </table>

    <p class="text-2xl font-black font-serif pt-4">新規タスクの追加</p>
    <div class="pt-4">
    <input
    type="text"
    id="tasks"
    class="border border-gray-500"
    name="tasks"
    />
    <input type="button" id="addbutton" value="追加" class="rounded" />
    </div>

    <script src="index.js"></script>
    </body>
    </html>
    ```
  2. 試して見ましたが、アラートは出ずに動いているように見えます。
    キャッシュが原因ということは無いですか?
  3. @tiiti

    Questioner

    HTML、折りたたみについてありがとうございます!

    また、お試しいただきありがとうございます。
    最初に記載させていただいたコードはアラートは出ないのですが、
    ラジオボタン「完了」にチェックを入れてタスクを追加した場合でも状態が「作業中」でタスクが表示されてしまいます。タスクを追加する際は初期値を「作業中」で出力するため
    ラジオボタン「完了」にしている場合タスクを追加してもfilterをかけて表示されないようにしたいです。

    input.addEventListener("click", () => {
    const text = document.getElementById("tasks");
    if (text.value === "") {
    alert("タスクを入力してください");
    } else {
    tasks.push({
    comment: text.value,
    status: "作業中",
    });
    if (radiowork.checked) {
    const result = tasks.filter((task) => task.status === "作業中");
    showTaskList(result);
    } else if (radiocomplete.checked) {
    const result2 = tasks.filter((task) => task.status === "完了");
    showTaskList(result2);
    }
    text.value = "";
    }
    });

    上記に関しては、タスク追加した瞬間からfilterを作用させるために自分で試してみたコードを抜粋したもので実際に記載してはおりません。
    本文のinput.addEventListener("click", () => {から始まる部分を上記に書き換えた場合アラートが出てしまいます。

    分かりにくくて申し訳ございません。。
  4. 「自分で試したこと」のコードに書き換えて試してみました。アラートは出ずに動いています。
    「すべて」で追加 => タスクは何も表示されない
    「作業中」で追加 => 作業中のタスクが表示される
    「完了」で追加 => 完了のタスクが表示される

    コードはこちらにあるので確認していただけますか?
    https://codepen.io/blue32a/pen/zYjqMpp
  5. @tiiti

    Questioner

    ありがとうございます。大変失礼いたしました。
    僕自身で書いているコードがどこかおかしくなってるかもしれないので見直してみます。

    「すべて」で追加 => タスクは何も表示されない
    「作業中」で追加 => 作業中のタスクが表示される
    「完了」で追加 => 完了のタスクが表示される

    上記の状況なら何とかなりそうなのでもう一度自分で考えてみます。
    お手数お掛けいたしました、、ご丁寧にコードをお試しいただいたり状況を整理してくださり誠にありがとうございます!

Your answer might help someone💌