在表格上结合搜索和复选框的JavaScript过滤器

3
我在一个HTML表格上有一个搜索过滤器和复选框过滤器,它们都工作得很好,但它们是独立工作的。我希望能够选择一个类别,然后在该类别内使用搜索框。现在,如果我开始搜索,复选框会重置,反之亦然。
我认为有两种方法可以解决这个问题 - 要么更新GetElement函数以仅获取显示的内容,要么将两个if/else语句合并为一个。但是我是自学的,这对我来说都是新的,所以我在编写正确的代码方面遇到了困难!

  function myFunction() {
    var input, filter, table, tr, td, i, txtValue;
    input = document.getElementById("myInput");
    filter = input.value.toUpperCase();
    table = document.getElementById("myTable");
    tr = table.getElementsByTagName("tr");
    for (i = 0; i < tr.length; i++) {
      td = tr[i].getElementsByTagName("td")[0];
      if (td) {
        txtValue = td.textContent || td.innerText;
        if (txtValue.toUpperCase().indexOf(filter) > -1) {
          tr[i].style.display = "";
        } else {
          tr[i].style.display = "none";
        }
      }
    }
  } 
src = "https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"

  // Select cluster
  $(document).ready(function() {
    $('input[type="checkbox"]').change(function() {
      var inputValue = $(this).attr("value");
      var checked = $(this)[0].checked;
      $("tr").each(function() {
        if ($(this).find("td:eq(1)").html() !== undefined && $(this).find("td:eq(1)").html().includes(inputValue.toString())) {
          if (checked) {
            $(this).show(); // slice by n numbers here
          } else {
            $(this).hide();
          }
        }
      });
    });
  });

function checkedAll() {
  console.log("All")
  var elements = this.form.getElementsByTagName('input');
  console.log(elements)
  // iterate and change status
  for (var i = elements.length; i--;) {
    if (elements[i].type == 'checkbox') {
      console.log(this)
      elements[i].checked = this.checked;
      $(elements[i]).trigger("change");
    }
  }
} 
table#myTable {
  width: 800px;
}
<!-- SEARCH -->

<h3>Search by keyword or phrase:</h3>
<input type="text" id="myInput" onkeyup="myFunction()" placeholder="Start typing to filter the table below" style="width:100%; transform: none;">


<!-- CHECKMARKS -->


<form action="" method="post" name="frm1" id="frm1">

  <h3>Filter by category:</h3>

  <label class="clickable">
<input type="checkbox" name="cluster_ids" id="cluster_ids" onclick="checkedAll.call(this);" checked /> Select all</label><br>

  <div style="float:left; width:33%; min-width:200px;">
    <label class="clickable">
<input value="For attorneys" type="checkbox" name="cluster_ids" checked/> For attorneys</label><br>

    <label class="clickable">
<input value="For clinicians" type="checkbox" name="cluster_ids" checked/> For clinicians</label><br>

    <label class="clickable">
<input value="For patients and families" type="checkbox" name="cluster_ids" checked/> For patients and families</label><br>


    <!-- TABLE -->

    <table id="myTable">
      <tr>
        <th>
          <h1>Resource</h1>
        </th>
        <th>
          <h1>Category</h1>
        </th>
      </tr>

      <tr>
        <td>
          <h3>20 things patients can do to help prevent medical errors</h3>
          <p>Information for patients from the Agency for Healthcare Research and Quality (AHRQ)</p>
        </td>
        <td class="topic-column">For patients and families</td>
      </tr>

      <tr>
        <td>
          <h3>Best practices for attorneys representing patients using CARe</h3>
          <p>How lawyers can best support patients during the CARe process</p>
        </td>

        <td class="topic-column">For attorneys</td>

        <tr>
          <td>
            <h3>Clinician CARe communication algorithm</h3>
            <p>Flow chart with examples of what to say and what not to say during conversations with patients and families</p>
          </td>
          <td class="topic-column">For clinicians</td>
        </tr>

        <tr>
          <td>
            <h3>Guidelines for handling medical adverse events: Enhancing safety through candid communication</h3>
            <p>Covers the seven aspects of response to adverse events: initial response, truth-telling, apologies, mediation, root cause analysis, compensation, and reporting</p>
          </td>
          <td class="topic-column">For clinicians</td>
        </tr>

        <tr>
          <td>
            <h3>Handout for patients</h3>
            <p>A patient-focused flyer that explains the elements of CARe</p>
          </td>
          <td class="topic-column">For patients and families</td>
        </tr>

    </table>


您更喜欢使用代码片段来展示实际示例。 - undefined
2个回答

