Jwan622
Jwan622

Reputation: 11639

Javascript filtering on keyup

Here is my current HTML table:

<table class="table table-index">
    <thead>
        <tr class="filters">
            <th><input type="text" id="search_table" class="form-control company-id" placeholder="ID"></th>
            <th><input type="text" id="search_table" class="form-control" placeholder="Organization"></th>
            <th><input type="text" id="search_table" class="form-control" placeholder="Contact"></th>
            <th><input type="text" id="search_table" class="form-control" placeholder="Title"></th>
            <th><input type="text" id="search_table" class="form-control" placeholder="City"></th>
            <th><input type="text" id="search_table" class="form-control" placeholder="State"></th>
            <th><input type="text" id="search_table" class="form-control" placeholder="email"></th>
            <th><input type="text" id="search_table" class="form-control" placeholder="contacted"></th>
            <th><input type="text" id="search_table" class="form-control" placeholder="hiring"></th>
            <th><input type="text" id="search_table" class="form-control" placeholder="hire_count"></th>
            <th>
                <div class="checkbox-inline">
                    <input type="checkbox" id="checkbox1" class="large" data-label-prepend="prefix">
                        <label for="checkbox1">Contacted</label>
                </div>
             </th>
        </tr>
    </thead>


    <tbody>
        <% @companies.each do |company| %>
        <tr>
            <td class="id"><%= company.id %></td>
            <td class="Organization"><%= link_to company.organization,
                    admin_company_path(company.id) %></td>
            <td class="contact"><%= company.name %></td>
            <td class="contact-title"><%= company.title %></td>
            <td class="city"><%= company.city %></td>
            <td class="state"><%= company.state %></td>
            <td class="email"><%= company.email %></td>
            <td class="contacted"><%= company.status %></td>
            <td class="hiring"><%= company.hiring %></td>
            <td class="hire_count"><%= company.hire_count %></td>
        </tr>
        <% end %>
    </tbody>
</table>

Here is my table_filtering.js file:

$(document).ready(function() {
    if ($(".table-index").length > 0 ) {
        $('#search_table').keyup(function() {
            searchByColumn($(this).val());
        });

        function searchByColumn(searchVal) {
            var table = $('.table-index')
            table.find('tr').each(function(index, row){
                var allDataPerRow = $(row).find('td');
                if (allDataPerRow.length > 0) {
                    var found = false;
                    allDataPerRow.each(function(index, td) {
                        var regExp = new RegExp(searchVal, "i");

                        if(regExp.test($(td).text())) {
                            found = true
                            return false;
                        }
                  });

                  if(found === true) {
                      $(row).show();
                  }else {
                      $(row).hide();
                  }
                }
            });
        }
    }
});

The problem is that I'm only filtering by the first $("#search_table") which is the ID column but I'm not filtering by any of the text boxes. What can I do so that all of the text boxes are filtering? I also want users to be able to filter by multiple text boxes. So if a user puts in input in the city and title, results only by the city and title will show.

Also, is my current filtering compatible with will_paginate? Meaning... will results on other pages be searched through?

Upvotes: 2

Views: 4044

Answers (2)

Samurai
Samurai

Reputation: 3729

I'm getting all the inputs with class .form-control and pass them to the function. Then check if the input has a value, if not it won't be taken into account. For each input only the same column index is searched (e.g. for id I only filter the td with index=0 and so on. For each input rows not matching the value are given a class hide which has style of display: none;.

jsfiddle DEMO

jQuery:

if ($(".table-index").length > 0) {
    $('.form-control').keyup(function () {
        var inputs = ($('.form-control'));
        searchByColumn(inputs);
    });

    function searchByColumn(inputs) {
        $('.table-index tr').removeClass('hide');
        var table = $('.table-index');
        inputs.each(function () {
            var idx = $(this).parent().index();
            var searchVal = $(this).val();
            if (searchVal != "") {
                table.find('tr').not('.hide').each(function (index, row) {
                    var allDataPerRow = $(row).find('td').eq(idx);
                    if (allDataPerRow.length > 0) {
                        var found = false;
                        allDataPerRow.each(function (index, td) {
                            var regExp = new RegExp(searchVal, "i");
                            if (regExp.test($(td).text())) {
                                found = true;
                                return false;
                            }
                        });
                        if (found === true) {
                            $(row).removeClass('hide');
                        } else {
                            $(row).addClass('hide');
                        }
                    }
                });
            }
        });
    }
}

CSS:

tr.hide {
    display: none;
}

Sidenote:

  • IDs should be unique, try to avoid giving different elements the same ID.

Upvotes: 1

dfsq
dfsq

Reputation: 193261

In your case all you need to do is to change from using ids to classes.

<tr class="filters">
    <th>
        <input type="text" class="search_table form-control company-id" placeholder="ID" />
    </th>
    <!-- etc -->            

and relevant JS part will use .search_table selector:

$('.search_table').keyup(function() {
    searchByColumn($(this).val());
});

http://plnkr.co/edit/CXuhR4ucd4bFKbrifVMp?p=preview

Upvotes: 2

Related Questions