我想改进这个 JavaScript 代码,它通过 ''value="

问题描述

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

@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 个 CheckBoxes 等于我数据库中 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>

这段代码生成了选择所有值的 ALL 复选框,以及允许过滤它们的搜索按钮,但它有以下问题(因为基本上 javascript 代码不能按照我希望的方式工作)。

1) 当我希望它通过 Id 或 CheckBox 中的另一个标签过滤它时,这会按其值过滤复选框(因为我在“value=”中拥有的是我需要发送到控制器,而“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”编写的内容的 CheckBox,唯一的例外是脚本考虑了空格,因此如果我查找 Jan ,它会找到我“Jan Dos”,因为“Jan”和“Dos”这两个词之间有空格分隔。 但正如我所说,我希望它的工作方式是在我搜索“Pabl”时向我展示包含序列“Pabl”的所有复选框。

3) ALL 按钮始终选择所有内容

JavaScript 代码现在的工作方式是,如果我过滤数据,然后按 ALL,所有复选框都会被选中,即使是那些隐藏的复选框,如果单击 ALL 并且数据被过滤,我希望这样做,这只会选择所有通过过滤器的复选框(非隐藏的)。

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

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 代码吗?

我在互联网上寻找替代的 Javascript 代码来完成所有这些,但没有一个包含我提到的所有功能,我喜欢原始代码的简单性是它允许我轻松控制数据,因为我很容易在控制器中获取 CheckBox 值;如果Div代码是这样的。

解决方法

我建议您比较每个复选框旁边显示的文本...因为这才是真正要搜索的内容。不要为此使用 idid 必须唯一且不能包含空格。所以使用 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 },Id: 7,Roo: 1250 },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