首页 > 解决方案 > 单击选项卡时过滤数据

问题描述

我有两个输入(标题和状态)和一个提交按钮。当我单击提交按钮时,我将输入值添加到表中。但是,表格有 3 个按钮;全部,活动且已完成。我想要做的是当我单击“活动”或“已完成”按钮时,该按钮应该处于活动状态并根据列表中的“状态”值过滤数据。(默认情况下应选择所有按钮并显示所有数据,无论其状态如何)

例如,在下图中,如果我单击“已完成”选项卡,该选项卡应该处于活动状态并且只显示 Cook。

在此处输入图像描述

这是我几天前尝试解决的 DOM 挑战,但仍然无法解决。我不允许更改 HTML 中的任何内容。只有普通的 JavaScript。

HTML

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link
      href="https://cdn.jsdelivr.net/npm/@ionic/core/css/ionic.bundle.css"
      rel="stylesheet"
    />
    <script
      type="module"
      src="https://cdn.jsdelivr.net/npm/@ionic/core/dist/ionic/ionic.esm.js"
    ></script>
    <script
      nomodule
      src="https://cdn.jsdelivr.net/npm/@ionic/core/dist/ionic/ionic.js"
    ></script>

    <script src="https://cdn.jsdelivr.net/npm/h8k-components@latest/dist/h8k-components.js"></script>
    <link
      rel="stylesheet"
      href="https://cdn.jsdelivr.net/npm/h8k-design@latest/dist/index.css"
    />

    <link rel="stylesheet" href="./styles.css" />
    <script type="module" src="./index.js"></script>

    <title>Document</title>
  </head>
  <body>
    <div id="root">
      <h8k-navbar header="Notes"></h8k-navbar>
      <div class="layout-column align-items-center justify-content-start">
        <section
          class="layout-row align-items-center justify-content-center mt-30"
        >
          <input
            data-testid="input-note-name"
            type="text"
            class="large mx-8"
            placeholder="Note Title"
          />
          <input
            data-testid="input-note-status"
            type="text"
            class="large mx-8"
            placeholder="Note Status"
          />
          <button class="" data-testid="submit-button">Add Note</button>
        </section>
        <div class="mt-50">
          <ul class="tabs">
            <li class="tab-item slude-up-fade-in" data-testid="allButton">
              All
            </li>
            <li class="tab-item slude-up-fade-in" data-testid="activeButton">
              Active
            </li>
            <li class="tab-item slude-up-fade-in" data-testid="completedButton">
              Completed
            </li>
          </ul>
        </div>
        <div class="card w-40 pt-30 pb-8">
          <table>
            <thead>
              <tr>
                <th>Title</th>
                <th>Status</th>
              </tr>
            </thead>
            <tbody data-testid="noteList"></tbody>
          </table>
        </div>
      </div>
    </div>
  </body>
</html>

CSS

.tabs {
  list-style: none;
  display: flex;
  margin: 0;
  padding: 0;
}

.tabs .tab-item {
  min-width: 88px;
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: center;
  position: relative;
  cursor: pointer;
  padding: 20px 16px;
  color: var(--heading-color);
}

.tabs .tab-item::before {
  content: '';
  position: absolute;
  top: 0;
  width: 100%;
  height: 2px;
  background: var(--primary-color);
  opacity: 0;
  transition: opacity 0.3s ease-in-out;
}

.tabs .tab-item:active {
  background: #fff;
  position: relative;
  color: black;
}

.tabs .tab-item:active::before {
  opacity: 1;
}

table tbody tr td {
  font-weight: bold;
  font-size: 16px;
  height: 21px;
  padding: 1.6rem;
}

JavaScript

const nameInput = document.querySelector('[data-testid="input-note-name"]');
const statusInput = document.querySelector('[data-testid="input-note-status"]');
const submitButton = document.querySelector('[data-testid="submit-button"]');
const allButton = document.querySelector('[data-testid="allButton"]');
const activeButton = document.querySelector('[data-testid="activeButton"]');
const completedButton = document.querySelector(
  '[data-testid="completedButton"]'
);
const noteList = document.querySelector('[data-testid="noteList"]');
const tabs = document.querySelector('.tabs');

submitButton.addEventListener('click', () => {
  console.log('Hey');
  const titleNode = document.createTextNode(nameInput.value);
  const statusNode = document.createTextNode(statusInput.value);
  const trEl = document.createElement('tr');
  const tdEl = document.createElement('td');
  const tdEl2 = document.createElement('td');

  trEl.appendChild(tdEl);
  tdEl.appendChild(titleNode);
  trEl.appendChild(tdEl2);
  tdEl2.appendChild(statusNode);
  noteList.appendChild(trEl);
});

标签: javascriptdom

解决方案


以防万一您尝试创建尽可能多的代码行并且您不想用尽可能多的变量填充全局空间,那么也许以下内容也适用于您:

const tb=document.querySelector("[data-testid=noteList]");

document.querySelector("button").onclick=ev=>    // add an entry
 tb.innerHTML+="<tr><td>"
  +[...ev.target.parentNode.children]
    .filter(e=>e.tagName==="INPUT")
    .map(e=>e.value)
    .join("</td><td>")+"</td></tr>";
    
document.querySelector("ul.tabs").onclick=ev=>{  // filter buttons
 if (ev.target.tagName==="LI"){
  let sel=ev.target.textContent.trim().toLowerCase();
  [...tb.children].forEach(tr=>tr.style.display=
    sel=="all" || sel===tr.children[1].textContent.trim().toLowerCase()
    ? "" : "none"  )
}}
.tabs {
  list-style: none;
  display: flex;
  margin: 0;
  padding: 0;
}

.tabs .tab-item {
  min-width: 88px;
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: center;
  position: relative;
  cursor: pointer;
  padding: 20px 16px;
  color: var(--heading-color);
}

.tabs .tab-item::before {
  content: '';
  position: absolute;
  top: 0;
  width: 100%;
  height: 2px;
  background: var(--primary-color);
  opacity: 0;
  transition: opacity 0.3s ease-in-out;
}

.tabs .tab-item:active {
  background: #fff;
  position: relative;
  color: black;
}

.tabs .tab-item:active::before {
  opacity: 1;
}

table tbody tr td {
  font-weight: bold;
  font-size: 16px;
  height: 1px;
  padding: 2px 20px;
}
<div id="root">
  <h8k-navbar header="Notes"></h8k-navbar>
  <div class="layout-column align-items-center justify-content-start">
    <section class="layout-row align-items-center justify-content-center mt-30">
      <input data-testid="input-note-name" type="text" class="large mx-8" placeholder="Note Title" />
      <input data-testid="input-note-status" type="text" class="large mx-8" placeholder="Note Status" />
      <button class="" data-testid="submit-button">Add Note</button>
    </section>
    <div class="mt-50">
      <ul class="tabs">
        <li class="tab-item slude-up-fade-in" data-testid="allButton">
          All
        </li>
        <li class="tab-item slude-up-fade-in" data-testid="activeButton">
          Active
        </li>
        <li class="tab-item slude-up-fade-in" data-testid="completedButton">
          Completed
        </li>
      </ul>
    </div>
    <div class="card w-40 pt-30 pb-8">
      <table>
        <thead>
          <tr>
            <th>Title</th>
            <th>Status</th>
          </tr>
        </thead>
        <tbody data-testid="noteList"></tbody>
      </table>
    </div>
  </div>
</div>

<td>我还冒昧地删除了元素 ( )周围的一些随机空白,padding: 1.6rem因为我宁愿看到内容而不是空白。


推荐阅读