Skip to content

Instantly share code, notes, and snippets.

@moritztim
Created November 30, 2022 15:09
Show Gist options
  • Save moritztim/69d43e4aa373bb4be378159459209057 to your computer and use it in GitHub Desktop.
Save moritztim/69d43e4aa373bb4be378159459209057 to your computer and use it in GitHub Desktop.
Merge all repeated cells per column using jQuery
/**
* Find a cell at a given distance below the given cell.
* @param {jQuery} cell The origin cell below which to find the target.
* @param {number} steps The number of steps to take.
* @returns {jQuery} The target cell.
*/
function below(cell, steps) {
return cell.parent().nextAll().eq(steps - 1).children().eq(cell.index());
// Get the current row
// Step down the given amount of rows
// Go to the index of the origin cell
}
/**
* Merge all repeated cells in each column.
* @param {jQuery} table The table to merge cells in.
* @param {boolean} [includeHeader] Whether to include the header row.
* @param {boolean} [keepHeight] Whether to include the footer row.
*/
function mergeTwinCells(table, includeHeader = false, keepHeight = true) {
/**
* First row to merge cells in.
* @type {jQuery}
*/
let firstRow = table.find('tr').eq(includeHeader + 1);
/**
* Original height of the table.
* only set if keepHeight is true.
* @type {number|undefined}
*/
let height = firstRow.height();
firstRow.find('td').each(function () {
for (
// For each column
let /** Current cell @type {jQuery} */ thisCell = $(this),
/** @type {number} */ steps = 1,
/** @type {jQuery} */ nextCell = below(thisCell, steps);
nextCell.length; // While there is a next cell
nextCell = below(thisCell, steps) // Either the current cell or steps are incremented within the loop
) {
// Merge twins
if (thisCell.text() == nextCell.text()) { // If this and next are identical
// Merge them
thisCell.attr('rowspan', steps + 1); // rowspan++
below(thisCell, steps++).attr('hidden', true); // Hide the next cell
} else {
// Go to the next cell
steps = 1; // Reset steps
thisCell = nextCell; // Increment cell
}
}
});
if (keepHeight) {
// Reset the height of the rows with only merged cells
table.find('tr').each(function () {
$(this).css('height', height);
});
}
}
$(document).ready(function () {
$('table').each(function () {
mergeTwinCells($(this));
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment