可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I\'ve been Googling and searching Stack Overflow for a while, but I just can\'t get around this problem.
I have a standard HTML table, containing, say, fruit. Like so:
<table>
<tr>
<td>Apple</td>
<td>Green</td>
</tr>
<tr>
<td>Grapes</td>
<td>Green</td>
</tr>
<tr>
<td>Orange</td>
<td>Orange</td>
</tr>
</table>
Above this I have a text box, which I would like to search the table as a user types. So, if they type Gre
for example, the Orange row of the table would disapear, leaving the Apple and Grapes. If they carried on and typed Green Gr
the Apple row should disapear, leaving just grapes. I hope this is clear.
And, should the user delete some or all of their query from the text box, I should like all of the rows that now match the query to reappear.
While I know how to remove a table row in jQuery, I have little idea about how to go about doing the search and removing rows selectively based on this. Is there a simple solution to this? Or a plugin?
If anyone could point me in the right direction it would be brilliant.
Thank you.
回答1:
I created these examples.
Simple indexOf search
var $rows = $(\'#table tr\');
$(\'#search\').keyup(function() {
var val = $.trim($(this).val()).replace(/ +/g, \' \').toLowerCase();
$rows.show().filter(function() {
var text = $(this).text().replace(/\\s+/g, \' \').toLowerCase();
return !~text.indexOf(val);
}).hide();
});
Demo: http://jsfiddle.net/7BUmG/2/
Regular expression search
More advanced functionality using regular expressions will allow you to search words in any order in the row. It will work the same if you type apple green
or green apple
:
var $rows = $(\'#table tr\');
$(\'#search\').keyup(function() {
var val = \'^(?=.*\\\\b\' + $.trim($(this).val()).split(/\\s+/).join(\'\\\\b)(?=.*\\\\b\') + \').*$\',
reg = RegExp(val, \'i\'),
text;
$rows.show().filter(function() {
text = $(this).text().replace(/\\s+/g, \' \');
return !reg.test(text);
}).hide();
});
Demo: http://jsfiddle.net/dfsq/7BUmG/1133/
Debounce
When you implement table filtering with search over multiple rows and columns it is very important that you consider performance and search speed/optimisation. Simply saying you should not run search function on every single keystroke, it\'s not necessary. To prevent filtering to run too often you should debounce it. Above code example will become:
$(\'#search\').keyup(debounce(function() {
var val = $.trim($(this).val()).replace(/ +/g, \' \').toLowerCase();
// etc...
}, 300));
You can pick any debounce implementation, for example from Lodash _.debounce, or you can use something very simple like I use in next demos (debounce from here): http://jsfiddle.net/7BUmG/6230/ and http://jsfiddle.net/7BUmG/6231/.
回答2:
i have an jquery plugin for this. It uses jquery-ui also. You can see an example here
http://jsfiddle.net/tugrulorhan/fd8KB/1/
$(\"#searchContainer\").gridSearch({
primaryAction: \"search\",
scrollDuration: 0,
searchBarAtBottom: false,
customScrollHeight: -35,
visible: {
before: true,
next: true,
filter: true,
unfilter: true
},
textVisible: {
before: true,
next: true,
filter: true,
unfilter: true
},
minCount: 2
});
回答3:
Here is the best solution for searching inside HTML table while covering all of the table, (all td, tr in the table), pure javascript and as short as possible:
<input id=\'myInput\' onkeyup=\'searchTable()\' type=\'text\'>
<table id=\'myTable\'>
<tr>
<td>Apple</td>
<td>Green</td>
</tr>
<tr>
<td>Grapes</td>
<td>Green</td>
</tr>
<tr>
<td>Orange</td>
<td>Orange</td>
</tr>
</table>
<script>
function searchTable() {
var input, filter, found, table, tr, td, i, j;
input = document.getElementById(\"myInput\");
filter = input.value.toUpperCase();
table = document.getElementById(\"myTable\");
tr = table.getElementsByTagName(\"tr\");
for (i = 0; i < tr.length; i++) {
td = tr[i].getElementsByTagName(\"td\");
for (j = 0; j < td.length; j++) {
if (td[j].innerHTML.toUpperCase().indexOf(filter) > -1) {
found = true;
}
}
if (found) {
tr[i].style.display = \"\";
found = false;
} else {
tr[i].style.display = \"none\";
}
}
}
</script>
回答4:
Thank you @dfsq for the very helpful code!
I\'ve made some adjustments and maybe some others like them too. I ensured that you can search for multiple words, without having a strict match.
Example rows:
- Apples and Pears
- Apples and Bananas
- Apples and Oranges
- ...
You could search for \'ap pe\' and it would recognise the first row
You could search for \'banana apple\' and it would recognise the second row
Demo:
http://jsfiddle.net/JeroenSormani/xhpkfwgd/1/
var $rows = $(\'#table tr\');
$(\'#search\').keyup(function() {
var val = $.trim($(this).val()).replace(/ +/g, \' \').toLowerCase().split(\' \');
$rows.hide().filter(function() {
var text = $(this).text().replace(/\\s+/g, \' \').toLowerCase();
var matchesSearch = true;
$(val).each(function(index, value) {
matchesSearch = (!matchesSearch) ? false : ~text.indexOf(value);
});
return matchesSearch;
}).show();
});
回答5:
I found dfsq\'s answer its comments extremely useful. I made some minor modifications applicable to me (and I\'m posting it here, in case it is of some use to others).
- Using
class
as hooks, instead of table elements tr
- Searching/comparing text within a child
class
while showing/hiding parent
- Making it more efficient by storing the
$rows
text elements into an array only once (and avoiding $rows.length
times computation)
var $rows = $(\'.wrapper\');
var rowsTextArray = [];
var i = 0;
$.each($rows, function() {
rowsTextArray[i] = $(this).find(\'.fruit\').text().replace(/\\s+/g, \' \').toLowerCase();
i++;
});
$(\'#search\').keyup(function() {
var val = $.trim($(this).val()).replace(/ +/g, \' \').toLowerCase();
$rows.show().filter(function(index) {
return (rowsTextArray[index].indexOf(val) === -1);
}).hide();
});
span {
margin-right: 0.2em;
}
<input type=\"text\" id=\"search\" placeholder=\"type to search\" />
<div class=\"wrapper\"><span class=\"number\">one</span><span class=\"fruit\">apple</span></div>
<div class=\"wrapper\"><span class=\"number\">two</span><span class=\"fruit\">banana</span></div>
<div class=\"wrapper\"><span class=\"number\">three</span><span class=\"fruit\">cherry</span></div>
<div class=\"wrapper\"><span class=\"number\">four</span><span class=\"fruit\">date</span></div>
<script src=\"https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js\"></script>
回答6:
Datatable JS plugin is also one good alternate to accomedate search feature for html table
var table = $(\'#example\').DataTable();
// #myInput is a <input type=\"text\"> element
$(\'#myInput\').on( \'keyup\', function () {
table.search( this.value ).draw();
} );
https://datatables.net/examples/basic_init/zero_configuration.html
回答7:
Pure Javascript Solution :
Works for ALL columns and Case Insensitive :
function search_table(){
// Declare variables
var input, filter, table, tr, td, i;
input = document.getElementById(\"search_field_input\");
filter = input.value.toUpperCase();
table = document.getElementById(\"table_id\");
tr = table.getElementsByTagName(\"tr\");
// Loop through all table rows, and hide those who don\'t match the search query
for (i = 0; i < tr.length; i++) {
td = tr[i].getElementsByTagName(\"td\") ;
for(j=0 ; j<td.length ; j++)
{
let tdata = td[j] ;
if (tdata) {
if (tdata.innerHTML.toUpperCase().indexOf(filter) > -1) {
tr[i].style.display = \"\";
break ;
} else {
tr[i].style.display = \"none\";
}
}
}
}
}
回答8:
you can use native javascript like this
<script>
function myFunction() {
var input, filter, table, tr, td, i;
input = document.getElementById(\"myInput\");
filter = input.value.toUpperCase();
table = document.getElementById(\"myTable\");
tr = table.getElementsByTagName(\"tr\");
for (i = 0; i < tr.length; i++) {
td = tr[i].getElementsByTagName(\"td\")[0];
if (td) {
if (td.innerHTML.toUpperCase().indexOf(filter) > -1) {
tr[i].style.display = \"\";
} else {
tr[i].style.display = \"none\";
}
}
}
}
</script>