1
让我们看看出了什么问题:
myFunction实际上在每一行上进行搜索,但根据您的需求,它应该只在选定的类别上进行搜索。
在document ready中的逻辑也是错误的$(this).find("td:eq(1)").html().includes(inputValue.toString())。
我们如何修复它:
我们有一个名为getCheckedItems的函数,它返回一个数组,其中包含当前选中的复选框值,即类别。
getCheckedItems在document ready中调用,仅显示选定类别的行。文档准备代码也被简化了。
在myFunction中,还检查了相同的逻辑过滤器,只返回getCheckedItems函数返回的选定类别。
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>

     function getCheckedItems() {
        
        let checkboxValues = [];
        
        $('input[type="checkbox"]').each(function(index) {
            
            let inputValue = $(this).attr("value");
            
            if( $(this).is(':checked') && inputValue ){
                
                checkboxValues.push(inputValue);
            }
        });

        return checkboxValues;
    }

    function myFunction() {
        var input, filter, table, tr, td, i, txtValue;
        input = document.getElementById("myInput");
        filter = input.value.toUpperCase();
        table = document.getElementById("myTable");
        tr = table.getElementsByTagName("tr");

        for (i = 0; i < tr.length; i++) {
            td = tr[i].getElementsByTagName("td")[0];
            let htmlCategory = $(tr[i]).find("td:eq(1)").html();
            if (td) {
                txtValue = td.textContent || td.innerText;
                if (txtValue.toUpperCase().indexOf(filter) > -1 && getCheckedItems().includes(htmlCategory)) {
                    tr[i].style.display = "";
                } else {
                    tr[i].style.display = "none";
                }
            }
        }
    }

    $(document).ready(function() {
        $('input[type="checkbox"]').change(function() {

            $("tr").each(function() {

                let htmlCategory = $(this).find("td:eq(1)").html();
                if(getCheckedItems().includes(htmlCategory)) {
                    $(this).show(); // slice by n numbers here
                }
                else {
                    $(this).hide();
                }
            });
        });
    });

    function checkedAll() {
        console.log("All")
        var elements = this.form.getElementsByTagName('input');
        console.log(elements)
        // iterate and change status
        for (var i = elements.length; i--;) {
            if (elements[i].type == 'checkbox') {
                console.log(this)
                elements[i].checked = this.checked;
                $(elements[i]).trigger("change");
            }
        }
    }


    table#myTable {
            width: 800px;
    }


通过关键词或短语搜索:

<h3>Filter by category:</h3>

<label class="clickable">
    <input type="checkbox" name="cluster_ids" id="cluster_ids" onclick="checkedAll.call(this);" checked /> Select all</label><br>

<div style="float:left; width:33%; min-width:200px;">
    <label class="clickable">
        <input value="For attorneys" type="checkbox" name="cluster_ids" checked/> For attorneys</label><br>

    <label class="clickable">
        <input value="For clinicians" type="checkbox" name="cluster_ids" checked/> For clinicians</label><br>

    <label class="clickable">
        <input value="For patients and families" type="checkbox" name="cluster_ids" checked/> For patients and families</label><br>


    <!-- TABLE -->

    <table id="myTable">
        <tr>
            <th>
                <h1>Resource</h1>
            </th>
            <th>
                <h1>Category</h1>
            </th>
        </tr>

        <tr>
            <td>
                <h3>20 things patients can do to help prevent medical errors</h3>
                <p>Information for patients from the Agency for Healthcare Research and Quality (AHRQ) apologies</p>
            </td>
            <td class="topic-column">For patients and families</td>
        </tr>

        <tr>
            <td>
                <h3>Best practices for attorneys representing patients using CARe</h3>
                <p>How lawyers can best support patients during the CARe process</p>
            </td>

            <td class="topic-column">For attorneys</td>

        <tr>
            <td>
                <h3>Clinician CARe communication algorithm</h3>
                <p>Flow chart with examples of what to say and what not to say during conversations with patients and families</p>
            </td>
            <td class="topic-column">For clinicians</td>
        </tr>

        <tr>
            <td>
                <h3>Guidelines for handling medical adverse events: Enhancing safety through candid communication</h3>
                <p>Covers the seven aspects of response to adverse events: initial response, truth-telling, apologies, mediation, root cause analysis, compensation, and reporting</p>
            </td>
            <td class="topic-column">For clinicians</td>
        </tr>

        <tr>
            <td>
                <h3>Handout for patients</h3>
                <p>A patient-focused flyer that explains the elements of CARe</p>
            </td>
            <td class="topic-column">For patients and families</td>
        </tr>

    </table>

也许这个方法会起作用。然而,不说明你做了什么,使得这个答案对其他遇到同样问题的人毫无用处。 - undefined
@Wimanicesir,感谢您的评论,我已经从我的角度进行了核实,它完全满足了问题的要求。而且,它肯定对其他有类似需求的人也有帮助。请告诉我是什么原因让您给出了负面评价,这样我在发布答案之前可以更加谨慎。 - undefined
好的,另一个答案应该会给你一些启发。你应该用言辞表达出出了什么问题,以及你是如何改进/修复它的。这可以是一个像另一个答案那样的列表,也可以是代码中的注释。另一个人可能不会有完全相同的代码,但可能会犯类似的错误,所以他可以从你的方法中学习。 - undefined
1
@Wimanicesir 非常感谢您的热心建议。从现在开始,我会尽量包含出错的部分以及您是如何改进/修复的,还会尝试发布代码片段运行的内容。 - undefined
最后一个提示,我现在对你的问题进行了封锁,直到你编辑问题,所以即使我想取消投票,也无法做到。 - undefined
显示剩余3条评论

