2

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 2

1

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>

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks a lot for your solution @Swati, it's working well!
1

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>

1 Comment

Thanks a lot for your solution @Rory McCrossan, it's working well! U just forgot to add the "+" quantifier in the second group of your regex to match two-digit numbers ;)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.