Referencing specific tables (<tbody>) by ID in JavaScript - javascript

I have a website with three tables on it and a JavaScript search compoment that allows the user to search each table. However because the JavaScript refers to the tag and not a specific ID for each table, it means when the user searches it searches all tables. How can I write in JavaScript that it must refer to X
Here's my JavaScript:
$(document).ready(function () {
$(".search").keyup(function () {
var searchTerm = $(".search").val();
var listItem = $('.results tbody').children('tr');
var searchSplit = searchTerm.replace(/ /g, "'):containsi('")
$.extend($.expr[':'], {
'containsi': function (elem, i, match, array) {
return (elem.textContent || elem.innerText || '').toLowerCase().indexOf((match[3] || "").toLowerCase()) >= 0;
}
});
$(".results tbody tr").not(":containsi('" + searchSplit + "')").each(function (e) {
$(this).attr('visible', 'false');
});
$(".results tbody tr:containsi('" + searchSplit + "')").each(function (e) {
$(this).attr('visible', 'true');
});
var jobCount = $('.results tbody tr[visible="true"]').length;
$('.counter').text(jobCount + ' item');
if (jobCount == '0') {
$('.no-result').show();
} else {
$('.no-result').hide();
}
});
});
Thanks in advance! :)

two way :
adding an id on your table and working with$("#myID") Jquery
work with the DOM object that make the call : <table onclick="f(this)">

Related

I have a search and checkbox filter that should be filtering together, but my checkbox filter code isn't working

For some reason, my checkbox filter isn't working but my search filter is. What's wrong with it? Here is my search + checkbox filter below:
// search filter (working)
$(document).ready(function() {
$("#myInput").keyup(function() {
// Retrieve the input field text and reset the count to zero
var filter = $(this).val(),
count = 0;
// Loop through the comment list
$("tr").each(function() {
// If the list item does not contain the text phrase fade it out
if ($(this).text().search(new RegExp(filter, "i")) < 0) {
$(this).fadeOut(0).addClass('hidden');
// Show the list item if the phrase matches and increase the count by 1
} else {
$(this).show().removeClass('hidden');
count++;
}
});
// Update the count
var numberItems = count;
$("#filter-count").text("Number of Rows = " + count);
});
});
// checkbox filter (not working)
$(document).ready(function() {
$('#myTable tr' + $(this).attr('rel')).show();
$('div.modal-body').find('input:checkbox').live('click', function() {
if ($('div.modal-body').find('input:checkbox:checked').length > 0) {
$('#myTable tr').hide();
$('div.modal-body').find('input:checked').each(function() {
$('#myTable tr' + $(this).attr('rel')).not('.hidden').show();
});
} else {
$('#myTable tr').not('.hidden').show();
}
});
});
live is depreciated in latest versions of jquery, use on instead for your event.
$(document).ready(function () {
$('#myTable tr' + $(this).attr('rel')).show();
$('div.modal-body').find('input:checkbox').on('change', function () {
if($('div.modal-body').find('input:checkbox:checked').length > 0){
$('#myTable tr').hide();
$('div.modal-body').find('input:checked').each(function () {
$('#myTable tr' + $(this).attr('rel')).not('.hidden').show();
});
} else {
$('#myTable tr').not('.hidden').show();
}
});
});

Filterering data from table

Good Morning
I've this code of JS and I want to use it in VB but I don't know how what I want to achieve is to filter data from table if I'm searching.
$(document).ready(function() {
var activeSystemClass = $('.list-group-item.active');
//something is entered in search form
$('#system-search').keyup( function() {
var that = this;
// affect all table rows on in systems table
var tableBody = $('.table-list-search tbody');
var tableRowsClass = $('.table-list-search tbody tr');
$('.search-sf').remove();
tableRowsClass.each( function(i, val) {
//Lower text for case insensitive
var rowText = $(val).text().toLowerCase();
var inputText = $(that).val().toLowerCase();
if(inputText != '')
{
$('.search-query-sf').remove();
tableBody.prepend('<tr class="search-query-sf"><td colspan="6"><strong>Searching for: "'
+ $(that).val()
+ '"</strong></td></tr>');
}
else
{
$('.search-query-sf').remove();
}
if( rowText.indexOf( inputText ) == -1 )
{
//hide rows
tableRowsClass.eq(i).hide();
}
else
{
$('.search-sf').remove();
tableRowsClass.eq(i).show();
}
});
//all tr elements are hidden
if(tableRowsClass.children(':visible').length == 0)
{
tableBody.append('<tr class="search-sf"><td class="text-muted" colspan="6">No entries found.</td></tr>');
}
});
});

Find value in all TD with Highlighting

