Наименьший возможный код для фильтрации списка флажков через JavaScript - PullRequest
6 голосов
/ 06 сентября 2011

Проекту не нужны никакие библиотеки javascript, такие как jQuery, Dojo, Prototype, поэтому я полагаю, что нет простого способа. Я хотел бы получить подробные ответы на вопрос, объясняющий, как можно это сделать. Как многие из вас могут знать, asp.net checkboxlist испускает разметку, как показано ниже в Flow repeatLayout.

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

Для простоты я не ставил закрывающие / закрывающие теги. У нас есть текстовое поле для поиска в этом списке. Теперь возникает вопрос,

Как мне отфильтровать список флажков, когда пользователь вводит поисковый запрос в текстовое поле, и скрывать непревзойденный флажок + метка.

еще несколько вопросов, на которые я хотел бы получить ответы, которые относятся к выше

  1. Есть ли готовый сценарий STANDALONE для этой цели?

  2. Есть ли шаблон, статья, сообщение, объясняющее глюки, моменты, которые следует помнить при предоставлении функции поиска? что-то вроде onkeydown don't do this,

  3. Моя идея сейчас состоит в том, чтобы иметь кешированную коллекцию тегов меток innerHTML, затем проходить по каждому тегу и проверять поисковый запрос, когда найдены, скрывают все остальные, но показывают только совпадение. [Моя забота - это то, что произойдет если список слишком длинный, то при каждом нажатии клавиш не лучшая идея, я полагаю]

Ваши предложения, ответы, решения, сценарии приветствуются

Ответы [ 2 ]

7 голосов
/ 07 сентября 2011

Это решение основано на ответе Кташа. Я сделал это потому, что хочу узнать больше о JavaScript, навигации по DOM и RegExp.

Я изменил событие «нажатие клавиши» на «keydown», так как предыдущий не срабатывает при возврате / удалении, поэтому удаление всех символов с возвратом / удалением все еще оставляет список отфильтрованным.

[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();
        }
    }
}
7 голосов
/ 06 сентября 2011
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 миллисекунд, поэтому он не запускается при каждом нажатии клавиш, но, скорее всего, сразу после того, как они перестали печатать. Возможно, вы захотите немного поиграть со значением, как считаете нужным, но это дает вам общее представление. Кроме того, я не установил переменные для inputField и inputVal, но те, которые, как я полагаю, вы уже знаете, как получить. Если ваши ярлыки не являются статическим списком при загрузке, вы, вероятно, захотите получать список каждый раз.

...