我与 ChatGPT 4o 合作,根据客户的需求创建了一个复杂的 DataTables.net 概念证明,其中包括以下 DataTables.net 插件和功能:
在提供的示例代码/jsfiddle 中,每个都用不同的颜色突出显示,以便于识别。
一切都很完美。固定标头只有一个问题。向下和向上滚动时,固定标题完美对齐。但是,当您向上滚动并到达页面/视图的顶部时,固定标题会向左移动并与下面的列不对齐。 (参见位置栏)
您可以在这个jsfiddle中看到问题:https://jsfiddle.net/v5fs3do6/
我花了几个小时尝试用 chatgpt 解决这个问题,但这个例子似乎太复杂了,无法解决。我们尝试回滚某些插件来尝试查看问题在何处/何时引入,但这也失败了。
不幸的是,这些要求需要所有这些功能和插件。
我希望前端设计/编码方面的人类专家的眼睛能够帮助我解决这个问题。
jsfiddle 有一个演示所有功能和问题的工作示例,但这里也是代码。
任何帮助将不胜感激,并让我免于发疯。 谢谢!
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>DataTable with Grouping, Expanded Child Rows</title>
<link rel="stylesheet" href="https://cdn.datatables.net/1.13.6/css/jquery.dataTables.min.css">
<link rel="stylesheet" href="https://cdn.datatables.net/fixedheader/3.4.0/css/fixedHeader.dataTables.min.css">
<link rel="stylesheet" href="https://cdn.datatables.net/rowgroup/1.4.0/css/rowGroup.dataTables.min.css">
<style>
table.dataTable thead th {
background-color: #f4f4f4;
}
.group-header {
font-weight: bold;
background-color: #d8d8d8;
}
.child-row td {
padding: 10px 0;
border-top: none;
text-align: left;
}
.blueTable th {
background-color: #007bff !important;
color: white !important;
}
.groupRow {
background-color: #0056b3 !important;
color: white !important;
}
.childDataRow {
background-color: #80c1ff !important;
color: black !important;
}
.groupFooterRow {
background-color: #cce5ff !important;
font-weight: bold;
color: black !important;
}
</style>
</head>
<body>
<h3>Select Grouping Column:</h3>
<select id="group-by-column">
<option value="none">None</option>
<option value="office">Office</option>
<option value="position">Position</option>
</select>
<table id="example" class="display nowrap table responsive-table table-vcenter table-hover" style="width:100%">
<thead class="text-white">
<tr class="bg-primary">
<th><input type="checkbox" id="select-all"></th>
<th>Name</th>
<th>Position</th>
<th>Age</th>
<th>Start date</th>
<th>Salary</th>
<th>Department</th>
<th>Project</th>
<th>Experience (Years)</th>
<th>Location</th>
<th class="d-none">Office</th>
<th class="d-none">Hobby</th>
<th class="d-none">Favorite Animal</th>
</tr>
</thead>
<tbody>
<tr class="mainRecordRow table-light">
<td></td>
<td class="custom-cell-class">
Tiger Nixon
<input type="hidden" class="hobby" value="Fishing">
<input type="hidden" class="favorite-animal" value="Tiger">
</td>
<td>System Architect</td>
<td>61</td>
<td>2011/04/25</td>
<td>$320,800</td>
<td>IT</td>
<td>Project A</td>
<td>10</td>
<td>Scotland</td>
<td>Edinburgh</td>
<td>Fishing</td>
<td>Tiger</td>
</tr>
<tr class="mainRecordRow table-light">
<td></td>
<td class="custom-cell-class">
Garrett Winters
<input type="hidden" class="hobby" value="Gardening">
<input type="hidden" class="favorite-animal" value="Cat">
</td>
<td>Accountant</td>
<td>63</td>
<td>2011/07/25</td>
<td>$170,750</td>
<td>Finance</td>
<td>Project B</td>
<td>8</td>
<td>Japan</td>
<td>Tokyo</td>
<td>Gardening</td>
<td>Cat</td>
</tr>
<tr class="mainRecordRow table-light">
<td></td>
<td class="custom-cell-class">
Ashton Cox
<input type="hidden" class="hobby" value="Painting">
<input type="hidden" class="favorite-animal" value="Dog">
</td>
<td>Junior Technical Author</td>
<td>66</td>
<td>2009/01/12</td>
<td>$86,000</td>
<td>Documentation</td>
<td>Project C</td>
<td>5</td>
<td>USA</td>
<td>San Francisco</td>
<td>Painting</td>
<td>Dog</td>
</tr>
<tr class="mainRecordRow table-light">
<td></td>
<td class="custom-cell-class">
Ryan Dixon
<input type="hidden" class="hobby" value="Fishing">
<input type="hidden" class="favorite-animal" value="Tiger">
</td>
<td>System Architect</td>
<td>61</td>
<td>2011/04/25</td>
<td>$320,800</td>
<td>IT</td>
<td>Project D</td>
<td>15</td>
<td>Japan</td>
<td>Tokyo</td>
<td>Fishing</td>
<td>Tiger</td>
</tr>
<tr class="mainRecordRow table-light">
<td></td>
<td class="custom-cell-class">
Brielle Williamson
<input type="hidden" class="hobby" value="Photography">
<input type="hidden" class="favorite-animal" value="Dolphin">
</td>
<td>Integration Specialist</td>
<td>61</td>
<td>2012/12/02</td>
<td>$372,000</td>
<td>Development</td>
<td>Project E</td>
<td>9</td>
<td>New Zealand</td>
<td>Wellington</td>
<td>Photography</td>
<td>Dolphin</td>
</tr>
<tr class="mainRecordRow table-light">
<td></td>
<td class="custom-cell-class">
Herrod Chandler
<input type="hidden" class="hobby" value="Hiking">
<input type="hidden" class="favorite-animal" value="Eagle">
</td>
<td>Sales Assistant</td>
<td>59</td>
<td>2012/08/06</td>
<td>$137,500</td>
<td>Sales</td>
<td>Project F</td>
<td>12</td>
<td>UK</td>
<td>London</td>
<td>Hiking</td>
<td>Eagle</td>
</tr>
<tr class="mainRecordRow table-light">
<td></td>
<td class="custom-cell-class">
Rhona Davidson
<input type="hidden" class="hobby" value="Reading">
<input type="hidden" class="favorite-animal" value="Panda">
</td>
<td>Senior Javascript Developer</td>
<td>55</td>
<td>2010/10/14</td>
<td>$327,900</td>
<td>Development</td>
<td>Project G</td>
<td>7</td>
<td>Canada</td>
<td>Toronto</td>
<td>Reading</td>
<td>Panda</td>
</tr>
<tr class="mainRecordRow table-light">
<td></td>
<td class="custom-cell-class">
Colleen Hurst
<input type="hidden" class="hobby" value="Cooking">
<input type="hidden" class="favorite-animal" value="Elephant">
</td>
<td>Javascript Developer</td>
<td>39</td>
<td>2009/09/15</td>
<td>$205,500</td>
<td>Development</td>
<td>Project H</td>
<td>6</td>
<td>Australia</td>
<td>Sydney</td>
<td>Cooking</td>
<td>Elephant</td>
</tr>
<tr class="mainRecordRow table-light">
<td></td>
<td class="custom-cell-class">
Sonya Frost
<input type="hidden" class="hobby" value="Knitting">
<input type="hidden" class="favorite-animal" value="Fox">
</td>
<td>Software Engineer</td>
<td>23</td>
<td>2008/12/13</td>
<td>$103,600</td>
<td>IT</td>
<td>Project I</td>
<td>4</td>
<td>USA</td>
<td>San Diego</td>
<td>Knitting</td>
<td>Fox</td>
</tr>
<tr class="mainRecordRow table-light">
<td></td>
<td class="custom-cell-class">
Jena Gaines
<input type="hidden" class="hobby" value="Traveling">
<input type="hidden" class="favorite-animal" value="Whale">
</td>
<td>Office Manager</td>
<td>30</td>
<td>2008/12/19</td>
<td>$90,560</td>
<td>Administration</td>
<td>Project J</td>
<td>2</td>
<td>USA</td>
<td>New York</td>
<td>Traveling</td>
<td>Whale</td>
</tr>
<tr class="mainRecordRow table-light">
<td></td>
<td class="custom-cell-class">
Quinn Flynn
<input type="hidden" class="hobby" value="Swimming">
<input type="hidden" class="favorite-animal" value="Shark">
</td>
<td>Support Lead</td>
<td>22</td>
<td>2013/03/03</td>
<td>$342,000</td>
<td>Support</td>
<td>Project K</td>
<td>1</td>
<td>Canada</td>
<td>Vancouver</td>
<td>Swimming</td>
<td>Shark</td>
</tr>
<tr class="mainRecordRow table-light">
<td></td>
<td class="custom-cell-class">
Charde Marshall
<input type="hidden" class="hobby" value="Writing">
<input type="hidden" class="favorite-animal" value="Wolf">
</td>
<td>Regional Director</td>
<td>36</td>
<td>2008/10/16</td>
<td>$470,600</td>
<td>Management</td>
<td>Project L</td>
<td>11</td>
<td>Singapore</td>
<td>Singapore</td>
<td>Writing</td>
<td>Wolf</td>
</tr>
<tr class="mainRecordRow table-light">
<td></td>
<td class="custom-cell-class">
Haley Kennedy
<input type="hidden" class="hobby" value="Cycling">
<input type="hidden" class="favorite-animal" value="Bear">
</td>
<td>Senior Marketing Designer</td>
<td>43</td>
<td>2012/12/18</td>
<td>$313,500</td>
<td>Marketing</td>
<td>Project M</td>
<td>8</td>
<td>UK</td>
<td>Manchester</td>
<td>Cycling</td>
<td>Bear</td>
</tr>
<tr class="mainRecordRow table-light">
<td></td>
<td class="custom-cell-class">
Tatyana Fitzpatrick
<input type="hidden" class="hobby" value="Dancing">
<input type="hidden" class="favorite-animal" value="Peacock">
</td>
<td>Regional Director</td>
<td>19</td>
<td>2010/03/17</td>
<td>$385,750</td>
<td>Management</td>
<td>Project N</td>
<td>3</td>
<td>India</td>
<td>Mumbai</td>
<td>Dancing</td>
<td>Peacock</td>
</tr>
</tbody>
</table>
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<script src="https://cdn.datatables.net/1.13.6/js/jquery.dataTables.min.js"></script>
<script src="https://cdn.datatables.net/fixedheader/3.4.0/js/dataTables.fixedHeader.min.js"></script>
<script src="https://cdn.datatables.net/rowgroup/1.4.0/js/dataTables.rowGroup.min.js"></script>
<script>
$(document).ready(function() {
var groupColumn = 10;
var initialColumnWidths = [];
function storeOriginalClasses() {
$('#example tbody tr').each(function() {
$(this).data('original-classes', $(this).attr('class'));
$(this).find('td').each(function() {
$(this).data('original-classes', $(this).attr('class'));
});
});
}
function reapplyOriginalClasses() {
$('#example tbody tr').each(function() {
var originalClasses = $(this).data('original-classes');
if (originalClasses) {
$(this).attr('class', originalClasses);
}
$(this).find('td').each(function() {
var originalTdClasses = $(this).data('original-classes');
if (originalTdClasses) {
$(this).attr('class', originalTdClasses);
}
});
});
$('.groupRow').each(function() {
var originalClasses = $(this).data('original-classes');
if (originalClasses) {
$(this).attr('class', originalClasses);
}
});
}
function addChildRows() {
$('.child-row').remove();
var colspan = $('#example thead tr th:visible').length - 1;
table.rows().every(function(rowIdx, tableLoop, rowLoop) {
var tr = $(this.node());
var hobby = tr.find('.hobby').val();
var favoriteAnimal = tr.find('.favorite-animal').val();
var childRowHtml = `
<tr class="childDataRow table-light">
<td></td>
<td colspan="${colspan}">Hobby: ${hobby} | Favorite Animal: ${favoriteAnimal}</td>
</tr>
`;
tr.after(childRowHtml);
});
}
function addGroupFooter() {
$('.groupFooterRow').remove();
var groupData = {};
table.rows({
page: 'current'
}).every(function() {
var data = this.data();
var groupKey = data[groupColumn];
if (!groupData[groupKey]) {
groupData[groupKey] = {
totalSalary: 0,
totalYears: 0,
rows: []
};
}
groupData[groupKey].rows.push(this.node());
groupData[groupKey].totalSalary += parseFloat(data[5].toString().replace(/[\$,]/g, ''));
groupData[groupKey].totalYears += parseFloat(data[8]) || 0;
});
$.each(groupData, function(groupKey, groupInfo) {
var lastRow = $(groupInfo.rows[groupInfo.rows.length - 1]);
var lastChildRow = lastRow.next('.childDataRow').length ? lastRow.next('.childDataRow') : lastRow;
var totalVisibleColumns = $('#example thead tr th:visible').length;
var colspanBeforeSalary = 5;
var colspanBetween = 2;
var colspanAfterYears = totalVisibleColumns - 9;
var formattedSalary = groupInfo.totalSalary.toFixed(2).replace(/\B(?=(\d{3})+(?!\d))/g, ',');
var formattedYears = groupInfo.totalYears.toFixed(2);
var groupFooterHtml = `
<tr class="groupFooterRow bg-primary text-white">
<td colspan="${colspanBeforeSalary}"></td>
<td>Group Total Salary: $${formattedSalary}</td>
<td colspan="${colspanBetween}"></td>
<td>Group Total Years: ${formattedYears}</td>
<td colspan="${colspanAfterYears}"></td>
</tr>
`;
lastChildRow.after(groupFooterHtml);
});
}
// Capture initial column widths when the table is first drawn
function captureInitialColumnWidths() {
initialColumnWidths = [];
$('#example thead th').each(function() {
initialColumnWidths.push($(this).width());
});
}
// Apply the captured column widths
function applyColumnWidths() {
$('#example thead th').each(function(index) {
$(this).css('width', initialColumnWidths[index] + 'px');
});
$('#example tbody tr:first td').each(function(index) {
$(this).css('width', initialColumnWidths[index] + 'px');
});
}
storeOriginalClasses();
var table = $('#example').DataTable({
responsive: false,
fixedHeader: true,
scrollX: true,
order: [
[1, 'asc']
],
lengthChange: true,
lengthMenu: [10, 25, 50, 100],
paging: true,
rowGroup: {
dataSrc: groupColumn,
startRender: function(rows, group) {
var colspan = $('#example thead tr th:visible').length;
return $('<tr/>')
.addClass('groupRow bg-primary-light text-white')
.append(`<td colspan="${colspan}">Group: ${group}</td>`);
}
},
columnDefs: [{
targets: 0,
orderable: false,
searchable: false,
className: 'select-checkbox',
render: function() {
return '<input type="checkbox" class="select-row">';
}
},
{
targets: [10, 11, 12],
visible: false,
searchable: true
},
{
targets: 2, // The "Position" column
width: '100px', // Set width to 100px
createdCell: function(td, cellData, rowData, row, col) {
$(td).css('white-space', 'normal'); // Enable word wrapping
$(td).css('word-wrap', 'break-word'); // Ensure long words break
}
}
],
autoWidth: false
});
// Add child rows and group footers initially
addChildRows();
addGroupFooter();
// Capture initial column widths after the table is drawn
table.on('draw', function() {
if (initialColumnWidths.length === 0) {
captureInitialColumnWidths();
}
addChildRows();
addGroupFooter();
reapplyOriginalClasses();
adjustTable();
});
// Apply fixed column widths during scrolling to avoid shifting
$('#example_wrapper .dataTables_scrollBody').on('scroll', function() {
applyColumnWidths();
});
// Adjust on column order change
table.on('order', function() {
adjustTable();
});
// Handle Select All checkbox
$('#select-all').on('click', function() {
var rows = table.rows({
'search': 'applied'
}).nodes();
$('input[type="checkbox"]', rows).prop('checked', this.checked);
});
// Handle grouping change based on dropdown
$('#group-by-column').on('change', function() {
var selectedColumn = $(this).val();
if (selectedColumn === "none") {
groupColumn = null;
} else if (selectedColumn === "position") {
groupColumn = 2;
} else if (selectedColumn === "office") {
groupColumn = 10;
}
table.rowGroup().dataSrc(groupColumn).draw();
adjustTable();
});
// Function to adjust columns and fixed header alignment
function adjustTable() {
table.columns.adjust();
if (table.fixedHeader) {
table.fixedHeader.adjust();
}
}
// Fix header alignment on window resize
$(window).on('resize', function() {
adjustTable();
});
// Recalculate column width on table draw events, like search or paging
table.on('responsive-resize', function() {
adjustTable();
});
// Call the adjustment function on initial load to ensure correct alignment
adjustTable();
});
</script>
</body>
</html>
只需添加以下 CSS:
.dataTables_scrollHeadInner table .text-white .bg-primary{
display: flex;
justify-content: space-evenly;
}
.dataTables_scrollHeadInner table .text-white .bg-primary th{
flex: 1;
}
像这样:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>DataTable with Grouping, Expanded Child Rows</title>
<link rel="stylesheet" href="https://cdn.datatables.net/1.13.6/css/jquery.dataTables.min.css">
<link rel="stylesheet" href="https://cdn.datatables.net/fixedheader/3.4.0/css/fixedHeader.dataTables.min.css">
<link rel="stylesheet" href="https://cdn.datatables.net/rowgroup/1.4.0/css/rowGroup.dataTables.min.css">
<style>
table.dataTable thead th {
background-color: #f4f4f4;
}
.group-header {
font-weight: bold;
background-color: #d8d8d8;
}
.child-row td {
padding: 10px 0;
border-top: none;
text-align: left;
}
.blueTable th {
background-color: #007bff !important;
color: white !important;
}
.groupRow {
background-color: #0056b3 !important;
color: white !important;
}
.childDataRow {
background-color: #80c1ff !important;
color: black !important;
}
.groupFooterRow {
background-color: #cce5ff !important;
font-weight: bold;
color: black !important;
}
.dataTables_scrollHeadInner table .text-white .bg-primary {
display: flex;
justify-content: space-evenly;
}
.dataTables_scrollHeadInner table .text-white .bg-primary th {
flex: 1;
}
</style>
</head>
<body>
<h3>Select Grouping Column:</h3>
<select id="group-by-column">
<option value="none">None</option>
<option value="office">Office</option>
<option value="position">Position</option>
</select>
<table id="example" class="display nowrap table responsive-table table-vcenter table-hover" style="width:100%">
<thead class="text-white">
<tr class="bg-primary">
<th><input type="checkbox" id="select-all"></th>
<th>Name</th>
<th>Position</th>
<th>Age</th>
<th>Start date</th>
<th>Salary</th>
<th>Department</th>
<th>Project</th>
<th>Experience (Years)</th>
<th>Location</th>
<th class="d-none">Office</th>
<th class="d-none">Hobby</th>
<th class="d-none">Favorite Animal</th>
</tr>
</thead>
<tbody>
<tr class="mainRecordRow table-light">
<td></td>
<td class="custom-cell-class">
Tiger Nixon
<input type="hidden" class="hobby" value="Fishing">
<input type="hidden" class="favorite-animal" value="Tiger">
</td>
<td>System Architect</td>
<td>61</td>
<td>2011/04/25</td>
<td>$320,800</td>
<td>IT</td>
<td>Project A</td>
<td>10</td>
<td>Scotland</td>
<td>Edinburgh</td>
<td>Fishing</td>
<td>Tiger</td>
</tr>
<tr class="mainRecordRow table-light">
<td></td>
<td class="custom-cell-class">
Garrett Winters
<input type="hidden" class="hobby" value="Gardening">
<input type="hidden" class="favorite-animal" value="Cat">
</td>
<td>Accountant</td>
<td>63</td>
<td>2011/07/25</td>
<td>$170,750</td>
<td>Finance</td>
<td>Project B</td>
<td>8</td>
<td>Japan</td>
<td>Tokyo</td>
<td>Gardening</td>
<td>Cat</td>
</tr>
<tr class="mainRecordRow table-light">
<td></td>
<td class="custom-cell-class">
Ashton Cox
<input type="hidden" class="hobby" value="Painting">
<input type="hidden" class="favorite-animal" value="Dog">
</td>
<td>Junior Technical Author</td>
<td>66</td>
<td>2009/01/12</td>
<td>$86,000</td>
<td>Documentation</td>
<td>Project C</td>
<td>5</td>
<td>USA</td>
<td>San Francisco</td>
<td>Painting</td>
<td>Dog</td>
</tr>
<tr class="mainRecordRow table-light">
<td></td>
<td class="custom-cell-class">
Ryan Dixon
<input type="hidden" class="hobby" value="Fishing">
<input type="hidden" class="favorite-animal" value="Tiger">
</td>
<td>System Architect</td>
<td>61</td>
<td>2011/04/25</td>
<td>$320,800</td>
<td>IT</td>
<td>Project D</td>
<td>15</td>
<td>Japan</td>
<td>Tokyo</td>
<td>Fishing</td>
<td>Tiger</td>
</tr>
<tr class="mainRecordRow table-light">
<td></td>
<td class="custom-cell-class">
Brielle Williamson
<input type="hidden" class="hobby" value="Photography">
<input type="hidden" class="favorite-animal" value="Dolphin">
</td>
<td>Integration Specialist</td>
<td>61</td>
<td>2012/12/02</td>
<td>$372,000</td>
<td>Development</td>
<td>Project E</td>
<td>9</td>
<td>New Zealand</td>
<td>Wellington</td>
<td>Photography</td>
<td>Dolphin</td>
</tr>
<tr class="mainRecordRow table-light">
<td></td>
<td class="custom-cell-class">
Herrod Chandler
<input type="hidden" class="hobby" value="Hiking">
<input type="hidden" class="favorite-animal" value="Eagle">
</td>
<td>Sales Assistant</td>
<td>59</td>
<td>2012/08/06</td>
<td>$137,500</td>
<td>Sales</td>
<td>Project F</td>
<td>12</td>
<td>UK</td>
<td>London</td>
<td>Hiking</td>
<td>Eagle</td>
</tr>
<tr class="mainRecordRow table-light">
<td></td>
<td class="custom-cell-class">
Rhona Davidson
<input type="hidden" class="hobby" value="Reading">
<input type="hidden" class="favorite-animal" value="Panda">
</td>
<td>Senior Javascript Developer</td>
<td>55</td>
<td>2010/10/14</td>
<td>$327,900</td>
<td>Development</td>
<td>Project G</td>
<td>7</td>
<td>Canada</td>
<td>Toronto</td>
<td>Reading</td>
<td>Panda</td>
</tr>
<tr class="mainRecordRow table-light">
<td></td>
<td class="custom-cell-class">
Colleen Hurst
<input type="hidden" class="hobby" value="Cooking">
<input type="hidden" class="favorite-animal" value="Elephant">
</td>
<td>Javascript Developer</td>
<td>39</td>
<td>2009/09/15</td>
<td>$205,500</td>
<td>Development</td>
<td>Project H</td>
<td>6</td>
<td>Australia</td>
<td>Sydney</td>
<td>Cooking</td>
<td>Elephant</td>
</tr>
<tr class="mainRecordRow table-light">
<td></td>
<td class="custom-cell-class">
Sonya Frost
<input type="hidden" class="hobby" value="Knitting">
<input type="hidden" class="favorite-animal" value="Fox">
</td>
<td>Software Engineer</td>
<td>23</td>
<td>2008/12/13</td>
<td>$103,600</td>
<td>IT</td>
<td>Project I</td>
<td>4</td>
<td>USA</td>
<td>San Diego</td>
<td>Knitting</td>
<td>Fox</td>
</tr>
<tr class="mainRecordRow table-light">
<td></td>
<td class="custom-cell-class">
Jena Gaines
<input type="hidden" class="hobby" value="Traveling">
<input type="hidden" class="favorite-animal" value="Whale">
</td>
<td>Office Manager</td>
<td>30</td>
<td>2008/12/19</td>
<td>$90,560</td>
<td>Administration</td>
<td>Project J</td>
<td>2</td>
<td>USA</td>
<td>New York</td>
<td>Traveling</td>
<td>Whale</td>
</tr>
<tr class="mainRecordRow table-light">
<td></td>
<td class="custom-cell-class">
Quinn Flynn
<input type="hidden" class="hobby" value="Swimming">
<input type="hidden" class="favorite-animal" value="Shark">
</td>
<td>Support Lead</td>
<td>22</td>
<td>2013/03/03</td>
<td>$342,000</td>
<td>Support</td>
<td>Project K</td>
<td>1</td>
<td>Canada</td>
<td>Vancouver</td>
<td>Swimming</td>
<td>Shark</td>
</tr>
<tr class="mainRecordRow table-light">
<td></td>
<td class="custom-cell-class">
Charde Marshall
<input type="hidden" class="hobby" value="Writing">
<input type="hidden" class="favorite-animal" value="Wolf">
</td>
<td>Regional Director</td>
<td>36</td>
<td>2008/10/16</td>
<td>$470,600</td>
<td>Management</td>
<td>Project L</td>
<td>11</td>
<td>Singapore</td>
<td>Singapore</td>
<td>Writing</td>
<td>Wolf</td>
</tr>
<tr class="mainRecordRow table-light">
<td></td>
<td class="custom-cell-class">
Haley Kennedy
<input type="hidden" class="hobby" value="Cycling">
<input type="hidden" class="favorite-animal" value="Bear">
</td>
<td>Senior Marketing Designer</td>
<td>43</td>
<td>2012/12/18</td>
<td>$313,500</td>
<td>Marketing</td>
<td>Project M</td>
<td>8</td>
<td>UK</td>
<td>Manchester</td>
<td>Cycling</td>
<td>Bear</td>
</tr>
<tr class="mainRecordRow table-light">
<td></td>
<td class="custom-cell-class">
Tatyana Fitzpatrick
<input type="hidden" class="hobby" value="Dancing">
<input type="hidden" class="favorite-animal" value="Peacock">
</td>
<td>Regional Director</td>
<td>19</td>
<td>2010/03/17</td>
<td>$385,750</td>
<td>Management</td>
<td>Project N</td>
<td>3</td>
<td>India</td>
<td>Mumbai</td>
<td>Dancing</td>
<td>Peacock</td>
</tr>
</tbody>
</table>
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<script src="https://cdn.datatables.net/1.13.6/js/jquery.dataTables.min.js"></script>
<script src="https://cdn.datatables.net/fixedheader/3.4.0/js/dataTables.fixedHeader.min.js"></script>
<script src="https://cdn.datatables.net/rowgroup/1.4.0/js/dataTables.rowGroup.min.js"></script>
<script>
$(document).ready(function() {
var groupColumn = 10;
var initialColumnWidths = [];
function storeOriginalClasses() {
$('#example tbody tr').each(function() {
$(this).data('original-classes', $(this).attr('class'));
$(this).find('td').each(function() {
$(this).data('original-classes', $(this).attr('class'));
});
});
}
function reapplyOriginalClasses() {
$('#example tbody tr').each(function() {
var originalClasses = $(this).data('original-classes');
if (originalClasses) {
$(this).attr('class', originalClasses);
}
$(this).find('td').each(function() {
var originalTdClasses = $(this).data('original-classes');
if (originalTdClasses) {
$(this).attr('class', originalTdClasses);
}
});
});
$('.groupRow').each(function() {
var originalClasses = $(this).data('original-classes');
if (originalClasses) {
$(this).attr('class', originalClasses);
}
});
}
function addChildRows() {
$('.child-row').remove();
var colspan = $('#example thead tr th:visible').length - 1;
table.rows().every(function(rowIdx, tableLoop, rowLoop) {
var tr = $(this.node());
var hobby = tr.find('.hobby').val();
var favoriteAnimal = tr.find('.favorite-animal').val();
var childRowHtml = `
<tr class="childDataRow table-light">
<td></td>
<td colspan="${colspan}">Hobby: ${hobby} | Favorite Animal: ${favoriteAnimal}</td>
</tr>
`;
tr.after(childRowHtml);
});
}
function addGroupFooter() {
$('.groupFooterRow').remove();
var groupData = {};
table.rows({
page: 'current'
}).every(function() {
var data = this.data();
var groupKey = data[groupColumn];
if (!groupData[groupKey]) {
groupData[groupKey] = {
totalSalary: 0,
totalYears: 0,
rows: []
};
}
groupData[groupKey].rows.push(this.node());
groupData[groupKey].totalSalary += parseFloat(data[5].toString().replace(/[\$,]/g, ''));
groupData[groupKey].totalYears += parseFloat(data[8]) || 0;
});
$.each(groupData, function(groupKey, groupInfo) {
var lastRow = $(groupInfo.rows[groupInfo.rows.length - 1]);
var lastChildRow = lastRow.next('.childDataRow').length ? lastRow.next('.childDataRow') : lastRow;
var totalVisibleColumns = $('#example thead tr th:visible').length;
var colspanBeforeSalary = 5;
var colspanBetween = 2;
var colspanAfterYears = totalVisibleColumns - 9;
var formattedSalary = groupInfo.totalSalary.toFixed(2).replace(/\B(?=(\d{3})+(?!\d))/g, ',');
var formattedYears = groupInfo.totalYears.toFixed(2);
var groupFooterHtml = `
<tr class="groupFooterRow bg-primary text-white">
<td colspan="${colspanBeforeSalary}"></td>
<td>Group Total Salary: $${formattedSalary}</td>
<td colspan="${colspanBetween}"></td>
<td>Group Total Years: ${formattedYears}</td>
<td colspan="${colspanAfterYears}"></td>
</tr>
`;
lastChildRow.after(groupFooterHtml);
});
}
// Capture initial column widths when the table is first drawn
function captureInitialColumnWidths() {
initialColumnWidths = [];
$('#example thead th').each(function() {
initialColumnWidths.push($(this).width());
});
}
// Apply the captured column widths
function applyColumnWidths() {
$('#example thead th').each(function(index) {
$(this).css('width', initialColumnWidths[index] + 'px');
});
$('#example tbody tr:first td').each(function(index) {
$(this).css('width', initialColumnWidths[index] + 'px');
});
}
storeOriginalClasses();
var table = $('#example').DataTable({
responsive: false,
fixedHeader: true,
scrollX: true,
order: [
[1, 'asc']
],
lengthChange: true,
lengthMenu: [10, 25, 50, 100],
paging: true,
rowGroup: {
dataSrc: groupColumn,
startRender: function(rows, group) {
var colspan = $('#example thead tr th:visible').length;
return $('<tr/>')
.addClass('groupRow bg-primary-light text-white')
.append(`<td colspan="${colspan}">Group: ${group}</td>`);
}
},
columnDefs: [{
targets: 0,
orderable: false,
searchable: false,
className: 'select-checkbox',
render: function() {
return '<input type="checkbox" class="select-row">';
}
},
{
targets: [10, 11, 12],
visible: false,
searchable: true
},
{
targets: 2, // The "Position" column
width: '100px', // Set width to 100px
createdCell: function(td, cellData, rowData, row, col) {
$(td).css('white-space', 'normal'); // Enable word wrapping
$(td).css('word-wrap', 'break-word'); // Ensure long words break
}
}
],
autoWidth: false
});
// Add child rows and group footers initially
addChildRows();
addGroupFooter();
// Capture initial column widths after the table is drawn
table.on('draw', function() {
if (initialColumnWidths.length === 0) {
captureInitialColumnWidths();
}
addChildRows();
addGroupFooter();
reapplyOriginalClasses();
adjustTable();
});
// Apply fixed column widths during scrolling to avoid shifting
$('#example_wrapper .dataTables_scrollBody').on('scroll', function() {
applyColumnWidths();
});
// Adjust on column order change
table.on('order', function() {
adjustTable();
});
// Handle Select All checkbox
$('#select-all').on('click', function() {
var rows = table.rows({
'search': 'applied'
}).nodes();
$('input[type="checkbox"]', rows).prop('checked', this.checked);
});
// Handle grouping change based on dropdown
$('#group-by-column').on('change', function() {
var selectedColumn = $(this).val();
if (selectedColumn === "none") {
groupColumn = null;
} else if (selectedColumn === "position") {
groupColumn = 2;
} else if (selectedColumn === "office") {
groupColumn = 10;
}
table.rowGroup().dataSrc(groupColumn).draw();
adjustTable();
});
// Function to adjust columns and fixed header alignment
function adjustTable() {
table.columns.adjust();
if (table.fixedHeader) {
table.fixedHeader.adjust();
}
}
// Fix header alignment on window resize
$(window).on('resize', function() {
adjustTable();
});
// Recalculate column width on table draw events, like search or paging
table.on('responsive-resize', function() {
adjustTable();
});
// Call the adjustment function on initial load to ensure correct alignment
adjustTable();
});
</script>
</body>
</html>
因为,一旦向后滚动,
width
属性中的style
就会消失,因此最简单的解决方案是使用flex
并均匀地间隔标题单元格。