Instantaneous search with DOM API and JS

Posted by admin at December 23, 2016

In this tutorial, we are going to look at how to instantaneously search a table using JavaScript. We can achieve this by using the value entered into a search text box to search the innerHTML property of all the rows in the table, toggling the style display property of rows or:

<tr></tr>

to and from none to null, depending on whether the string was found or not respectively.

Algorithm:

  1. User enters a value into the search text box.
  2. Javascript picks up the value using the onKeyUp or onKeyDown eventListener, and searches for the string in innerHTML property of all html elements specified by a given name.
  3. If the string is found in the innerHTML of an element, the element’s style.display attribute is set to ”.
  4. If not, the element’s style.display attribute is set to ‘none’, hiding said element.
  5. The code is going to loop through all the html elements with same name attribute as specified in the parameter passed to the onKeyUp or onKeyDown eventListener.

I will be using traditional javascript and simple event triggering. You can choose to implement this solution in jQuery, if you choose.

Setting up the search text box:

HTML Code to display the search text box

<input id="txt_src" name="txt_src" placeholder="search table..." />

Add the event listener,

<input id="txt_src" name="txt_src" placeholder="search table..."
    onkeyup="insta_src(this.value, 'tr_src');" />

Add a result counter where the number of rows displayed will be displayed after the search:

<input id="txt_src" name="txt_src" placeholder="search table..."
    onkeyup="insta_src(this.value, 'tr_src');" /><br>
  <span id="res_counter"></span>

We are going to use the onKeyUp event, i.e. perform the function insta_src(); whenever the user presses and releases a key. The function insta_src(); takes two parameters,

  1. The search value which we specified as this.value, the current value of select box after the key is pressed.
  2. The name of the html elements to search, specified as ‘tr_src’, <tr> being the tag for rows.

Lay down the insta_src() function


function insta_src(src_val, tr_name)
{
    var space_chr = ' ';

    // start the search result counter
    var res_count = 0;

    // get all the row elements to search
    var rows = document.getElementsByName(tr_name);

    // loop through all the rows and search

    // make sure the rows or elements are more than 0
    if (rows.length > 0)
    {

        for (i=0; i<rows.length; i++)
        {
            // define the search haystack:
            // i.e. the current row's
            // innerHTML property in lower case
            var haystack = src_pad + rows[i].innerHTML.toLowerCase();

            // define the needle: the input value also in lower
            // case
            var needle = src_val.toLowerCase();

            if (
                // if the needle is found in the haystack
                (haystack.search(needle) > 0)
                
                // and the needle is not a space, we want
                // alphanumeric characters in the search
                && (needle != space_chr)
            )
            {
                // set the style.display state as null:
                // i.e. to show the element
                dstate = '';

                // increment the search result counter
                res_count++;
            }
            else
            {
                // set the style.display state as none:
                // i.e. to hide the element
                dstate = 'none';

                // ensure that the needle is not null
                if (needle == '')
                {
                    // if so, reset the style.display
                    // state to null: show
                    dstate = '';
                }
            }

            // set the current row's style.display
            // attribute
            rows[i].style.display = dstate;

            // set the result counter
            res_counter.innerHTML = '';
            if (res_count > 0)
            {
                res_counter.innerHTML = res_count + ' results';
            }
        }
    }
}

Setting up the table:

