我有一个表格,其页脚的每一列中都有搜索栏。每列的搜索都按预期进行。但当它出现在日期这一栏时,问题就来了。
我当前的日期格式是
"mm/dd/yyyy"
当我尝试输入
"mm/yyyy"
例如"03/2023"
时,我会得到带有日年"dd/yyyy"
的值,如["01/03/2023","02/03/2023", "04/03/2023"]
。这不是我想要的,因为我想获取给定月份和年份内的所有日期。
所以我尝试使用数据表中的
DataTable.ext.search.push
函数。首先,我想保留全局搜索,所以我包括:
if (inputData === '') {
return true;
}
然后我想过滤给定的格式为
"mm/yyyy"
的输入是否有效以及年份或月份是否等于输入。
return (
isValidDate(inputData, 'MM/yyyy') &&
inputDate.year === rowDate.year ||
inputDate.month === rowDate.month
);
这个逻辑给了我同样的问题,其中
"dd/yyyy"
数据没有显示"mm/yyyy"
如何修复我的逻辑或代码以便过滤正确的数据?我尝试询问 chatGPT,但它表明了相同的逻辑和相同的结果。另外,如果有更好的方法来过滤或重构我的代码,请随时提出建议。
有关更多上下文,这里是我当前代码的更大片段。
$('.table-resize tfoot th').each(function(i) {
if (headerLen - 1 != i) {
var title = $('.table-resize thead th').eq(i).text();
$(this).html(
'<div class="form-group"><input class="form-control ' + (title ==
'Date Sourced' ? 'ds_search' : '') + '" type="text" placeholder="' +
title +
'" data-index="' + i + '" /></div>');
}
});
table = $('.table-resize').DataTable({
scrollY: "500px",
scrollX: true,
scrollCollapse: true,
scrollResize: true,
pageResize: true,
fixedColumns: {
leftColumns: 5,
},
drawCallback: function(settings) {
$('.table-loading-cont').removeClass('d-flex').css('display', 'none')
$('.table-resize').removeClass('d-none')
resizeTable()
}
});
$(table.table().container()).on('keyup change', 'tfoot input', function() {
table
.column($(this).data('index'))
.search(this.value)
.draw()
});
DataTable.ext.search.push(function(settings, data, dataIndex) {
var searchData = data[1];
var inputData = $($('tfoot .ds_search')[1]).val();
if (inputData === '') {
return true;
}
var inputDate = getDate(inputData, 'MM/yyyy');
var rowDate = getDate(searchData);
return (
isValidDate(inputData, 'MM/yyyy') &&
inputDate.year === rowDate.year ||
inputDate.month === rowDate.month
);
});
编辑:
我找到了解决方法。我将从列搜索中获取月份,并在全局搜索中获取年份。
DataTable.ext.search.push(function(settings, data, dataIndex) {
var searchData = data[1];
var inputData = $($('tfoot .ds_search')[1]).val();
if (inputData == '' ||
isValidDate(inputData) ||
(inputData.length == 2 && parseInt(inputData) == getDate(searchData).month)
) {
return true;
}
return false;
});
这个解决方案给了我预期的输出。然而,这对于用户来说并不直观,因为用户会同时使用 2 个搜索栏。所以现在的问题是:是否有更好的方法只需要从列搜索栏中输入一个即可完成此操作?
这是一个最小示例,基于以下代码:https://datatables.net/examples/api/multi_filter.html
搜索“03/2023”时,会得到“01/03/2023”、“02/03/2023”和“04/03/2023”。
new DataTable('#example', {
initComplete: function() {
this.api()
.columns()
.every(function() {
let column = this;
let title = column.footer().textContent;
// Create input element
let input = document.createElement('input');
input.placeholder = title;
column.footer().replaceChildren(input);
// Event listener for user input
input.addEventListener('keyup', () => {
if (column.search() !== this.value) {
column.search(input.value).draw();
}
});
});
}
});
tfoot input {
width: 100%;
padding: 3px;
box-sizing: border-box;
}
<link href="https://cdn.datatables.net/1.13.6/css/jquery.dataTables.min.css" rel="stylesheet" />
<script src="https://code.jquery.com/jquery-3.7.0.js"></script>
<script src="https://cdn.datatables.net/1.13.6/js/jquery.dataTables.min.js"></script>
<table id="example" class="display" style="width:100%">
<thead>
<tr>
<th>Name</th>
<th>Position</th>
<th>Office</th>
<th>Age</th>
<th>Start date</th>
<th>Salary</th>
</tr>
</thead>
<tbody>
<tr>
<td>Tiger Nixon</td>
<td>System Architect</td>
<td>Edinburgh</td>
<td>61</td>
<td>04/03/2023</td>
<td>$320,800</td>
</tr>
<tr>
<td>Garrett Winters</td>
<td>Accountant</td>
<td>Tokyo</td>
<td>63</td>
<td>01/03/2023</td>
<td>$170,750</td>
</tr>
<tr>
<td>Ashton Cox</td>
<td>Junior Technical Author</td>
<td>San Francisco</td>
<td>66</td>
<td>02/03/2023</td>
<td>$86,000</td>
</tr>
<tr>
<td>Cedric Kelly</td>
<td>Senior Javascript Developer</td>
<td>Edinburgh</td>
<td>22</td>
<td>03/29/2023</td>
<td>$433,060</td>
</tr>
<tr>
<td>Airi Satou</td>
<td>Accountant</td>
<td>Tokyo</td>
<td>33</td>
<td>03/28/2023</td>
<td>$162,700</td>
</tr>
<tr>
<td>Brielle Williamson</td>
<td>Integration Specialist</td>
<td>New York</td>
<td>61</td>
<td>12/02/2023</td>
<td>$372,000</td>
</tr>
</tbody>
<tfoot>
<tr>
<th>Name</th>
<th>Position</th>
<th>Office</th>
<th>Age</th>
<th>Start date</th>
<th>Salary</th>
</tr>
</tfoot>
</table>
遵循 https://datatables.net/examples/api/regex.html,此解决方案通过将“MM/YYY”形式的类似日期的文本转换为正则表达式,在内部使用自定义正则表达式搜索。
当用户在这个新搜索框中键入“03/2023”时,输入文本将转换为正则表达式
03\d{2}2023
,并且此搜索的结果是开始日期为“03/28/2023”和“03”的记录/29/2023”。
let table = new DataTable('#example', {
initComplete: function() {
this.api()
.columns()
.every(function() {
let column = this;
let title = column.footer().textContent;
// Create input element
let input = document.createElement('input');
input.placeholder = title;
column.footer().replaceChildren(input);
// Event listener for user input
input.addEventListener('keyup', () => {
if (column.search() !== this.value) {
column.search(input.value).draw();
}
});
});
}
});
function isValidDate(value) {
// matches 1/2023, 01/2023, 1/3/2023, 01/03/2023, etc.
return /^\d{1,2}(\/\d{1,2})?\/\d{4}$/.test(value)
}
function filterColumn(table, i) {
let filter = document.querySelector('#col' + i + '_filter');
let regex = document.querySelector('#col' + i + '_regex');
if (isValidDate(filter.value) && filter.value.length < 8) {
// form regular expression from MM/YYYY
let myRegex = filter.value.split('/').join('/\\d{2}/');
console.log("Search for matching:", myRegex);
table.column(i).search(myRegex, regex = true).draw();
} else {
table.column(i).search(filter.value).draw();
}
}
document.querySelectorAll('input.column_filter').forEach((el) => {
let tr = el.closest('tr');
let columnIndex = tr.getAttribute('data-column');
el.addEventListener(el.type === 'text' ? 'keyup' : 'change', () =>
filterColumn(table, columnIndex)
);
});
tfoot input {
width: 100%;
padding: 3px;
box-sizing: border-box;
}
<link href="https://cdn.datatables.net/1.13.6/css/jquery.dataTables.min.css" rel="stylesheet" />
<script src="https://code.jquery.com/jquery-3.7.0.js"></script>
<script src="https://cdn.datatables.net/1.13.6/js/jquery.dataTables.min.js"></script>
<table cellpadding="3" cellspacing="0" border="0" style="width: 50%; margin: 0 auto 2em auto;">
<tbody>
<tr id="filter_col5" data-column="4">
<td><b>Search by month MM/YYYY</b></td>
<td align="center"><input type="text" class="column_filter" id="col4_filter"></td>
</tr>
</tbody>
</table>
<table id="example" class="display" style="width:100%">
<thead>
<tr>
<th>Name</th>
<th>Position</th>
<th>Office</th>
<th>Age</th>
<th>Start date</th>
<th>Salary</th>
</tr>
</thead>
<tbody>
<tr>
<td>Tiger Nixon</td>
<td>System Architect</td>
<td>Edinburgh</td>
<td>61</td>
<td>04/03/2023</td>
<td>$320,800</td>
</tr>
<tr>
<td>Garrett Winters</td>
<td>Accountant</td>
<td>Tokyo</td>
<td>63</td>
<td>01/03/2023</td>
<td>$170,750</td>
</tr>
<tr>
<td>Ashton Cox</td>
<td>Junior Technical Author</td>
<td>San Francisco</td>
<td>66</td>
<td>02/03/2023</td>
<td>$86,000</td>
</tr>
<tr>
<td>Cedric Kelly</td>
<td>Senior Javascript Developer</td>
<td>Edinburgh</td>
<td>22</td>
<td>03/29/2023</td>
<td>$433,060</td>
</tr>
<tr>
<td>Airi Satou</td>
<td>Accountant</td>
<td>Tokyo</td>
<td>33</td>
<td>03/28/2023</td>
<td>$162,700</td>
</tr>
<tr>
<td>Brielle Williamson</td>
<td>Integration Specialist</td>
<td>New York</td>
<td>61</td>
<td>12/02/2023</td>
<td>$372,000</td>
</tr>
</tbody>
<tfoot>
<tr>
<th>Name</th>
<th>Position</th>
<th>Office</th>
<th>Age</th>
<th>Start date</th>
<th>Salary</th>
</tr>
</tfoot>
</table>