1

I am having a little trouble in jQuery.

$(document).on('change', '.filter-status, .filter-week', function() {
    var filter = [];
    filter.push({
        week: $('.filter-week').val(),
        status: $('.filter-status').val(),
    })

    //filter.week('week', $('.filter-week').val());
    filter.status = $('.filter-status').val();
    var tags = [];
    //console.log(filter);
    $.each(filter, function(index, value) {
        if (value != 'all') {
            tags.push(value);
        }
    });
});

I have a table row that looks as follows:

<tr>
    <td>1</td>
    <td>Some text...
    <td>
        <button class="tag" data-tag="1234"></button>
        <button class="tag" data-tag="1235"></button>
    </td>
</tr>
<tr>
    <td>2</td>
    <td>Some text...
    <td>
        <button class="tag" data-tag="1234"></button>
    </td>
</tr>

What I am trying to do is to hide a tr that does not contain tag 1234 and 1235.

Edit

To be a bit more clear.

The tags object contains id 1234 and 1235. I want to hide all table rows that do not have both these tags. So if a table row only has 1234 it should be hidden. If it has only 1235 it should be hidden as well. If it has both 1234 and 1235 it should NOT be hidden.

Peter
  • 8,776
  • 6
  • 62
  • 95
  • @Pete They are in the `tags` object as integers. I was thinking about imploding them using `join` but this is not possible because i need to surround them with data-tag=... – Peter Feb 29 '16 at 11:53

3 Answers3

1

You can use .filter():

$('table tr').filter(function(i, el) {
  return $(el).find('button').eq(0).data('tag') != '1234' ||
    $(el).find('button').eq(1).data('tag') != '1235'
}).hide();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
  <tr>
    <td>1</td>
    <td>Some text...</td>
    <td>
      <button class="tag" data-tag="1234"></button>
      <button class="tag" data-tag="1235"></button>
    </td>
  </tr>
  <tr>
    <td>2</td>
    <td>Some text...</td>
    <td>
      <button class="tag" data-tag="1234"></button>
    </td>
  </tr>
</table>
Jai
  • 74,255
  • 12
  • 74
  • 103
  • This works. However, the ids should be coming from my tags object. It could just as well be three or for ids with varying contents. – Peter Feb 29 '16 at 13:22
1

The following will hide any rows that have the same values as your tags array (I have added a class to your button column).

The compare function has been taken from this question

Array.prototype.compare = function(testArr) {
    if (this.length != testArr.length) return false;
    for (var i = 0; i < testArr.length; i++) {
        if (this[i].compare) { 
            if (!this[i].compare(testArr[i])) return false;
        }
        if (this[i] !== testArr[i]) return false;
    }
    return true;
}

var tags = [1234, 1235];  // example tags array
$('.button-holder').filter(function() {
    // put data attributes into an array
    var buttonsData = [];
    $(this).find('button.tag').each(function() {
        buttonsData.push(parseInt($(this).data('tag')));
    });
    
    return !tags.compare(buttonsData);  // compare the arrays
}).closest('tr').hide();  // hide the row if the values are not the same
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr>
    <td>1</td>
    <td>Some text...
    <td class="button-holder"> <!-- add class to button column -->
        <button class="tag" data-tag="1234"></button>
        <button class="tag" data-tag="1235"></button>
    </td>
</tr>
<tr>
    <td>2</td>
    <td>Some text...
    <td class="button-holder">
        <button class="tag" data-tag="1234"></button>
    </td>
</tr>
<tr>
    <td>3</td>
    <td>Some text...
    <td class="button-holder">
        <button class="tag" data-tag="1234"></button>
        <button class="tag" data-tag="1235"></button>
        <button class="tag" data-tag="1236"></button>
    </td>
</tr>
</table>

If you are wanting to show all the rows that may have the tags values plus extras, you can use the following containsAll function instead of the compares function above:

Array.prototype.containsAll = function(needles){ 
  for(var i = 0 , len = needles.length; i < len; i++){
     if($.inArray(needles[i], this) == -1) return false;
  }
  return true;
}

var tags = [1234, 1235];
$('.button-holder').filter(function() {
    var buttonsData = [];
    $(this).find('button.tag').each(function() {
        buttonsData.push(parseInt($(this).data('tag')));
    });
    
    return !buttonsData.containsAll(tags);
}).closest('tr').hide();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr>
    <td>1</td>
    <td>Some text...
    <td class="button-holder">
        <button class="tag" data-tag="1234"></button>
        <button class="tag" data-tag="1235"></button>
    </td>
</tr>
<tr>
    <td>2</td>
    <td>Some text...
    <td class="button-holder">
        <button class="tag" data-tag="1234"></button>
    </td>
</tr>
<tr>
    <td>3</td>
    <td>Some text...
    <td class="button-holder">
        <button class="tag" data-tag="1234"></button>
        <button class="tag" data-tag="1235"></button>
        <button class="tag" data-tag="1236"></button>
    </td>
</tr>
</table>
Community
  • 1
  • 1
Pete
  • 57,112
  • 28
  • 117
  • 166
  • Great, but I am looking for exactly the opposite. If a table row has both the tags it should be shown. Otherwise it should be hidden. – Peter Feb 29 '16 at 13:24
  • 1
    @Peter have a look at the snippets, the first only shows the table row with both tags in it, the second shows table rows with both tags in plus additional. My comment may be misleading as I have put hide the rows if the values are the same (I forgot to change it when I edited to change the filter the opposite way round) – Pete Feb 29 '16 at 13:32
0

You can find the element and then go back with parents() to find the related <tr>:

$(':not([data-tag="1235"])').each(function() {
     $(this).parents('tr').hide();
});

Edited due comments that I misunderstanding the question:

hide a tr that does not contain tag 1234 and 1235.

I missed the not when I read it

Marcos Pérez Gude
  • 21,869
  • 4
  • 38
  • 69