【问题标题】:I want to improve this JavaScript code which Filters a list of CheckBoxes by ''value="我想改进这个通过 ''value=" 过滤 CheckBoxes 列表的 JavaScript 代码
【发布时间】:2021-04-09 01:28:18
【问题描述】:

在我的 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 或复选框中的另一个标签过滤它时,它会按其值过滤复选框(因为我在“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 的复选框,如果我写 Pablo,则相同,但是如果我写例如“Mat”或“Pabl”,这不会找到我两者中的任何一个;当我想要这样时,当我搜索“Pabl”时,它会向我显示所有包含用字符序列“Pabl”编写的内容的 CheckBox,唯一的例外是脚本考虑空格,所以如果我寻找 Jan ,它找到我“Jan Dos”,因为“Jan”和“Dos”这两个词之间有一个空格分隔。 但正如我所说,我希望它的工作方式是在我搜索“Pabl”时显示所有包含序列“Pabl”的复选框。

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

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

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 代码来完成这一切,但没有一个包含我提到的所有功能,而我喜欢原始代码的简单之处在于它允许我轻松控制数据,因为我很容易在控制器中获取 Checkbox 值;如果Div代码是这样的。

【问题讨论】:

    标签: javascript jquery asp.net-mvc asp.net-core checkbox


    【解决方案1】:

    我建议您比较每个复选框旁边显示的文本...因为这才是真正要搜索的内容。不要为此使用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 },
      { 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

    【讨论】:

    • 非常感谢,这正是我所需要的,你救了我的命!!!我可以为 value/id 问题想出一个解决方案,所以不要担心那部分!
    • 太棒了!但在所有情况下,不要使用id 来携带值...看看data attribute 和jQuery .data() 也许... ;)
    • 万一,你在吗?我知道已经有一段时间了,但最近我意识到最终的脚本有一个小错误,而其他一切都很好。错误就是这样,如果您搜索某些内容以过滤数据,然后选择一个复选框,然后在输入字段中编写其他内容以再次搜索某些内容,则取消选择您之前选择的复选框,这确实如果在字段为空时按搜索以再次显示所有复选框,则不会发生。也许您可以再次提供帮助,因为这只是一个小问题(=
    • 我自愿取消选中 $(".tipoo:hidden").prop("checked", false);.. 的所有隐藏复选框。如果您想保留选中的复选框,即使它们因搜索而被隐藏。
    • 是的!我想保留选中的复选框,即使它们由于搜索而被隐藏。唯一应该忽略隐藏框的是 ALL 复选框。
    猜你喜欢
    • 2011-11-11
    • 2021-12-30
    • 2013-05-06
    • 2020-07-03
    • 1970-01-01
    • 2013-12-21
    • 1970-01-01
    • 2023-03-23
    • 2023-01-23
    相关资源
    最近更新 更多