0

I want to make live search using jQuery AJAX and PHP, with one input textbox as the filter of the data. So on the background I have JSON data like this:

[
    ["1","Your Name 1","button_field"],
    ["2","Your Name 2","button_field"],
    ["3","Your Name 3","button_field"]
]

This is my jQuery code, for the live search when user start typing on the textbox:

$('input[name="search_value"]').on('keydown', function() {
    $.ajax({
        url: 'http://localhost/myapp/ajax/get',
        type: 'GET',
        dataType: 'json',
        success: function(data) {
            var search = $('input[name="search_value"]').val();
            var output = '';

            for (i = 0; i < data.length; i++) {
                if (($.inArray(search, data[i]) !== -1) || (search === '')) {
                    output += '<tr>';

                    for (j = 0; j < data[i].length; j++) {
                        output += '<td>' + data[i][j] + '</td>';
                    }

                    output += '</tr>';
                }
            }

            $('.table-data > table > tbody').html(output);
        }
    });
});

I try to using search, by typing Your Name 2, and it works. But when I try to typing your name 2 (no uppercase for each first word) and try to typing our name 2 (with missing y), the result is not shown.

And my question is : How to make the search results is ignoring the uppercase (make case insensitive) and start showing the data even the search value is incomplete ? Thanks for all your answers :)

Rory McCrossan
  • 331,213
  • 40
  • 305
  • 339
imbagila
  • 513
  • 1
  • 8
  • 26
  • Convert the array values and the search string to the same case, ie apply `toLowerCase()` or `toUpperCase()` – Rory McCrossan Dec 07 '16 at 07:38
  • [case-insensitive-jquery](http://stackoverflow.com/questions/187537/is-there-a-case-insensitive-jquery-contains-selector) – prasanth Dec 07 '16 at 07:41

1 Answers1

2

It sounds like you want a case-insensitive substring match. If so, $.inArray isn't the right tool.

I'd use Array#some for this. First I'd modify the line getting search to get it in lower case:

var search = $('input[name="search_value"]').val().toLowerCase();

Then when you're checking to see if data[i] contains it:

if (!search || data[i].some(function(entry) { return entry.toLowerCase().indexOf(search) != -1; })) {

Array#some calls the callback you give it once for each entry in the array until the callback returns a truthy value (in which case it stops). some returns true if the callback ever returns a truthy value, or false if it gets through the entire array without that ever happening.

That looks a bit better in ES2015, thanks to the arrow function and String#includes:

if (!search || data[i].some(entry => entry.toLowerCase().includes(search))) {

Live Example:

$('input[name="search_value"]').on('input', function() {
  // setTimeout to simulate ajax
  setTimeout(function() {
    var data = [
      ["1","Your Name 1","button_field"],
      ["2","Your Name 2","button_field"],
      ["3","Your Name 3","button_field"]
    ];
    var search = $('input[name="search_value"]').val().toLowerCase();
    var output = '';

    for (var i = 0; i < data.length; i++) {
      if (!search || data[i].some(function(entry) { return entry.toLowerCase().indexOf(search) != -1; })) {
        output += '<tr>';

        for (j = 0; j < data[i].length; j++) {
          output += '<td>' + data[i][j] + '</td>';
        }

        output += '</tr>';
      }
    }

    $('.table-data > table > tbody').html(output);
  });
});
<input type="text" name="search_value">
<div class="table-data">
  <table>
    <tbody>
    </tbody>
  </table>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Two other notes, both fixed it the example above:

  • I'd use input, not keydown, so you respond to all inputs (including pasting)
  • Your code is falling prety to The Horror of Implicit Globals.¹ Declare your variables (i in this case). :-)

¹ That's a post on my anemic little blog.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875