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
Is there any ready made STANDALONE script for this purpose?
Is there a pattern , article, post explaining the glitches, points to remember while providing search functionality? something like onkeydown don't do this,
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
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();
}
}
}
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With