Opened 23 hours ago
Last modified 17 hours ago
#65968 new defect (bug)
Hidden check box (checkbox) column in the `WP_List_Table` is not hide.
| Reported by: | okvee | Owned by: | |
|---|---|---|---|
| Priority: | normal | Milestone: | Awaiting Review |
| Component: | General | Version: | 7.1 |
| Severity: | normal | Keywords: | has-patch has-unit-tests |
| Cc: | Focuses: |
Description
On the source of WP_List_Table ( https://github.com/WordPress/wordpress-develop/blob/3f5fdc537810c3b11f8084f3d35398edad5f8f35/src/wp-admin/includes/class-wp-list-table.php#L1383 ), the hidden columns can be set to _column_headers property.
The hidden columns can hide properly on another columns except on the check box column.
From my example ( https://github.com/Rundiz-WP/demo-listtable-ajax/blob/f6691a114414cd16d0911518e55d8592b91b23cf/App/DB/CustomersListTableHideCb.php#L238-L242 ), I was set the hidden column as check box column.
<?php $this->_column_headers = [ $this->get_columns(), ['cb'], $this->get_sortable_columns(), ];
By default, WordPress did not hide this column (as seen in the method single_row_columns() https://github.com/WordPress/wordpress-develop/blob/3f5fdc537810c3b11f8084f3d35398edad5f8f35/src/wp-admin/includes/class-wp-list-table.php#L1824-L1827 )
This happens on WP 7.0, 7.1 and not sure that the older versions too or not.
I tried to override the method single_row_column and it seems to work but next problem is, it (check box column) is not hidden properly on small screen of WordPress 7.0- (or older).
I am not sure is this the main purpose of WP_List_Table class to always display checkbox column. Or not?
If it is, then this ticket will be end here.
(If this is main purpose of this column, it still weird that checkbox column only hide on <thead> and <tfoot> except <tbody>.)
Step to re-produce:
- Create some simple extended of list table class with hidden column as
cb. - Create display page to display the list table.
- Open this list table page.
Expect: List table hide the column checkbox completely.
Actual: Only checkbox column header, footer is hide. Not in <tbody>.
Fix 1: override single_row_columns() method.
protected function single_row_columns( $item )
{
global $wp_version;
if (version_compare($wp_version, '7.1', '>=')) {
$wp7_1 = true;
} else {
$wp7_1 = false;
}
list($columns, $hidden, $sortable, $primary) = $this->get_column_info();
foreach ($columns as $column_name => $column_display_name) {
$classes = "$column_name column-$column_name";
if ($primary === $column_name) {
$classes .= ' has-row-actions column-primary';
}
if (in_array($column_name, $hidden, true)) {
$classes .= ' hidden';
}
/*
* Comments column uses HTML in the display name with screen reader text.
* Strip tags to get closer to a user-friendly string.
*/
$data = 'data-colname="' . esc_attr(wp_strip_all_tags($column_display_name)) . '"';
$attributes = "class='$classes' $data";
if ('cb' === $column_name) {
$tag = (true === $wp7_1 ? 'td' : 'th');
$cb_attributes = (false === $wp7_1 ? ' scope="row"' : '');
$cb_classes = 'check-column';
if (in_array($column_name, $hidden, true)) {
$cb_classes .= ' hidden demo-listtable-ajax-hidecb-column';
}
echo '<' . $tag . $cb_attributes . ' class="' . esc_attr($cb_classes) . '">';
echo $this->column_cb($item);
echo '</' . $tag . '>';
} elseif (method_exists($this, '_column_' . $column_name)) {
echo call_user_func(
array($this, '_column_' . $column_name),
$item,
$classes,
$data,
$primary
);
} else {
if (true === $wp7_1) {
$is_primary = ($primary === $column_name);
$tag = $is_primary ? 'th' : 'td';
$scope = $is_primary ? ' scope="row"' : '';
$aria_label = '';
if ($is_primary) {
$label = $this->get_primary_column_aria_label($item);
if ('' !== $label) {
$aria_label = ' aria-label="' . esc_attr($label) . '"';
}
}
} else {
$aria_label = '';
$scope = '';
$tag = 'td';
}
echo "<$tag $attributes$scope$aria_label>";
if (method_exists($this, 'column_' . $column_name)) {
echo call_user_func(array($this, 'column_' . $column_name), $item);
} else {
echo $this->column_default($item, $column_name);
}
echo $this->handle_row_actions($item, $column_name, $primary);
echo "</$tag>";
}
}// endforeach;
}// single_row_columns
Result: Only fixed on WordPress 7.1+ or newer. But WordPress 7.0.x or older still has a problem on small screen that checkbox column is not hide.
Fix2: Enqueue this CSS for WordPress 7.0.x or older.
@media (max-width: 782px) {
.demo-listtable-ajax-hidecb-column {
display: none !important;/* On small screen with hidden check box column, the column not really hidden due to `display: table-cell;` by WP core. */
}
}
Result: The checkbox column is now completely hide on small and large screen, based on WordPress 7.0.x.
Change History (2)
This ticket was mentioned in PR #13284 on WordPress/wordpress-develop by @iamchitti.
17 hours ago
#2
- Keywords has-patch has-unit-tests added
Trac ticket: https://core.trac.wordpress.org/ticket/65968
## What
When cb is included in a list table's hidden columns, <thead> and <tfoot> hide it but <tbody> does not, so every row still renders a checkbox cell.
WP_List_Table::print_column_headers() honours $hidden for every column including cb, but single_row_columns() short-circuits the cb case before $classes is used and always emits <td class="check-column">.
On a wide screen the still-visible body cell also absorbs the width freed by the hidden header, so it renders ~330px wide instead of ~35px and pushes the remaining columns out of alignment.
## How
Apply the hidden class to the checkbox cell when cb is in $hidden. $hidden is already available from the get_column_info() call at the top of the method.
## Test
- Create a list table with a
cbcolumn that sets$this->_column_headers = array( $this->get_columns(), array( 'cb' ), array() );and render it on an admin page. - Before: the header and footer hide the checkbox column, but every body row shows an empty checkbox cell and the columns are misaligned.
- After: the checkbox column is hidden in the body too, at both desktop and sub-782px widths, and the columns line up.
- Confirm Posts, Plugins and Users are unchanged, since
cbis not hidden there.
## Screenshots
Before -
After -
No regression -
## AI Usage
AI assistance: Yes
Tool(s): Claude Code
Model(s): Opus 5
Used for: drafting the fix and unit tests
![(please configure the [header_logo] section in trac.ini)](/chrome/site/your_project_logo.png)
Thanks for the report, @okvee - reproduced on trunk.
print_column_headers()honours$hiddenfor every column includingcb, butsingle_row_columns()short-circuits thecbcase before$classesis used, so<thead>/<tfoot>hide and<tbody>does not. Looks unintentional.$hiddenis already available in the method:Verified in the browser: the body cell now computes to
display: noneat both 1400px and 600px, and Posts/Plugins/Users are unchanged wherecbis not hidden. I will open a PR with this change and a unit test.Fix 2 should not be needed on trunk - the
display: table-cellon.check-columnthat beat.hiddenis gone since [62958] / #65743. A backport to older branches would need the CSS looked at separately.