通过 JavaScript 过滤复选框列表的最小代码

发布于 2024-12-03 03:33:08 字数 782 浏览 1 评论 0原文

项目不需要任何 javascript 库,如 jQuery、Dojo、Prototype,所以我认为没有简单的方法。我想对这个问题有深入的答案,解释如何做到这一点。大多数人可能都知道,asp.net checkboxlist 会在 Flow RepeatLayout 中发出如下所示的标记。

<span>
<checkbox><label></br>
<checkbox><label></br>
<checkbox><label></br>
</span>

为了简单起见,我没有放置结束/结束标签。我们有一个用于搜索此复选框列表的文本框。现在出现了问题,

当用户在文本框中键入搜索词并隐藏不匹配的复选框+标签时,我将如何过滤复选框列表。

还有一些问题我想获得与上述相关的答案

  1. 是否有用于此目的的现成的独立脚本?

  2. 在提供搜索功能时,是否有解释故障的模式、文章、帖子以及需要记住的要点?像 onkeydown 这样的东西不这样做,

  3. 我现在的想法是拥有一个标签标签的缓存集合 innerHTML 然后循环每个标签并检查搜索词,当发现隐藏所有其他但仅显示匹配时。[我担心的是当列表太长时会发生什么,我认为每次按键循环都不是最好的主意]

欢迎您的建议、答案、解决方案、脚本

Project doesn't need any javascript libraries such as jQuery, Dojo, Prototype so there is no easy way i suppose. I would like to have in-depth answers for the question explaining how would one do this. As most of you might know asp.net checkboxlist emits a markup like below in Flow repeatLayout.

<span>
<checkbox><label></br>
<checkbox><label></br>
<checkbox><label></br>
</span>

i haven't put the ending/closing tags for simplicity. We have a textbox for searching through this list of checkbox.Now comes the question,

How would i Filter the checkboxlist when user types the search term in the textbox and hide the unmatched checkbox+label.

some more questions i would like getting answers for that are related to above

  1. Is there any ready made STANDALONE script for this purpose?

  2. Is there a pattern , article, post explaining the glitches, points to remember while providing search functionality? something like onkeydown don't do this,

  3. My Idea right now would be have a cached collection of label tags innerHTML then loop through each tag and check for search term, when found hide all others but show only matching.[My Concern is what will happen when list is too long, on every keypress looping is not the best idea i suppose]

Your suggestions, answers, solution, scripts are welcome

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

筱武穆 2024-12-10 03:33:08

该解决方案基于 Ktash 的答案。我之所以这么做是因为我想了解更多关于 javascript、DOM 导航和 RegExp 的知识。

我用“keydown”更改了“keypress”事件,因为前一个事件不会在退格/删除时触发,因此使用退格/删除删除所有字符仍然会过滤列表。

[默认.aspx]

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="RealtimeCheckBoxListFiltering.Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
  <title></title>
  <script type="text/javascript">
    window.onload = function () {
      var tmr = false;
      var labels = document.getElementById('cblItem').getElementsByTagName('label');
      var func = function () {
        if (tmr)
          clearTimeout(tmr);
        tmr = setTimeout(function () {
          var regx = new RegExp(document.getElementById('inputSearch').value);
          for (var i = 0, size = labels.length; i < size; i++)
            if (document.getElementById('inputSearch').value.length > 0) {
              if (labels[i].textContent.match(regx)) setItemVisibility(i, true);
              else setItemVisibility(i, false);
            }
            else
              setItemVisibility(i, true);
        }, 500);

        function setItemVisibility(position, visible)
        {
          if (visible)
          {
            labels[position].style.display = '';
            labels[position].previousSibling.style.display = '';
            if (labels[position].nextSibling != null)
              labels[position].nextSibling.style.display = '';
          }
          else
          {
            labels[position].style.display = 'none';
            labels[position].previousSibling.style.display = 'none';
            if (labels[position].nextSibling != null)
              labels[position].nextSibling.style.display = 'none';

          }
        }
      }

      if (document.attachEvent) document.getElementById('inputSearch').attachEvent('onkeypress', func);  // IE compatibility
      else document.getElementById('inputSearch').addEventListener('keydown', func, false); // other browsers
    };
  </script>
</head>
<body>
  <form id="form1" runat="server">
  <table>
    <tr>
      <td>
        <asp:TextBox runat="server" ID="inputSearch" ClientIDMode="Static" />
      </td>
    </tr>
    <tr>
      <td>
        <asp:CheckBoxList runat="server" ID="cblItem" ClientIDMode="Static" RepeatLayout="Flow" />
      </td>
    </tr>
  </table>
  </form>
</body>
</html>

[默认.aspx.cs]

using System;
using System.Collections.Generic;

