Matt Swinehart
Matt Swinehart

Reputation: 13

Hide a tr only if td contains no content AFTER a specific html tag

Is it possible to examine the content within a tr, AFTER an html element (br) to see if any exists? If there is no content after the br element, I'd like to hide the parent td. Please note that the html code is system generated and I cannot edit it.

I'm just not sure where to begin with this. Any help is greatly appreciated.

    <table class="tabledefault">
    <tbody>
        <tr>
            <td id="customfields">
                <table class="tabledefault">
                    <tbody>
                        <tr><!-- this TR should be hidden -->
                            <td id="CAT_Custom_451068"><strong>Laser Tag</strong>
                            <br>
                            </td>
                        </tr>
                        <tr>
                            <td id="CAT_Custom_451069"><strong>Arcade</strong>
                            <br>Selected
                            </td>
                        </tr>
                        <tr>
                            <td id="CAT_Custom_450908"><strong>Bounce House (45 minutes) $100</strong>
                            <br>False
                            </td>
                        </tr>
                        <tr>
                            <td id="CAT_Custom_451307"><strong>Party Room Rental (per hour) $75</strong>
                            <br>True</td>
                        </tr>
                    </tbody>
                </table>
            </td>
        </tr>
    </tbody>
    </table>

Upvotes: 0

Views: 313

Answers (2)

guest271314
guest271314

Reputation: 1

Try using .each() , nextSibling , nodeValue , String.prototype.match() , .closest()

$("table tr td br").each(function(i, el) {
  // if `br` next sibling does not contain alphanumeric characters,
  // hide parent `tr` element
  if (el.nextSibling.nodeType === 3 
      && el.nextSibling.nodeValue.match(/\w+/) === null
      || $(el).next(":empty").length) {
    $(this).closest("tr").hide()
  }
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>
<table class="tabledefault">
    <tbody>
        <tr>
            <td id="customfields">
                <table class="tabledefault">
                    <tbody>
                        <tr><!-- this TR should be hidden -->
                            <td id="CAT_Custom_451068"><strong>Laser Tag</strong>
                            <br><span></span>
                            </td>
                        </tr>
                        <tr>
                            <td id="CAT_Custom_451069"><strong>Arcade</strong>
                            <br>Selected
                            </td>
                        </tr>
                        <tr>
                            <td id="CAT_Custom_450908"><strong>Bounce House (45 minutes) $100</strong>
                            <br>False
                            </td>
                        </tr>
                        <tr>
                            <td id="CAT_Custom_451307"><strong>Party Room Rental (per hour) $75</strong>
                            <br>True</td>
                        </tr>
                    </tbody>
                </table>
            </td>
        </tr>
    </tbody>
    </table>

Upvotes: 1

T.J. Crowder
T.J. Crowder

Reputation: 1074276

Yes, you just get the trs, then find out if the first <br> element inside the first <td> has any following element siblings (I'm making an assumption there, that you don't want those hidden), or any following text node siblings that aren't blank. jQuery's contents is handy for that, as it includes text nodes. I'd probably loop through them backward:

$("#customfields .tabledefault tr").each(function(index) {
  var $tr = $(this);
  $tr.find("td:first").contents().get().reverse().some(function(node) {
    if (node.nodeName.toUpperCase() === "BR") {
      // Hide it, and we're done looping
      $tr.hide();
      return true;
    }
    if (node.nodeType != 3 || $.trim(node.nodeValue)) {
      // Don't hide it, and we're done looping
      return true;
    }
  });
});

I expect that can be optimized, but you get the idea.

Live Example:

var counter = 3;
tick();

function tick() {
  $("#countdown").text(counter--);
  if (counter < 0) {
    hideIt();
  } else {
    setTimeout(tick, 500);
  }
}

function hideIt() {
  $("#customfields .tabledefault tr").each(function(index) {
    var $tr = $(this);
    $tr.find("td:first").contents().get().reverse().some(function(node) {
      if (node.nodeName.toUpperCase() === "BR") {
        // Hide it, and we're done looping
        $tr.hide();
        return true;
      }
      if (node.nodeType != 3 || $.trim(node.nodeValue)) {
        // Don't hide it, and we're done looping
        return true;
      }
    });
  });
}
<table class="tabledefault">
  <tbody>
    <tr>
      <td id="customfields">
        <table class="tabledefault">
          <tbody>
            <tr>
              <!-- this TR should be hidden -->
              <td id="CAT_Custom_451068"><strong>Laser Tag</strong>
                <br>
              </td>
            </tr>
            <tr>
              <td id="CAT_Custom_451069"><strong>Arcade</strong>
                <br>Selected
              </td>
            </tr>
            <tr>
              <td id="CAT_Custom_450908"><strong>Bounce House (45 minutes) $100</strong>
                <br>False
              </td>
            </tr>
            <tr>
              <td id="CAT_Custom_451307"><strong>Party Room Rental (per hour) $75</strong>
                <br>True</td>
            </tr>
          </tbody>
        </table>
      </td>
    </tr>
  </tbody>
</table>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="countdown">&nbsp;</div>

Upvotes: 1

Related Questions