Select multiple rows in a table from input field

Viewed 181

I'm trying to apply one to several filters in order to display specific rows in a table from the value of an input field.

I know that the slice() method allows us to do this process, but when multiple values are put used I don't know exactly how to manage structure of several values to achieve the desired result.

For example, if the value field corresponds to 1,5-10,15 it will then show me line 1, lines 5 to 10 and line 15. It is to know that the order of value field doesn't matter. This may look like 5-10, 15, 20-30, 19 or 2,5,8-10,11-15 for example.

Here is what I've tried so far :

for (let i = 0; i <= 50; i++) {
  let rows = '<tr>';
  rows += '<td>100</td><td>100</td><td>100</td>';
  rows += '</tr>';
  $('table tbody').append(rows);
}

$('input').off().on('focusout', function() {
  let format, row = '';
  let val = $(this).val();
  if (val.includes(',')) {
    row = val.split(',');
  }

  format = !!row ? row : val;

  if (!format.includes('-')) {
    let filters = '';
    for (let i = 0; i < format.length; i++) {
      filters += '.not(":nth-child(' + format[i] + ')")';
    }

    $('table tbody tr') + filters + '.css("display", "none")';
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="text" placeholder="1-5,9">
<table border="border">
  <thead>
    <tr>
      <th class="text-center">data</th>
      <th class="text-center">data</th>
      <th class="text-center">data</th>
    </tr>
  </thead>
  <tbody>
  </tbody>
</table>

2 Answers

You can first check if the value has , in it means mutliple value then you need split the value of inputs and then use for loop and at each iteration check value of i if there is - or not depending on this use :eq or splice method of jquery.

Demo Code :

for (let i = 1; i <= 50; i++) {
  let rows = '<tr>';
  rows += '<td>' + i + '</td><td>100</td><td>100</td>';
  rows += '</tr>';
  $('table tbody').append(rows);
}

$('input').on('focusout', function() {
  let format, row = '';
  let val = $(this).val();
  $('table tbody tr').hide() //hide all
  //if include `,`
  if (val.includes(',')) {
    row = val.split(',');
    //loop through all datas
    for (var i = 0; i < row.length; i++) {
      //not there `-`
      if (!row[i].includes('-')) {
        //show that using eq
        $('table tbody tr:eq(' + (row[i] - 1) + ')').show()

      } else {
        //split and show using splice
        var value = row[i].split('-')
        $('table tbody tr').slice(value[0] - 1, value[1]).show()


      }

    }
  } else {
  //for single value
    if (!val.includes('-')) {
      $('table tbody tr:eq(' + (val - 1) + ')').show()

    } else {
      var value = val.split('-')
      $('table tbody tr').slice(value[0] - 1, value[1]).show()
    }


  }

});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="text" placeholder="1-5,9">
<table border="border">
  <thead>
    <tr>
      <th class="text-center">data</th>
      <th class="text-center">data</th>
      <th class="text-center">data</th>
    </tr>
  </thead>
  <tbody>
  </tbody>
</table>

One way to do this would be to split the input in to an array. From there you can use a regular expression to determine if the user is looking to find a single row index or a range. Then you can use :eq() to target the relevant rows and display them. Try this:

// demo code for HTML setup...
let rows = [];
for (let i = 0; i <= 50; i++) {
  let rowNum = i + 1;
  rows.push(`<tr><td>${rowNum}</td><td>${rowNum}</td><td>${rowNum}</td></tr>`);
}
let $rows = $('table tbody').append(rows).find('tr');

// filtering handler:
$('input').on('input', function() {
  $rows.hide();

  this.value.split(/,\s?/g).forEach(value => {
    let matches = value.match(/^(\d+)-?(\d+)?$/);
    if (matches && matches[2]) {
      // range...
      let from = Math.min(matches[1], matches[2]) - 1;
      let to = Math.max(matches[1], matches[2]) + 1;
      $rows.filter(`tr:eq(${from})`).nextUntil(`tr:eq(${to})`).addBack().show();
    } else if (matches && matches[1]) {
      // single...
      $rows.filter(`:eq(${matches[1] - 1})`).show();
    } else {
      value && console.log(`${value} - invalid`);
    }
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="text" placeholder="1-5,9">
<table border="border">
  <thead>
    <tr>
      <th class="text-center">data</th>
      <th class="text-center">data</th>
      <th class="text-center">data</th>
    </tr>
  </thead>
  <tbody>
  </tbody>
</table>

Related