I have this script for searching in table with Highlighting value from "input". But only for first TD in all TR.
Function remove Highlighting
function removeHighlighting(highlightedElements){
highlightedElements.each(function(){
var element = $(this);
element.replaceWith(element.html());
})
}
Function add Highlighting
function addHighlighting(element, textToHighlight){
var text = element.text();
var highlightedText = '<em>' + textToHighlight + '</em>';
var newText = text.replace(textToHighlight, highlightedText);
element.html(newText);
}
Searching in table but only in first TD in TR
$("#search").on("keyup", function() {
var value = $(this).val();
removeHighlighting($("table tr em"));
$("table tr").each(function(index) {
if (index !== 0) {
$row = $(this);
var $tdElement = $row.find('td:first');
var id = $tdElement.text();
var matchedIndex = id.indexOf(value);
if (matchedIndex != 0) {
$row.hide();
}
else {
addHighlighting($tdElement, value);
$row.show();
}
}
});
});
I don´t know how can I searching in all TD and How can I write e.g. some alert if "matchedIndex == -1" (if not found some value from input)
Try looping in all TDs of TR
$("table tr").each(function(index) {
if (index !== 0) {
row = $(this);
$("td", this).each(function(idx) {
var id = $(this).text(); //or $(this).innerText
var matchedIndex = id.indexOf(value);
if (matchedIndex != 0) {
$row.hide();
}
else {
addHighlighting($tdElement, value);
$row.show();
}
}
}
});
A short way
$("table tr > td em").each(function(){
$( this ).replaceWith( $( this ).text() );
});
Adding a span tag with a highlight class is the way to go like suggested in the comments.
Please find a working demo below and in this jsFiddle.
There is a really useful function to remove all the wrapping of the spans. You can do this with $('span.highlight').contents().unwrap().
For finding the text you can use string.search(searchText) or string.match(searchText). The search method will return -1 if nothing is found and the position of the text if found. And match would return occurences in the searchText.
For testing that it finds the first occurence I have added TestY in the table. The flag matched is responsible for this behavior. If you would remove it, it would highlight both TestY elements.
(function () {
var removeHighlight = function () {
$('span.highlight').contents().unwrap();
};
var wrapContent = function (index, $el, text) {
var $highlight = $('<span class="highlight"/>')
.text(text.substring(0, index));
//console.log(text.substring(0, index));
var normalText = document.createTextNode(text.substring(index, text.length));
//console.log(index, $highlight.text(), normalText);
$el.html($highlight).append(normalText);
};
var highlightTextInTable = function ($tableElements, searchText) {
// highlights if text found (during typing)
var matched = false;
//remove spans
removeHighlight();
$.each($tableElements, function (index, item) {
var $el = $(item);
if ($el.text().search(searchText) != -1 && !matched) {
//console.log("matched", $el, $el.html());
wrapContent(searchText.length, $el, $el.html());
//console.log(searchText, $el.text());
if (searchText == $el.text()) {
// found the entry
//console.log("matched");
matched = true;
}
}
});
};
$(function () {
//load table into object
var $tableRows = $('table tr');
var $tableElements = $tableRows.children();
//console.log($tableRows, $tableElements);
$('#search').on('keyup', function (e) {
var searchText = $(this).val();
if (searchText.length == 0) {
// catches false triggers with empty input (e.g. backspace delete or case lock switch would trigger the function)
removeHighlight(); // remove last remaining highlight
return;
}
highlightTextInTable($tableElements, searchText);
});
});
})();
.highlight {
background-color: #00FFFF;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" id="search" />
<table>
<tr>
<td>TestX</td>
<td>Test1.2</td>
<td>Test1.3</td>
<td>Test1.4</td>
</tr>
<tr>
<td>Test2.1</td>
<td>TestY</td>
<td>Test2.3</td>
<td>Test2.4</td>
</tr>
<tr>
<td>Test3.1</td>
<td>TestY</td>
<td>Test3.3</td>
<td>Test3.4</td>
</tr>
</table>

Improving the performance of JQuery find

I have adapted the following code from a tutorial to filter li elements based upon their contents:
$('#_selectSearch_' + index).keyup(function() {
var filter = $(this).val();
if(filter) {
$('#_selectDrop_' + index).find("li:not(:contains(" + filter + "))").slideUp();
$('#_selectDrop_' + index).find("li:contains(" + filter + ")").slideDown();
} else {
$('#_selectDrop_' + index).find("li").slideDown();
}
});
The code works just fine but when working with large lists is very slow bringing the browser to a grinding halt for seconds with every key-press. I have been looking around and have come to the conclusion that the way to improve this is to somehow cache the list and not operate directly on the DOM but have no idea how to implement this.
If your main concern is performance the following code:
caches element containing filter string.
caches li elements.
doesn't show or hide elements that are already in that state.
uses indexOf which is very fast.
if the user types letters under 500 milliseconds apart the showMatches will not run.
var selectSearch = $("#_selectSearch_" + index );
var li = $("#_selectDrop_" + index + " li");
var currentTimeout;
selectSearch.on( "keyup", function( ) {
if( currentTimeout ) { window.clearTimeout( currentTimeout ) };
currentTimeout = setTimeout( showMatches, 500 );
});
function showMatches( ) {
var txt = selectSearch.val();
for( var i = 0, len = li.length; i < len; i++ ) {
var content = li[i].textContent ? li[i].textContent : li[i].innerText;
if( txt && content.indexOf( txt ) > -1) {
if( li[i].style.display !== "block" ) {
li[i].style.display = "block";
}
} else {
if( li[i].style.display !== "none" ) {
li[i].style.display = "none";
}
}
}
}
Fiddle with 400 li elements here
You can cache this element $('#_selectDrop_' + index + ' li');
$('#_selectSearch_' + index).keyup(function() {
var $li = $('#_selectDrop_' + index + ' li');
var filter = $(this).val();
if (filter) {
$li.not(":contains(" + filter + ")").slideUp();
$li.contains(filter).slideDown();
} else {
$li.slideDown();
}
});​
drop = $('#_selectDrop_' + index + ' li');
$('#_selectSearch_' + index).keyup(function() {
var filter = $(this).val();
if(filter) {
drop.find(":not(:contains(" + filter + "))").slideUp();
drop.find(":contains(" + filter + ")").slideDown();
} else {
drop.slideDown();
}
});
Drop will be cached just once, and then will be used at every keyup. Also this uses the minimum possible of find
$('#_selectSearch_' + index).keyup(function() {
var filter = $(this).val();
// by combining and cacheing all the way to the li
// we save a lot of time, since it seems that's where you are doing
// all your searching from
var selectDrop = $('#_selectDrop_' + index + ' li');
if (filter) {
selectDrop.not(':contains("' + filter + '")').slideUp();
selectDrop.contains(filter).slideDown();
}
else {
selectDrop.slideDown();
}
});
I'll give it a go with a somewhat modified (and untested) version:
$('#_selectSearch_' + index).on('keyup', function() {
var filter = this.value,
lis = document.getElementById('_selectDrop_' + index).getElementsByTagName('li'),
len = lis.length,
sup = 'textContent' in this;
if (filter.length) {
for (var i = len; i--) {
var text = sup ? lis[i].textContent : lis[i].innerText;
$(lis[i])[text.indexOf(filter) != -1 ? 'slideDown' : 'slideUp']();
}
} else {
$(lis).slideDown();
}
});​

jquery remove duplicate li

<ul id="myid">
<li>microsoft</li>
<li>microsoft</li>
<li>apple</li>
<li>apple</li>
</ul>
I want to remove duplicates from li by using jquery.
How can I do that?
example
I find that the script is faster
var liText = '', liList = $('#myid li'), listForRemove = [];
$(liList).each(function () {
var text = $(this).text();
if (liText.indexOf('|'+ text + '|') == -1)
liText += '|'+ text + '|';
else
listForRemove.push($(this));
})​;
$(listForRemove).each(function () { $(this).remove(); });
uniqueLi = {};
$("#myid li").each(function () {
var thisVal = $(this).text();
if ( !(thisVal in uniqueLi) ) {
uniqueLi[thisVal] = "";
} else {
$(this).remove();
}
})
This build an index (an object) of unique values. For your example, uniqueLi will look like this afterwards:
{
"microsoft": "",
"apple": ""
}
So whenever a value is encountered that has been added to the index before, the associated <li> gets removed.
You could use
var inner = [];
$('li').each( function(index, Element){
if (jQuery.inArray(this.innerHTML, inner) == -1){
inner.push(this.innerHTML);
}
else {
$(this).remove();
}
});
Here's a function that will do it, a slightly different way:
function removeDuplicateItems(id) {
var ul = $('#' + id);
$('li', ul).each(function() {
if($('li:contains("' + $(this).text() + '")', ul).length > 1)
$(this).remove();
});
}
Call with removeDuplicateItems('myid');
I have used #Thariama solution in the past, but I have compatibility problems with IE6 (I still needs to support this dinosaur).
If the item repeats, so remove it from ul. It works with dynamic added li.
var seen = {};
$("ul#emails_exclusion_list").find("li").each(function(index, html_obj) {
txt = $(this).text().toLowerCase();
if(seen[txt]) {
$(this).remove();
} else {
seen[txt] = true;
}
});

Categories