Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix #11918: Datatable auto fit column like Excel #11986

Merged
merged 1 commit into from
May 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/14_0_0/gettingstarted/whatsnew.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ Look into [migration guide](https://primefaces.github.io/primefaces/14_0_0/#/../
* Added `filterPlaceholder` for `Column` and `Columns`
* Added `rowData` to `CellEditEvent` which contains the entire row from the cell being edited.
* Added `cellNavigation` property which defaults to true to enable WCAG keyboard navigation of table cells.
* Added `ALT+W` keyboard shortcut or double click on column resizer to auto adjust column to fit largest cell text.

* Dashboard
* Added `var` to allow dynamic panels in `DashboardWidget.setValue(obj)` per panel
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
</ui:define>

<ui:define name="description">
Columns can be resized in two ways, with a helper or live.
Columns can be resized in two ways, with a helper or live. Double-click on resizer or press <code>ALT+W</code> to auto-adjust the column width to fit text like Excel.
</ui:define>

<ui:param name="documentationLink" value="/components/datatable"/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -864,6 +864,11 @@ PrimeFaces.widget.DataTable = PrimeFaces.widget.DeferredWidget.extend({
var cell = $(this);

switch (e.code) {
case "KeyW":
if ($this.cfg.resizableColumns && e.altKey) {
$this.autosizeColumnWidth(cell);
}
break;
case "ArrowLeft":
var prevCell = $this.isRTL ? cell.next('[tabindex="-1"]') : cell.prev('[tabindex="-1"]');
makeFocusable(e, cell, prevCell);
Expand Down Expand Up @@ -1948,6 +1953,69 @@ PrimeFaces.widget.DataTable = PrimeFaces.widget.DeferredWidget.extend({
clearScrollState: function() {
this.scrollStateHolder.val('0,0');
},

/**
* Adjusts the width of a column in a table to fit the widest cell content.
*
* This function calculates the maximum width needed for a column in a table
* to accommodate the widest cell content. It creates a temporary span element
* to measure the width of cell contents and adjusts the column header width accordingly.
*
* @param {JQuery} cell - A jQuery object representing a cell in the column to be resized.
* @private
*/
autosizeColumnWidth: function(cell) {
// Create a temporary span element
var $span = $("<span></span>")
.css({
visibility: "hidden",
position: "absolute",
whiteSpace: "nowrap",
})
.appendTo(document.body);

// Function to set the span's styles based on a cell's styles
var setSpanStyles = function($element) {
$span.text($element.text()).css({
font: $element.css("font"),
fontSize: $element.css("fontSize"),
fontWeight: $element.css("fontWeight"),
fontFamily: $element.css("fontFamily"),
});
};

// Get the index of the cell's column within its row
var columnIndex = cell.index();

// Select all the cells in the same column of other rows
var cellsInSameColumn = this.tbody.find("tr td:nth-child(" + (columnIndex + 1) + ")");

// Find the max width of the largest column
var maxWidth = 0;
cellsInSameColumn.each(function() {
var $td = $(this);
setSpanStyles($td);
var cellWidth = $span.outerWidth(true);
maxWidth = Math.max(maxWidth, cellWidth);
});

// Find the header for the column
var $header = this.thead.find(".ui-resizable-column").eq(columnIndex);
setSpanStyles($header);

// get header width and add 20px to account for possible sort icon
var headerWidth = $span.outerWidth(true) + 20;
maxWidth = Math.max(maxWidth, headerWidth);

// Remove the span from the document body
$span.remove();

// set the TH header to the new width
$header.css("width", maxWidth);

// fire the AJAX event if necessary
this.fireColumnResizeEvent($header);
},

/**
* Adjusts the width of the given columns to fit the current settings.
Expand Down Expand Up @@ -4331,6 +4399,11 @@ PrimeFaces.widget.DataTable = PrimeFaces.widget.DeferredWidget.extend({

var resizers = this.thead.find('> tr > th > span.ui-column-resizer'),
$this = this;

// #11918 double click resizes column like Excel
resizers.on('dblclick', function() {
$this.autosizeColumnWidth($(this).parent());
});

resizers.draggable({
axis: 'x',
Expand Down