Skip to content

Commit

Permalink
Fix #11918: Datatable auto fit column like Excel (#11986)
Browse files Browse the repository at this point in the history
  • Loading branch information
melloware committed May 26, 2024
1 parent 10ab6c0 commit d9358e2
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 1 deletion.
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

0 comments on commit d9358e2

Please sign in to comment.