Persist table column widths across request actions (#8309)

* Persist table column widths across request actions

Column widths are stored in localStorage keyed by the table id, but
html_start_box() derives that id from the request action/report/tab, so a
filter refresh (action change/go) reloads the same table under a different
id and the saved widths are not restored. Emit a stable, action-independent
data-colsizing key on each cactiTable and use it in saveTableWidths(), while
keeping the DOM id unchanged.

* changelog: 8309 table column width persistence

* Column width persist: keep per-view key, normalize only filter-refresh actions

The previous key dropped the action/report/tab entirely, so distinct table schemas at the same page+ordinal (e.g. support.php processes vs background tabs, utilities.php view_snmp_cache vs view_poller_cache) collapsed into one localStorage entry and applied widths from the wrong schema.

Retain the stable logical-view discriminator (tab/report, or a non-transient action) in the data-colsizing key and normalize only the transient filter-refresh actions (go/change/clear/reset), so widths still survive a filter change but never cross unrelated schemas.

* Use short array syntax for the colsizing normalization list (php-cs-fixer)
This commit is contained in:
TheWitness authored and GitHub committed 2026-10-11 17:26:48 -04:00
1 parent e25a67c31f
commit d7ec67c4cf
3 files changed
+38 -7

No files matched your search

+1
View File
@@ -0,0 +1 @@
Persist table column widths across request actions (filter refreshes)
+13 -3
View File
@@ -3602,7 +3602,17 @@ function saveTableWidths(initial) {
// Initialize table width on the page
$('table.cactiTable').each(function (data) {
var key = $(this).attr('id');
var table = $(this);
// Persist widths under the action-independent data-colsizing key when it
// is present, so a table keeps its column widths across reloads that
// change the request action/report/tab (e.g. a filter refresh). Fall back
// to the DOM id for any table without the attribute.
var key = table.attr('data-colsizing');
if (key === undefined || key === '') {
key = table.attr('id');
}
if (storage.isSet(key)) {
var sizes = storage.get(key);
@@ -3637,7 +3647,7 @@ function saveTableWidths(initial) {
if (key !== undefined) {
if (initial && items.length > 1) {
$('#' + key).find('th.ui-resizable').each(function (data) {
table.find('th.ui-resizable').each(function (data) {
if (items[i] == 0) {
items[i] = $(this).width();
sizes[i] = items[i];
@@ -3650,7 +3660,7 @@ function saveTableWidths(initial) {
i++;
});
} else {
$('#' + key).find('th.ui-resizable').each(function (data) {
table.find('th.ui-resizable').each(function (data) {
sizes[i] = $(this).width();
if (sizes[i] != 0) {
+24 -4
View File
@@ -106,6 +106,26 @@ function html_start_box(string $title, string $width, bool $div, int $cell_paddi
$table_id = $table_prefix . $table_suffix;
// localStorage key for persisted column widths. Keep a stable logical
// discriminator (tab/report, or a non-transient action) so unrelated table
// schemas never share widths, while normalizing the transient filter-refresh
// actions so a table keeps its widths across a filter change / refresh.
$colsizing_view = '';
if (!ierv('action')) {
$colsizing_view = clean_up_name(gnrv('action'));
if (in_array($colsizing_view, ['go', 'change', 'clear', 'reset'], true)) {
$colsizing_view = '';
}
} elseif (!ierv('report')) {
$colsizing_view = clean_up_name(gnrv('report'));
} elseif (!ierv('tab')) {
$colsizing_view = clean_up_name(gnrv('tab'));
}
$colsizing_id = basename(get_current_page(), '.php') . ($colsizing_view != '' ? '_' . $colsizing_view : '') . $table_suffix . '_child';
if ($title != '') {
print "<div id='$table_id' class='cactiTable' style='width:$width;text-align:$align;'>";
print '<div class="cactiTableTitleRow">';
@@ -186,17 +206,17 @@ function html_start_box(string $title, string $width, bool $div, int $cell_paddi
print '</div><div class="cactiTableAction"></div></div>';
if ($div === true) {
print "<div id='$table_id" . "_child' class='cactiTable'>";
print "<div id='$table_id" . "_child' class='cactiTable' data-colsizing='$colsizing_id'>";
} else {
print "<table id='$table_id" . "_child' class='cactiTable' style='padding:" . $cell_padding . "px;'>";
print "<table id='$table_id" . "_child' class='cactiTable' data-colsizing='$colsizing_id' style='padding:" . $cell_padding . "px;'>";
}
} else {
print "<div id='$table_id' class='cactiTable' style='width:$width;text-align:$align;'>";
if ($div === true) {
print "<div id='$table_id" . "_child' class='cactiTable'>";
print "<div id='$table_id" . "_child' class='cactiTable' data-colsizing='$colsizing_id'>";
} else {
print "<table id='$table_id" . "_child' class='cactiTable' style='padding:" . $cell_padding . "px;'>";
print "<table id='$table_id" . "_child' class='cactiTable' data-colsizing='$colsizing_id' style='padding:" . $cell_padding . "px;'>";
}
}