0

I have just managed to get this table filter to work, but so far it only filters on one column (the hard coded one). I would like to prevent hardcoding and make the filter work on all columns at the same time. Could anyone help me get that to work?

I have tried using a double forloop to loop through all 6 columns but that did not seem to work.


JQuery

$(document).ready(function () {
            $('#myInput').keyup(function() {
                // Declare variables 
                var input, filter, table, tr, td, i;
                input = document.getElementById("myInput");
                filter = input.value.toUpperCase();
                table = document.getElementById("myTable");
                tr = table.getElementsByTagName("tr");

                // Loop through all table rows, and hide those who don't match the search query
                for (i = 0; i < tr.length; i++) {
                    td = tr[i].getElementsByTagName("td")[6]; // This is the hardcoded column

                    if (td) {
                        if (td.innerHTML.toUpperCase().indexOf(filter) > -1) {
                            tr[i].style.display = "";
                        } else {
                            tr[i].style.display = "none";
                        }
                    }
                }
            });
    });

HTML:

<table id="myTable">
<tr class="header">
    <th>Id</th>
    <th>Activity Name</th>
    <th>Description</th>
    <th>Capacity</th>
    <th>Start Time</th>
    <th>End Time</th>
    <th>Main Event</th>
    <th>Location</th>
    <th>Price</th>
    <th> </th>
    <th> </th>
</tr>

@foreach (Activity a in Model.ActivitiesList)
{
    if (a != null)
    {
        <tr>
            <td>@a.Id</td>
            <td>@a.Name</td>
            <td>@a.Description</td>
            <td>@a.Capacity</td>
            <td>@a.StartTime</td>
            <td>@a.EndTime</td>
            <td>@Model.GetSubjectById(a.SubjectId)</td>
            <td>@Model.GetLocationById(a.LocationId)</td>
            <td>@a.Price</td>
            <td>
                @Html.ActionLink(linkText: "Edit",
             actionName: "EditEvent",
             controllerName: "Dashboard",
             routeValues: new { id = a.Id, subjectId = a.SubjectId },
             htmlAttributes: new { @class = "icon-1 info-tooltip", @Title = "Edit" })
            </td>

            <td>
                @Html.ActionLink(
               "Remove",
               "RemoveEvent",
               new { id = a.Id, subjectId = a.SubjectId },
               new { onclick = "return confirm('Are you sure you wish to delete this activity?');" }
             )
            </td>
    </tr>
    }
    else
    {
        continue;
    }

}

Maistrenko Vitalii
  • 994
  • 1
  • 8
  • 16
Teije
  • 545
  • 1
  • 8
  • 16
  • Have you considered using jQuery DataTables plugin for the filtering purpose? https://datatables.net/ – Aamir Apr 12 '18 at 14:25
  • I have, but since it's for a school assignment I'd be better if I would implement it myself. I think the teacher would appreciate that more than implementing something someone has already made. – Teije Apr 12 '18 at 14:28

1 Answers1

1

You should definitely consider jqGrid or datatables (as suggested in comments), but since you already use jQuery, for your current code this should work:

// Loop through all table rows, and hide those who don't match the search query
for (i = 0; i < tr.length; i++) {
    var foundCells = $(tr[i]).find("td:contains(" + filter + ")");
    if (foundCells.length == 0) {
        $(tr[i]).hide();
    } else {
        $(tr[i]).show();
    }
}

Note that this does case-sensitive search. If you need case-insensitivity, check out this answer on how to have case-insensitive :contains.

Andrei
  • 55,890
  • 9
  • 87
  • 108
  • This works! Awesome thanks! Is this the right way to specify only the correct rows to be filtered? The table headers disappear with the current solution. $(tr[i].activity-row).hide(); – Teije Apr 12 '18 at 14:48