Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Smallest code possible to filter checkboxlist through javascript

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

like image 851
Deeptechtons Avatar asked Sep 06 '11 07:09

Deeptechtons


2 Answers

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();
        }
    }
}
like image 165
Răzvan Flavius Panda Avatar answered Oct 31 '22 13:10

Răzvan Flavius Panda


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.

like image 40
LoveAndCoding Avatar answered Oct 31 '22 13:10

LoveAndCoding