我想改进此 JavaScript 代码,该代码按“值=”过滤复选框列表

I want to improve this JavaScript code which Filters a list of CheckBoxes by ''value="

在我的 Asp.Net 核心应用程序的视图中,我有一个与此类似的代码:

@model Color.Models.AM

<div class="container">
    <div class="card level-3">
        <h4>AM</h4>
        <hr />
        <div class="row">
            <div class="col-md-4">
                <form asp-action="Create">
                    <div>
                        <input id="txt" type="text" value="" />
                        <input id="btn" type="button" value="Search" />
                    </div>
                    <div class="form-group">
                        <input id="cboAll" type="checkbox" value="CheckAll / unCheck" />
                        ALL<br />
                        <div class="wrapper">
                            @foreach (var cm in Model)
                            {
                                <div><input id=@cm.Name type="checkbox" name="selectedCdos" value=@cm.Id class="tipoo" />@cm.Name Roo: @cm.Roo</div>
                            }
                        </div>
                    </div>
                    <div class="form-group">
                        <input type="submit" value="Create" class="btn btn-primary" />
                    </div>
                </form>
            </div>
        </div>
    </div>
</div>

<style>
    .wrapper {
        width: 500px;
        height: 200px;
        overflow-y: scroll;
        overflow-x: hidden;
    }

    .card {
        background-color: #fff;
        border-radius: 10px;
        margin: 10% auto;
        position: relative;
        padding: 34px;
        color: #444;
        cursor: pointer;
        overflow-x: auto;
    }
        .card.level-3:hover:before {
            box-shadow: 0 0 80px #999999;
        }
</style>

重要的是简单理解,这会生成数量为N的CheckBox,等于我数据库中AM实体的​​数量,它使用AM的属性Id作为每个CheckBox的值。

模型的代码是这样的:

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading.Tasks;

namespace Color.Models
{
    public class AM
    {
        [key]
        public int Id { get; set; }
        [Required]
        public string Name { get; set; }
        [Required]
        public int Roo { get; set; }
    }
}

最后是一张视图的图片: pic of the view

所有这一切都工作得很好,没有问题,我检查的复选框被发送到控制器,它用所选的值做事。

我需要帮助,但我遇到了问题,但是,视图末尾的以下JavaScript代码:

<script src="https://code.jquery.com/jquery-3.1.1.js"></script>
<script type="text/javascript">
    $(function () {
        $("#cboAll").click(function () {
            if ($(this).is(":checked")) {
                $(".tipoo").prop('checked', true);
            }
            else {
                $(".tipoo").prop('checked', false);
            }
        });
        $("input[id*=btn]").click(function () {
            var searchvalue = $("input[id*=txt]").val();
            if (searchvalue != "") {
                $(".tipoo").each(function () {
                    if ($(this).val() == searchvalue) {
                        $(this).show();
                    }
                    else {
                        $(this).hide();
                        $(this.nextSibling).wrap('<span style="display:none"></style>');
                    }
                })
            }
            else {
                $("#cboAll,.tipoo").show();
            }
        })
    })
</script>

此代码生成 select 所有值的 ALL Checkbox,以及允许过滤它们的搜索按钮,但它有以下问题(因为基本上 javascript 代码没有按照我希望的方式工作)。

1) 当我希望它通过 Id 或 Checkbox 中的另一个标签过滤它时,这会按其值过滤复选框(因为我在“值= " 是我需要发送给控制器的内容,而 "Id" 可以是视图显示的文本。

现在假设我将“value=@cm.Id”更改为“value=@cm.Name”以测试搜索过滤器的工作原理,在这种情况下会出现以下问题:

2) 该代码仅过滤完全匹配的数据,而这不是我想要的。

Pic of the filter working (search button) and showing how it finds me the Checkbox with the value "Pablona"

Pic that shows that if I search for "Pabl" it finds nothing.

例如,如果输入“Mateo”并按下搜索按钮;好的,视图只显示 Mateo 的 CheckBox,如果我写 Pablo 也是一样,但是如果我写例如“Mat”或“Pabl”,这两个都找不到我;当我想要搜索“Pabl”时,它会向我显示所有包含用字符序列“Pabl”编写的内容的复选框,唯一的例外是脚本考虑 spaces,所以如果我查找 Jan,它会找到我“Jan Dos”,因为单词 'Jan' 和 'Dos' 之间有 space 分隔。 但正如我所说,我希望它的工作方式是在我搜索“Pabl”时向我显示包含序列“Pabl”的所有复选框。

