9

Given the following table:

<table id="incidents">
    <thead>
        <tr>
            <th></th>
        </tr>
    </thead>
    <tbody>
    </tbody>
</table>

Using jQuery the following evaluate as false:

$("#incidents tbody").is(":empty")

I would like to use CSS to set the content to be a message:

#incidents tbody:empty {
    content: "<tr>message foo</tr>";
}

Can the :empty selector be applied to tbody?

BoltClock
  • 630,065
  • 150
  • 1,295
  • 1,284
Darbio
  • 10,681
  • 12
  • 55
  • 98

7 Answers7

24

No, unfortunately the indentation and newlines within tbody prevent it from ever matching :empty in this case. This applies both to CSS and jQuery, where as far as I know :empty behaves identically, as well as jQuery's :parent, which is equivalent to :not(:empty) (with a very poor choice of name).

Furthermore, you cannot use CSS content to add elements to the DOM. You'll need to do this in jQuery or the server side: check if tbody has any rows and if not, add that row.

If you go with jQuery, you can use this:

var tbody = $("#incidents tbody");

if (tbody.children().length == 0) {
    tbody.html("<tr>message foo</tr>");
}
Community
  • 1
  • 1
BoltClock
  • 630,065
  • 150
  • 1,295
  • 1,284
  • "No, unfortunately the indentation and newlines within tbody prevent it from ever matching." Thanks, saved me some CSS debugging time. – rstackhouse Jun 16 '14 at 14:36
3

In this case tbody contains white space as content, so it won't work

:empty

The :empty pseudo-class represents any element that has no children at all. Only element nodes and text (including whitespace) are considered. Comments or processing instructions do not affect whether an element is considered empty or not.

Also the :content can be used only with :before or :after pseudo elements

The content CSS property is used with the ::before and ::after pseudo-elements to generate content in an element. Objects inserted using the content property are anonymous replaced elements.

Arun P Johny
  • 365,836
  • 60
  • 503
  • 504
  • 1
    `:before` and `:after` are not pseudo-classes. They're pseudo-elements. It says so right in the quote. – BoltClock Jul 30 '13 at 05:52
2

If you want to use the :empty then you need to give the tbody syntax like as:

<tbody></tbody>

As you have define the :empty will not check that as it have a new line.

Define the tbody as I have told you. You can also use the .html() to check the condition:

if(!$("#incidents tbody").html()) {}

Reference: How do I check if an HTML element is empty using jQuery?

Community
  • 1
  • 1
Code Lღver
  • 15,171
  • 16
  • 51
  • 71
2

The <tbody> isn't empty, as it contains whitespace. You'll have to use a filtering function to get around that:

$("#incidents tbody").filter(function() {
    return !$.trim($(this).text());
}).append('<tr>message foo</tr>');

Or count the number of children:

$("#incidents tbody").filter(function() {
    return !$(this).children().length;
}).append('<tr>message foo</tr>');
Blender
  • 257,973
  • 46
  • 399
  • 459
1

FYI: You can use the following jQuery selector to select a table with an empty tbody without depending on the id of the table element:

$("table:not(:has(>tbody>tr))")
Niels R.
  • 6,719
  • 5
  • 27
  • 43
0

Use

$("#incidents tbody").html()

and then check what you get.

kul_mi
  • 1,061
  • 4
  • 15
  • 32
-1

Check for this:

<table id="incidents">
    <thead>
        <tr>
            <th></th>
        </tr>
    </thead>
    <tbody></tbody>
</table>
Abhishek Jain
  • 2,557
  • 1
  • 15
  • 12