bootstrap 4, list-group, search all BUT SHOW LIMITED LINES

352 views Asked by At

I have a script, it shows database-rows as list-group with a searchbar. Yes, it works.

But the database has about 10.000 rows. I want to show only the first 5 rows in the list-group, but I want to use for search all rows.

    <ul class="list-group" id="myList">
   <?
      if ($result = $conn->query($sql)) {
      
      /* fetch object array */
      while ($row = $result->fetch_row()) {
      if ($show_row < 6) echo "<li class='list-group-item'>$row[0]</li>"; // show row
      if ($show_row > 5) echo "<li class='list-group-item'>$row[0]</li>"; // hide row, but use it for search
          $show_row++;
      }
      }
      ?>
</ul>

<script>
$(document).ready(function(){
  $("#myInput").on("keyup", function() {
    var value = $(this).val().toLowerCase();
    $("#myList li").filter(function() {
      $(this).toggle($(this).text().toLowerCase().indexOf(value) > -1)
    });
  });
});
</script>  

Thanks for answers ;-)

1

There are 1 answers

3
Rob Ruchte On

The easiest thing to do with what you have is use CSS display:none on rows that you do not want to initially display, then reset to the original state if there is no input. I would also pre-digest the searchable values and insert them as data attributes in the li tags, so that you don't have to calculate that in real time for each item during the search.

<ul class="list-group" id="myList">
    <?php
    if ($result = $conn->query($sql))
    {
        /* fetch object array */
        $i = 0;
        while ($row = $result->fetch_row())
        {
            /*
                Pre-digest the searchable string so we don't have to do this in JS for every comparison
                Set this as a data attribute in the li tag
                If you need something more than just strtolower, think about encapsulating this in a function.
            */
            $currSearchableValue = strtolower($row[0]);

            /*
             * Set any rows after the first 5 to display: none
             * Alternatively, you could just insert them all into the page displayed, then use JS to hide the rows,
             * but the user would see the list briefly, and the page contents would jump, which is amateur hour stuff.
             */
            $currStyleAttr = ($i>=5) ? ' style="display: none"':'';

            echo '<li class="list-group-item" data-searchable="'.$currSearchableValue.'"'.$currStyleAttr.'>'.$row[0].'</li>';
            $i++;
        }
    }
    ?>
</ul>

<script>
    $(document).ready(function ()
    {
        var $listItems = $("#myList li");
        $("#myInput").on("keyup", function ()
        {
            var value = $(this).val().toLowerCase();

            // Only search if we have input, otherwise reset the list
            if(value.length>0)
            {
                $listItems.filter(function()
                {
                    $(this).toggle($(this).data("searchable").indexOf(value) > -1)
                });
            }
            else
            {
                $listItems.hide().slice(0, 5).show();
            }
        });
    });
</script>