3) ALL 按钮总是 select 一切。

JavaScript 代码现在的工作方式是,如果我过滤数据,然后按 ALL,所有复选框都会被 selected,即使是那些隐藏的,当我想就像这样,如果单击“全部”并过滤数据,则只有 select 所有通过过滤器的复选框(未隐藏的)。

4) 如果我第二次单击搜索按钮,复选框的文本就会消失。

Pic showing this problem, because the code changes the value of a div to hidden, and then doesn't return it to how it was before.

真的有人能帮我解决这 4 个问题,并改进我的 Javascript 代码吗?

我已经在 Internet 上寻找替代的 Javascript 代码来完成这一切,但是 none 包括我提到的所有功能,我喜欢我的原始代码的简单性是它让我可以轻松控制数据,因为我很容易在控制器中获取 Checkbox 值;如果Div代码是这样的

我建议您比较每个复选框旁边显示的文本...因为这才是真正要搜索的内容。不要为此使用 idid 必须是唯一的,不能包含 space。所以 id=@cm.Name 是超级错误的。

因此在 .each() 循环中,您将比较 searchvalue(小写)与“父 div 文本”(也小写)。此外,为了允许部分匹配,您将检查该文本中的 indexOf()searchvalue

关于确保不选中隐藏的复选框,:visible 选择器很有用。

见下文:

// Feaking your @foreach loop
let Model = [
  { Name: "12 Pablo Usuario", Id: 1, Roo: 333 },
  { Name: "A111", Id: 2, Roo: 12345678 },
  { Name: "AA", Id: 3, Roo: 123456 },
  { Name: "AAAAA", Id: 4, Roo: 12345 },
  { Name: "DF", Id: 5, Roo: 1251 },
  { Name: "DFD", Id: 6, Roo: 1246 },
  { Name: "DFD", Id: 7, Roo: 1250 },
  { Name: "DFD", Id: 8, Roo: 1249 }
];

Model.forEach(function (cm, index) {
  $(".wrapper").append(
    $(
      `<div><input id="check_${cm.Id}" type="checkbox" name="selectedCdos" value="${cm.Id}" class="tipoo" /> ${cm.Name} Roo: ${cm.Roo}</div>`
    )
  );
});
// END fake...

$(function () {
  $("#cboAll").click(function () {
    if ($(this).is(":checked")) {
      $(".tipoo:visible").prop("checked", true);  // :visible is to ensure the hidden checkboxes wont be checked.
    } else {
      $(".tipoo").prop("checked", false);
    }
  });
  $("input[id*=btn]").click(function () {
    var searchvalue = $("input[id*=txt]").val().toLowerCase(); // Have the search value all lowercase
    if (searchvalue != "") {
      
      // Script change is here
      $(".tipoo").each(function () {
        let parentDiv = $(this).parent("div")
        parentDiv.toggle((parentDiv.text().toLowerCase().indexOf(searchvalue)>-1))
      });
      
      // Unchecking the hidden checkboxes
      $(".tipoo:hidden").prop("checked", false);
      
    } else {
      $("#cboAll,.tipoo").parent("div").show();
    }
  });
});
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.bundle.min.js"></script>

<div class="container">
  <div class="card level-3">
    <h4>AM</h4>
    <hr />
    <div class="row">
      <div class="col-md-4">
        <form asp-action="Create">
          <div>
            <input id="txt" type="text" value="" />
            <input id="btn" type="button" value="Search" />
          </div>
          <div class="form-group">
            <input id="cboAll" type="checkbox" value="CheckAll / unCheck" /> ALL
            <br />
            <div class="wrapper">
              <!-- Your @foreach loop is feaked by JS below -->
            </div>
          </div>
          <div class="form-group">
            <input type="submit" value="Create" class="btn btn-primary" />
          </div>
        </form>
      </div>
    </div>
  </div>
</div>

<style>
  .wrapper {
    width: 500px;
    height: 200px;
    overflow-y: scroll;
    overflow-x: hidden;
  }
  
  .card {
    background-color: #fff;
    border-radius: 10px;
    margin: 10% auto;
    position: relative;
    padding: 34px;
    color: #444;
    cursor: pointer;
    overflow-x: auto;
  }
  
  .card.level-3:hover:before {
    box-shadow: 0 0 80px #999999;
  }
</style>

CodePen