Search code examples
javascriptjqueryjquery-mobile

How to filter a list and then remove the results from it, using javascript


I have a list that I'm trying to filter, and then remove the filtered results. I found a ready made solution for the filtering in w3schools, but I'm having trouble with removing lines.

My html is here:

<body>
    <ul id="project-list">
        <li><a href="#">Please please me</a></li>
        <li><a href="#">With the Beatles</a></li>
        <li><a href="#">A Hard Day's Night</a></li>
        <li><a href="#">Beatles for Sale</a></li>
        <li><a href="#">Help!</a></li>
        <li><a href="#">Rubber Soul</a></li>
        <li><a href="#">Revolver</a></li>
        <li><a href="#">Sgt. Pepper's Lonely Hearts Club Band</a></li>
        <li><a href="#">The Beatles (The White Album)</a></li>
        <li><a href="#">Yellow Submarine</a></li>
        <li><a href="#">Abbey Road</a></li>
        <li><a href="#">Let It Be</a></li>
    </ul>

    <div data-role="footer" class="ui-grid-a" data-position="fixed">

        <div id="myNavbar" data-role="navbar" class="navbar">
            <div class="ui-block-a" style="width:auto">
                <button id="remove" onclick="listDelete">Remove</button>
            </div>

            <script>
            $("button").click(function () {
                $("li").remove(":contains('Beatles')");
            });
            </script>

            <div class="ui-block-b" style="width:70%">
                <input type="text" id="search-input" onkeyup="listFilter()" placeholder="Filter list...">
            </div>
        </div>
    </div><!--/footer-->

The filtering function is this

function listFilter() {
// Declare variables
var input, filter, ul, li, a, i;
input = document.getElementById('search-input');
filter = input.value.toUpperCase();
ul = document.getElementById("project-list");
li = ul.getElementsByTagName('li');

for (i = 0; i < li.length; i++) {
    a = li[i].getElementsByTagName("a")[0];
    if (a.innerHTML.toUpperCase().indexOf(filter) > -1) {
        li[i].style.display = "";
    } else {
        li[i].style.display = "none";
    }
}
}

The above code makes the button delete every line containing the word "Beatles". I'm trying to remove the lines that contain whatever goes into search-input, preferably non-case sensitive (just like the filtering). Ideally, I want this to not work when the filter textbox is empty, so that an accidental click on the remove button won't delete the whole list.

I'm using jquery-2.1.1 and jqm-1.4.4


Solution

  • Based on diabolic's answer and Highway Of Life's icontains expression, the non case sensitive way to do this is the following:

    Load the following two in your header, in one or two separate files:

    function listDelete(){
        $("button").click(function () {
            var input = $("#search-input").val();
                if (input) $("li").remove(":icontains('" +input+ "')");
        });
    }
    

    // non-case sensitive contains expression
    jQuery.expr[':'].icontains = function(a, i, m) {
        return jQuery(a).text().toUpperCase()
        .indexOf(m[3].toUpperCase()) >= 0;
    };
    

    Then your button should be like this:

    <button id="remove" onclick="listDelete()">Remove</button>