使用多个过滤器过滤 table 行
filter table rows with multiple filters
我有一个 table,其中包含多个行和列以及一组搜索字段。我希望能够显示/隐藏匹配/不匹配搜索字段的行。每个字段都与 table 的一列相关。我在这项任务中取得了部分成功,因为过滤是正确完成的(如您所见 here)。但是,我想解决两件事。
- 首先是 jquery 脚本也隐藏了 table 头部。
- 其次,我希望能够在键入时过滤行。前任。如果我只在名称框中键入 'J',所有内容都会消失,因为没有名称为 'J' 的行。但是,我们得到了 'James' 和 'Jamie',它们是潜在匹配。我想保留它们,直到名称被完全键入。我试着用
s1.localeCompare(s2)
(link here) 来做,但它不起作用。
顺便说一句,无需担心大写/小写输入。我实际上在原始代码中处理了它,但在这里尽量保持简单。
代码在这里:
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
<script>
$(document).ready(function(){
table = $("#MI6"); //set table name
search_field = new Object();
///we create it as an object, initially empty
$('.search-key').on('change keyup paste', function () {
search_field['name'] = $( "#name" ).val();
search_field['lastname'] = $("#lastname").val();
search_field['number'] = $("#number").val();
table.find('tr').each(function () {
current_row = $(this); //keep track of the row being checked, iterate through it's cells
var display = 0;
current_row.show();
$(this).find('td').each(function() {
//when we stumble upon the data used as a search criteria
cell_value = $(this).html(); //gets the value of the cell being checked
if (cell_value == search_field[this.id] || search_field[this.id] == '') {
display++;
}
});
if (display < 3) {
current_row.hide(); //if this cell is a match, or we no longer want to use it as a search criteria, the row is displayed
}
});
});
});
</script>
</head>
<body>
<input type="text" id="name" class="search-key" placeholder="name">
<input type="text" id="lastname" class="search-key" placeholder="lastname">
<input type="number" id="number" class="search-key" placeholder="number">
<p></p>
<table id="MI6">
<tr>
<th>Firstname</th>
<th>Lastname</th>
<th>Number</th>
</tr>
<tr>
<td id="name">James</td>
<td id="lastname">Bond</td>
<td id="number">7</td>
</tr>
<tr>
<td id="name">Vesper</td>
<td id="lastname">Lynd</td>
<td id="number">6</td>
</tr>
<tr>
<td id="name">Rene</td>
<td id="lastname">Mathis</td>
<td id="number">5</td>
</tr>
</table>
</body>
</html>
要回答您的第一个问题,只需使用 .not(':first')
:
从集合中省略 table 的第一行
table.find('tr').not(':first')
为了进行部分字符串匹配,可以使用indexOf()
.
The indexOf() method returns the index within the calling String
object of the first occurrence of the specified value, starting the
search at fromIndex. Returns -1 if the value is not found.
我注意到您可以在标记中重复 id,它们必须是唯一的。
您的脚本可以重写为更加动态,只需对标记进行一些小的更改:
<td data-input="name">Rene</td>
<td data-input="lastname">Mathis</td>
<td data-input="number">5</td>
然后您可以使用 data-input
来定位相应的 input
。您可以将此与 jQuery 的 filter()
方法结合使用以 return 匹配行:
/* $rows = table.find('tr').not(':first') */
$rows.hide().filter(function() {
return $(this).find('td').filter(function() {
var tdText = $(this).text().toLowerCase(),
inputValue = $('#' + $(this).data('input')).val().toLowerCase();
return tdText.indexOf(inputValue) != -1;
}).length == $(this).find('td').length;
}).show();
上面先隐藏每一行,然后过滤。在那里,每个包含的 td
都被过滤,将其文本与对应的 input
的值进行比较。如果找到匹配项,td
将被 return 编辑。然后它检查匹配 td
元素的数量与该行中 td
元素的数量,如果它们相同,则所有字段都包含部分匹配,并且整行是 return编辑。最后,将显示任何匹配的行。
这种方式将允许您添加更多的输入和 tds,而无需修改代码。您只需要在输入上设置 id
,并将相应的 data-input
添加到 td
元素。
Here's a complete example
这可能有帮助
$('.filter').change(function(){
filter_function();
//calling filter function each select box value change
});
$('table tbody tr').show(); //intially all rows will be shown
function filter_function(){
$('table tbody tr').hide(); //hide all rows
var companyFlag = 0;
var companyValue = $('#filter-company').val();
var contactFlag = 0;
var contactValue = $('#filter-contact').val();
var rangeFlag = 0;
var rangeValue = $('#filter-range').val();
var rangeminValue = $('#filter-range').find(':selected').attr('data-min');
var rangemaxValue = $('#filter-range').find(':selected').attr('data-max');
//setting intial values and flags needed
//traversing each row one by one
$('table tr').each(function() {
if(companyValue == 0){ //if no value then display row
companyFlag = 1;
}
else if(companyValue == $(this).find('td.company').data('company')){
companyFlag = 1; //if value is same display row
}
else{
companyFlag = 0;
}
if(contactValue == 0){
contactFlag = 1;
}
else if(contactValue == $(this).find('td.contact').data('contact')){
contactFlag = 1;
}
else{
contactFlag = 0;
}
if(rangeValue == 0){
rangeFlag = 1;
}
//condition to display rows for a range
else if((rangeminValue <= $(this).find('td.range').data('min') && rangemaxValue > $(this).find('td.range').data('min')) || (
rangeminValue < $(this).find('td.range').data('max') &&
rangemaxValue >= $(this).find('td.range').data('max'))){
rangeFlag = 1;
}
else{
rangeFlag = 0;
}
console.log(rangeminValue +' '+rangemaxValue);
console.log($(this).find('td.range').data('min') +' '+$(this).find('td.range').data('max'));
if(companyFlag && contactFlag && rangeFlag){
$(this).show(); //displaying row which satisfies all conditions
}
});
}
<html>
<head>
</head>
<body>
<select id="filter-company" class="filter">
<option value="0">No value</option>
<option value="Alfreds">Alfreds</option>
<option value="Centro">Centro</option>
<option value="Ernst">Ernst</option>
<option value="Island">Island</option>
<option value="Laughing">Laughing</option>
<option value="Magazzini">Magazzini</option>
</select>
<select id="filter-contact" class="filter">
<option value="0">No value</option>
<option value="Maria Anders">Maria Anders</option>
<option value="Francisco Chang">Francisco Chang</option>
<option value="Roland Mendel">Roland Mendel</option>
</select>
<select id="filter-range" class="filter">
<option value="0" data-min="1" data-max="1" >No value</option>
<option value="£100,000 - £200,000" data-min="100000" data-max="200000" >£100,000 - £200,000</option>
<option value="£200,000 - £300,000" data-min="200000" data-max="300000" >£200,000 - £300,000</option>
<option value="£300,000 - £400,000" data-min="300000" data-max="400000" >£300,000 - £400,000</option>
<option value="£400,000 - £500,000" data-min="400000" data-max="500000" >£400,000 - £500,000</option>
</select>
<!-- ^^ range select box contains data-max and data-min which will be used to compare ranges -->
<h2>HTML Table</h2>
<table>
<thead>
<tr>
<th>Company</th>
<th>Contact</th>
<th>Range</th>
</tr>
</thead>
<tr>
<tbody>
<td class="company" data-company="Alfreds">Alfreds</td>
<!-- Data attributes helps in fetching values but you can fetch value of text in td also -->
<td class="contact" data-contact="Maria Anders">Maria Anders</td>
<td class="range" data-min="200000" data-max="300000">£200,000 - £300,000</td>
<!-- here Data attributes are necessary as we need separate min max values -->
</tr>
<tr>
<td class="company" data-company="Centro">Centro</td>
<td class="contact" data-contact="Francisco Chang">Francisco Chang</td>
<td class="range" data-min="100000" data-max="200000">£100,000 - £200,000</td>
</tr>
<tr>
<td class="company" data-company="Alfreds" >Alfreds</td>
<td class="contact" data-contact="Roland Mendel">Roland Mendel</td>
<td class="range" data-min="200000" data-max="300000">£200,000 - £300,000</td>
</tr>
<tr>
<td class="company" data-company="Centro" >Centro</td>
<td class="contact" data-contact="Helen Bennett">Helen Bennett</td>
<td class="range" data-min="100000" data-max="200000">£100,000 - £200,000</td>
</tr>
<tr>
<td class="company" data-company="Laughing">Laughing</td>
<td class="contact" data-contact="Yoshi Tannamuri">Yoshi Tannamuri</td>
<td class="range" data-min="200000" data-max="300000">£200,000 - £300,000</td>
</tr>
<tr>
<td class="company" data-company="Laughing">Laughing</td>
<td data-contact="Giovanni Rovelli">Giovanni Rovelli</td>
<td class="range" data-min="150000" data-max="250000">£150,000 - £250,000</td>
</tr>
</tbody>
</table>
</body>
</html>
我有一个 table,其中包含多个行和列以及一组搜索字段。我希望能够显示/隐藏匹配/不匹配搜索字段的行。每个字段都与 table 的一列相关。我在这项任务中取得了部分成功,因为过滤是正确完成的(如您所见 here)。但是,我想解决两件事。
- 首先是 jquery 脚本也隐藏了 table 头部。
- 其次,我希望能够在键入时过滤行。前任。如果我只在名称框中键入 'J',所有内容都会消失,因为没有名称为 'J' 的行。但是,我们得到了 'James' 和 'Jamie',它们是潜在匹配。我想保留它们,直到名称被完全键入。我试着用
s1.localeCompare(s2)
(link here) 来做,但它不起作用。
顺便说一句,无需担心大写/小写输入。我实际上在原始代码中处理了它,但在这里尽量保持简单。
代码在这里:
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
<script>
$(document).ready(function(){
table = $("#MI6"); //set table name
search_field = new Object();
///we create it as an object, initially empty
$('.search-key').on('change keyup paste', function () {
search_field['name'] = $( "#name" ).val();
search_field['lastname'] = $("#lastname").val();
search_field['number'] = $("#number").val();
table.find('tr').each(function () {
current_row = $(this); //keep track of the row being checked, iterate through it's cells
var display = 0;
current_row.show();
$(this).find('td').each(function() {
//when we stumble upon the data used as a search criteria
cell_value = $(this).html(); //gets the value of the cell being checked
if (cell_value == search_field[this.id] || search_field[this.id] == '') {
display++;
}
});
if (display < 3) {
current_row.hide(); //if this cell is a match, or we no longer want to use it as a search criteria, the row is displayed
}
});
});
});
</script>
</head>
<body>
<input type="text" id="name" class="search-key" placeholder="name">
<input type="text" id="lastname" class="search-key" placeholder="lastname">
<input type="number" id="number" class="search-key" placeholder="number">
<p></p>
<table id="MI6">
<tr>
<th>Firstname</th>
<th>Lastname</th>
<th>Number</th>
</tr>
<tr>
<td id="name">James</td>
<td id="lastname">Bond</td>
<td id="number">7</td>
</tr>
<tr>
<td id="name">Vesper</td>
<td id="lastname">Lynd</td>
<td id="number">6</td>
</tr>
<tr>
<td id="name">Rene</td>
<td id="lastname">Mathis</td>
<td id="number">5</td>
</tr>
</table>
</body>
</html>
要回答您的第一个问题,只需使用 .not(':first')
:
table.find('tr').not(':first')
为了进行部分字符串匹配,可以使用indexOf()
.
The indexOf() method returns the index within the calling String object of the first occurrence of the specified value, starting the search at fromIndex. Returns -1 if the value is not found.
我注意到您可以在标记中重复 id,它们必须是唯一的。
您的脚本可以重写为更加动态,只需对标记进行一些小的更改:
<td data-input="name">Rene</td>
<td data-input="lastname">Mathis</td>
<td data-input="number">5</td>
然后您可以使用 data-input
来定位相应的 input
。您可以将此与 jQuery 的 filter()
方法结合使用以 return 匹配行:
/* $rows = table.find('tr').not(':first') */
$rows.hide().filter(function() {
return $(this).find('td').filter(function() {
var tdText = $(this).text().toLowerCase(),
inputValue = $('#' + $(this).data('input')).val().toLowerCase();
return tdText.indexOf(inputValue) != -1;
}).length == $(this).find('td').length;
}).show();
上面先隐藏每一行,然后过滤。在那里,每个包含的 td
都被过滤,将其文本与对应的 input
的值进行比较。如果找到匹配项,td
将被 return 编辑。然后它检查匹配 td
元素的数量与该行中 td
元素的数量,如果它们相同,则所有字段都包含部分匹配,并且整行是 return编辑。最后,将显示任何匹配的行。
这种方式将允许您添加更多的输入和 tds,而无需修改代码。您只需要在输入上设置 id
,并将相应的 data-input
添加到 td
元素。
Here's a complete example
这可能有帮助
$('.filter').change(function(){
filter_function();
//calling filter function each select box value change
});
$('table tbody tr').show(); //intially all rows will be shown
function filter_function(){
$('table tbody tr').hide(); //hide all rows
var companyFlag = 0;
var companyValue = $('#filter-company').val();
var contactFlag = 0;
var contactValue = $('#filter-contact').val();
var rangeFlag = 0;
var rangeValue = $('#filter-range').val();
var rangeminValue = $('#filter-range').find(':selected').attr('data-min');
var rangemaxValue = $('#filter-range').find(':selected').attr('data-max');
//setting intial values and flags needed
//traversing each row one by one
$('table tr').each(function() {
if(companyValue == 0){ //if no value then display row
companyFlag = 1;
}
else if(companyValue == $(this).find('td.company').data('company')){
companyFlag = 1; //if value is same display row
}
else{
companyFlag = 0;
}
if(contactValue == 0){
contactFlag = 1;
}
else if(contactValue == $(this).find('td.contact').data('contact')){
contactFlag = 1;
}
else{
contactFlag = 0;
}
if(rangeValue == 0){
rangeFlag = 1;
}
//condition to display rows for a range
else if((rangeminValue <= $(this).find('td.range').data('min') && rangemaxValue > $(this).find('td.range').data('min')) || (
rangeminValue < $(this).find('td.range').data('max') &&
rangemaxValue >= $(this).find('td.range').data('max'))){
rangeFlag = 1;
}
else{
rangeFlag = 0;
}
console.log(rangeminValue +' '+rangemaxValue);
console.log($(this).find('td.range').data('min') +' '+$(this).find('td.range').data('max'));
if(companyFlag && contactFlag && rangeFlag){
$(this).show(); //displaying row which satisfies all conditions
}
});
}
<html>
<head>
</head>
<body>
<select id="filter-company" class="filter">
<option value="0">No value</option>
<option value="Alfreds">Alfreds</option>
<option value="Centro">Centro</option>
<option value="Ernst">Ernst</option>
<option value="Island">Island</option>
<option value="Laughing">Laughing</option>
<option value="Magazzini">Magazzini</option>
</select>
<select id="filter-contact" class="filter">
<option value="0">No value</option>
<option value="Maria Anders">Maria Anders</option>
<option value="Francisco Chang">Francisco Chang</option>
<option value="Roland Mendel">Roland Mendel</option>
</select>
<select id="filter-range" class="filter">
<option value="0" data-min="1" data-max="1" >No value</option>
<option value="£100,000 - £200,000" data-min="100000" data-max="200000" >£100,000 - £200,000</option>
<option value="£200,000 - £300,000" data-min="200000" data-max="300000" >£200,000 - £300,000</option>
<option value="£300,000 - £400,000" data-min="300000" data-max="400000" >£300,000 - £400,000</option>
<option value="£400,000 - £500,000" data-min="400000" data-max="500000" >£400,000 - £500,000</option>
</select>
<!-- ^^ range select box contains data-max and data-min which will be used to compare ranges -->
<h2>HTML Table</h2>
<table>
<thead>
<tr>
<th>Company</th>
<th>Contact</th>
<th>Range</th>
</tr>
</thead>
<tr>
<tbody>
<td class="company" data-company="Alfreds">Alfreds</td>
<!-- Data attributes helps in fetching values but you can fetch value of text in td also -->
<td class="contact" data-contact="Maria Anders">Maria Anders</td>
<td class="range" data-min="200000" data-max="300000">£200,000 - £300,000</td>
<!-- here Data attributes are necessary as we need separate min max values -->
</tr>
<tr>
<td class="company" data-company="Centro">Centro</td>
<td class="contact" data-contact="Francisco Chang">Francisco Chang</td>
<td class="range" data-min="100000" data-max="200000">£100,000 - £200,000</td>
</tr>
<tr>
<td class="company" data-company="Alfreds" >Alfreds</td>
<td class="contact" data-contact="Roland Mendel">Roland Mendel</td>
<td class="range" data-min="200000" data-max="300000">£200,000 - £300,000</td>
</tr>
<tr>
<td class="company" data-company="Centro" >Centro</td>
<td class="contact" data-contact="Helen Bennett">Helen Bennett</td>
<td class="range" data-min="100000" data-max="200000">£100,000 - £200,000</td>
</tr>
<tr>
<td class="company" data-company="Laughing">Laughing</td>
<td class="contact" data-contact="Yoshi Tannamuri">Yoshi Tannamuri</td>
<td class="range" data-min="200000" data-max="300000">£200,000 - £300,000</td>
</tr>
<tr>
<td class="company" data-company="Laughing">Laughing</td>
<td data-contact="Giovanni Rovelli">Giovanni Rovelli</td>
<td class="range" data-min="150000" data-max="250000">£150,000 - £250,000</td>
</tr>
</tbody>
</table>
</body>
</html>