0

在这里,我对你的代码做了简单的修改。

  1. 当复选框隐藏时,我给tr添加了hidden-cat类,这样我们就可以知道这些项目是通过复选框隐藏的。
  2. 我修改了你的myFunction()函数,并将#myInput与输入事件绑定,而不是keyup事件,这样我就可以处理复制粘贴操作。
  3. 我还添加了hidden类,这样我们就可以知道项目是通过搜索字段隐藏的,当用户按下退格键或删除搜索关键字时,我们可以显示出来。
  4. 类似地,在你的// Select cluster部分,我通过if(inputValue !== undefined) {}检查是否为未定义。

注意:这只是一个概念验证示例。 你可能需要进行优化和异常处理。

$("#myInput").off("input").on("input", function() {
  var inputValue = $(this).val();
  if (inputValue === "") {
    $("tr:not(.header, .hidden-cat)").removeClass('hidden').show();
    return;
  }
  $("tr:not(.header,.hidden-cat)").addClass('hidden').hide();
  $("#myTable").find("tr:not(.header, .hidden-cat)").each(function() {
    let $this = $(this);
    if ($this.text().toLowerCase().indexOf(inputValue.toLowerCase()) > -1) {
      $this.removeClass('hidden').show();
    }
  });
});
src = "https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"

// Select cluster
$(document).ready(function() {
  $('input[type="checkbox"]').change(function() {
    var inputValue = $(this).attr("value");
    var checked = $(this)[0].checked;
    $("tr").each(function() {
      if (inputValue !== undefined) {
        if ($(this).find("td:eq(1)").html() !== undefined && $(this).find("td:eq(1)").html().includes(inputValue.toString())) {
          if (checked) {
            $(this).removeClass("hidden-cat").show(); // slice by n numbers here
          } else {
            $(this).addClass("hidden-cat").hide();
          }
        }
      }
    });
  });
});

function checkedAll() {
  //console.log("All")
  var elements = this.form.getElementsByTagName('input');
  //console.log(elements)
  // iterate and change status
  for (var i = elements.length; i--;) {
    if (elements[i].type == 'checkbox') {
      //console.log(this)
      elements[i].checked = this.checked;
      $(elements[i]).trigger("change");
    }
  }
}
table#myTable {
  width: 800px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!-- SEARCH -->

<h3>Search by keyword or phrase:</h3>
<input type="text" id="myInput" placeholder="Start typing to filter the table below" style="width:100%; transform: none;">


<!-- CHECKMARKS -->


<form action="" method="post" name="frm1" id="frm1">

  <h3>Filter by category:</h3>

  <label class="clickable">
<input type="checkbox" name="cluster_ids" id="cluster_ids" onclick="checkedAll.call(this);" checked /> Select all</label><br>

  <div style="float:left; width:33%; min-width:200px;">
    <label class="clickable">
<input value="For attorneys" type="checkbox" name="cluster_ids" checked/> For attorneys</label><br>

    <label class="clickable">
<input value="For clinicians" type="checkbox" name="cluster_ids" checked/> For clinicians</label><br>

    <label class="clickable">
<input value="For patients and families" type="checkbox" name="cluster_ids" checked/> For patients and families</label><br>


    <!-- TABLE -->

    <table id="myTable">
      <tr class="header">
        <th>
          <h1>Resource</h1>
        </th>
        <th>
          <h1>Category</h1>
        </th>
      </tr>

      <tr>
        <td>
          <h3>20 things patients can do to help prevent medical errors</h3>
          <p>Information for patients from the Agency for Healthcare Research and Quality (AHRQ)</p>
        </td>
        <td class="topic-column">For patients and families</td>
      </tr>

      <tr>
        <td>
          <h3>Best practices for attorneys representing patients using CARe</h3>
          <p>How lawyers can best support patients during the CARe process</p>
        </td>

        <td class="topic-column">For attorneys</td>

        <tr>
          <td>
            <h3>Clinician CARe communication algorithm</h3>
            <p>Flow chart with examples of what to say and what not to say during conversations with patients and families</p>
          </td>
          <td class="topic-column">For clinicians</td>
        </tr>

        <tr>
          <td>
            <h3>Guidelines for handling medical adverse events: Enhancing safety through candid communication</h3>
            <p>Covers the seven aspects of response to adverse events: initial response, truth-telling, apologies, mediation, root cause analysis, compensation, and reporting</p>
          </td>
          <td class="topic-column">For clinicians</td>
        </tr>

        <tr>
          <td>
            <h3>Handout for patients</h3>
            <p>A patient-focused flyer that explains the elements of CARe</p>
          </td>
          <td class="topic-column">For patients and families</td>
        </tr>

    </table>


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接