namespace RealtimeCheckBoxListFiltering
{
    public partial class Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            cblItem.DataSource = new List<string>() { "qwe", "asd", "zxc", "qaz", "wsx", "edc", "qsc", "esz" };
            cblItem.DataBind();
        }
    }
}

This solution is based on Ktash's answer. I made it cause I want to learn more about javascript, DOM navigating and RegExp.

I changed "keypress" event with "keydown" since the previous doesn't trigger on backspace/delete so deleting all the characters with backspace/delete still left the list filtered.

[Default.aspx]

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="RealtimeCheckBoxListFiltering.Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
  <title></title>
  <script type="text/javascript">
    window.onload = function () {
      var tmr = false;
      var labels = document.getElementById('cblItem').getElementsByTagName('label');
      var func = function () {
        if (tmr)
          clearTimeout(tmr);
        tmr = setTimeout(function () {
          var regx = new RegExp(document.getElementById('inputSearch').value);
          for (var i = 0, size = labels.length; i < size; i++)
            if (document.getElementById('inputSearch').value.length > 0) {
              if (labels[i].textContent.match(regx)) setItemVisibility(i, true);
              else setItemVisibility(i, false);
            }
            else
              setItemVisibility(i, true);
        }, 500);

        function setItemVisibility(position, visible)
        {
          if (visible)
          {
            labels[position].style.display = '';
            labels[position].previousSibling.style.display = '';
            if (labels[position].nextSibling != null)
              labels[position].nextSibling.style.display = '';
          }
          else
          {
            labels[position].style.display = 'none';
            labels[position].previousSibling.style.display = 'none';
            if (labels[position].nextSibling != null)
              labels[position].nextSibling.style.display = 'none';

          }
        }
      }

      if (document.attachEvent) document.getElementById('inputSearch').attachEvent('onkeypress', func);  // IE compatibility
      else document.getElementById('inputSearch').addEventListener('keydown', func, false); // other browsers
    };
  </script>
</head>
<body>
  <form id="form1" runat="server">
  <table>
    <tr>
      <td>
        <asp:TextBox runat="server" ID="inputSearch" ClientIDMode="Static" />
      </td>
    </tr>
    <tr>
      <td>
        <asp:CheckBoxList runat="server" ID="cblItem" ClientIDMode="Static" RepeatLayout="Flow" />
      </td>
    </tr>
  </table>
  </form>
</body>
</html>

[Default.aspx.cs]

using System;
using System.Collections.Generic;

namespace RealtimeCheckBoxListFiltering
{
    public partial class Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            cblItem.DataSource = new List<string>() { "qwe", "asd", "zxc", "qaz", "wsx", "edc", "qsc", "esz" };
            cblItem.DataBind();
        }
    }
}
蛮可爱 2024-12-10 03:33:08
var tmr = false;
var labels = document.getElementsByTagName('label')
var func = function() {
    if (tmr) clearTimeout(tmr);
    tmr = setTimeout(function () {
        var regx = new Regex(inputVal); /* Input value here */
        for(var i = 0, size = labels.length; i < size; i++) {
            if(regx.match(labels[i].textContent || labels[i].innerText)) labels[i].style.display = 'block';
            else labels[i].style.display = 'none';
        }
    }, 100);
}
if (document.attachEvent) inputField.attachEvent('onkeypress', func);
else inputField.addEventListener('keypress', func, false);

并不完美,也不是完全完整,但它应该可以帮助您开始。在执行循环之前有 100 毫秒的延迟,因此它不会在每次按键时运行,但很可能在他们停止打字后运行。可能想根据您认为合适的情况稍微调整一下该值,但它为您提供了总体思路。另外,我没有设置 inputFieldinputVal 的变量,但我假设您已经知道如何获取这些变量。如果您的标签不是加载的静态列表,您可能希望每次都获取该列表。

var tmr = false;
var labels = document.getElementsByTagName('label')
var func = function() {
    if (tmr) clearTimeout(tmr);
    tmr = setTimeout(function () {
        var regx = new Regex(inputVal); /* Input value here */
        for(var i = 0, size = labels.length; i < size; i++) {
            if(regx.match(labels[i].textContent || labels[i].innerText)) labels[i].style.display = 'block';
            else labels[i].style.display = 'none';
        }
    }, 100);
}
if (document.attachEvent) inputField.attachEvent('onkeypress', func);
else inputField.addEventListener('keypress', func, false);

Not perfect, and not all the way complete, but it should get you started on it. There is a 100 millisecond delay before it performs the loop so that it won't run on every keypress, but likely just after they've stopped typing. Probably want to play with the value a bit as you see fit, but it gives you the general idea. Also, I didn't set the variables for inputField nor inputVal, but those I assume you would already know how to grab. If your labels are not a static list onload, you'll probably want to get the list every time.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文