I am going to use an array to populate the table using PHP. You can decide to do this using any programming language you want (Java, javascript, C#, Python, anything you prefer). Also instead of using arbitrary values for your array, you can load values from a database table such as MySQL, Oracle if you wish.

PHP


<?php
            
    // a list of fruits and vegetables
    $table_values = array(
        'Apple - Fruits', 'Apricot - Vegetables', 'Asparagus - Vegetables',
        'Aubergine - Fruits', 'Avocado - Fruits', 'Banana - Fruits',
        'Beetroot - Roots', 'Black-Eye Bean - Vegetables', 'Broad Bean - Legumes',
        'Broccoli - Vegetables', 'Brussels Sprout - Vegetables',
        'Butternut Squash - Vegetables', 'Carrots - Vegetables',
        'Cherry - Fruits', 'Clementine - Fruits', 'Courgette - Vegetables',
        'Date - Fruits', 'Elderberry - Fruits', 'Endive - Vegetables',
        'Fennel - Vegetales', 'Fig - Fruits', 'Garlic - Vegetables',
        'Grape - Fruits', 'Green Beans - Vegetables', 'Guava - Fruits',
        'Haricot Beans - Vegetables', 'Honeydew Melon - Vegetables',
        'Iceberg Lettuce - Vegetables', 'Jerusalem Artichoke - Vegetables',
        'Kiwi Fruit - Fruits', 'Leek - Fruits', 'Lemon - Fruits',
        'Mango - Fruits', 'Melon - Fruits', 'Mushroom - Vegetables',
        'Nectarine - Fruits', 'Nut - Nuts', 'Olive - Fruits',
        'Orange Fruits', 'Pea - Vegetables', 'Peanut Nuts',
        'Pear - Fruits', 'Pepper - Spices', 'Pineapple - Fruits',
        'Pumpkin Vegetables', 'Quince - Fruits', 'Radish - Fruits',
        'Raisins - Fruits', 'Rhubarb - Vegetables', 'Satsuma Fruits',
        'Strawberry - Fruits', 'Sweet Potato - Roots', 'Tomato - Vegetables',
        'Turnip - Vegetables', 'Ugli Fruit - Fruits', 'Victoria Plum - Fruits',
        'Vine Leaf - Vegetables', 'Watercress - Vegetables', 'Watermelon - Vegetables',
        'Yam - Roots', 'Zucchini - Vegetables'
    );
            
?>
<table width="30%">
    <thead>
        <tr>
            <td width="10%"><b>SN</b></td>
            <td width="60%"><b>Food Name</b></td>
            <td width="30%"><b>Food Type</b></td>
        </tr>
    </thead>
    <tbody>
        <?php for ($i=0; $i<count($table_values); $i++) { ?>
        <tr name="tr_src">
            <td<>?php echo $i + 1; ?></td>
            <td>
                <?php echo str_replace(' - ', '</td><td>', $table_values[$i]); ?>
            </td>
        </tr>
        <?php } ?>
    </tbody>
    <tfoot><tr><td colspan="3"></td></tr></tfoot>
</table>

This is a table of fruits and vegetables with the classifications. Notice the name of each row or

element has been set to ‘tr_src’ so that the onKeyUp event can use this in the parameter as the haystack.

 

Putting it all together:

index.php





insta_src.js


function insta_src(src_val, tr_name) {

    var space_chr = ' ';

    // start the search result counter
    var res_count = 0;

    // get all the row elements to search
    var rows = document.getElementsByName(tr_name);

    // make sure the rows or elements are more than 0
    if (rows.length > 0)
    {

        // loop through all the rows and search
        for (i=0; i<rows.length; i++)
        {
            
            // define the search haystack: i.e. the current
            // row's innerHTML property in lower case
            var haystack = space_chr + rows[i].innerHTML.toLowerCase();

            // define the needle: the input value also in
            // lower case
            var needle = src_val.toLowerCase();
            
            if (
                
                // if the needle is found in the haystack
                (haystack.search(needle) > 0)
                
                // and the needle is not a space, we want
                // alphanumeric characters in the search
                && (needle != space_chr)
                
            )
            {
                
                // set the style.display state as null:
                // i.e. to show the element
                dstate = '';
                
                // increment the search result counter
                res_count++;
            }
            else
            {
                // set the style.display state as none:
                // i.e. to hide the element
                dstate = 'none';

                // ensure that the needle is not null
                if (needle == '')
                {
                    // if so, reset the style.display
                    // state to null: show
                    dstate = '';
                }
            }

            // set the current row's style.display attribute
            rows[i].style.display = dstate;
            
            // set the result counter
            res_counter.innerHTML = '';
            if (res_count > 0)
            {
                res_counter.innerHTML = res_count + ' results';
            }
            
        }
    }
}


Notes:

You can also choose to use the className attribute of the rows instead of the name attribute. Thus can be done by replacing:

var rows = document.getElementByName(tr_name);

with

var rows = document.getElementByClassName(tr_name);

in the insta_src.js file and replacing

<tr name="tr_src">

with

<tr class="tr_src">

in the index.html file.

This allows the function to select all the rows with class name ‘tr_src’ and search for the string the selected row’s innerHTML values.

Putting it all together

Here is the complete application, neatly packed for download.

   0 likes

Suggested Read