Case insensitive search in bootstrap table data - javascript

I am trying to find and highlight the matching text in a bootstrap table.
Here is the fiddler: https://jsfiddle.net/99x50s2s/74/
HTML
<table class='table table-bordered'>
<thead>
<tr><th>ID</th><th>Name</th></tr>
</thead>
<tbody id='UserInfoTableBody'>
<tr><td>1</td><td>UserName 1</td></tr>
<tr><td>2</td><td>UserName 2</td></tr>
<tr><td>3</td><td>UserName 1</td></tr>
<tr><td>4</td><td>UserName 3</td></tr>
<tr><td>5</td><td>UserName 2</td></tr>
<tr><td>6</td><td>UserName 2</td></tr>
<tr><td>7</td><td>UserName 1</td></tr>
<tr><td>8</td><td>UserName 1</td></tr>
<tr><td>9</td><td>username 2</td></tr>
</tbody>
</table>
JS
HighlightMatches();
function HighlightMatches(){
var textToMatch = 'UserName 2';
$('.match').replaceWith(function () {
return this.innerText;
});
$('#UserInfoTableBody td').each(function (i, tdContent) {
var $td = $(tdContent);
$td.html($td.html().
split(textToMatch).
join('<span class="match">' + textToMatch + '</span>'));
});
}
CSS
.match{background-color:yellow;}
Problem:
The current search is case-sensitive and I want it to be case-insensitive. In the code above, I am trying to search 'UserName 2' but it is missing the value in last row (username 2).
I tried to use contains but in that case, I am not sure how to highlight the text. Any help is appreciated.
Expectation
Highlight only the matching text.
Should work for,
var textToMatch = '2';
var textToMatch = 'User';
var textToMatch = 'user';

You can do it like this:
HighlightMatches();
function HighlightMatches(){
var textToMatch = 'username';
$('.match').replaceWith(function () {
return this.innerText;
});
$('#UserInfoTableBody td:odd').each(function (i, tdContent) {
var $td = $(tdContent);
var pos = $td.html().toLowerCase().search(textToMatch);
var len = textToMatch.length;
if(pos != -1 ){
var match = $td.html().substring(pos, len+pos);
var splitted = $td.html().split(match);
$td.html(splitted[0] + '<span class="match">' + match + '</span>' + splitted[1]);
}
});
}
Fiddle: https://jsfiddle.net/99x50s2s/87/

You can use the function toLowerCase().
this function characters converted to lowercase. use this function for textToMatch and td
Good luck

$.extend($.expr[":"], {
"containsIN": function(elem, i, match, array) {
return (elem.textContent || elem.innerText || "").toLowerCase().indexOf((match[3] || "").toLowerCase()) >= 0;
}
});
HighlightMatches();
function HighlightMatches(){
var textToMatch = 'UserName 2';
$('.match').replaceWith(function () {
return this.innerText;
});
$('#UserInfoTableBody td').each(function (i, tdContent) {
$('td:containsIN("'+textToMatch+'")').html('<span class="match">' + textToMatch + '</span>');
});
}
you can try this.
https://jsfiddle.net/99x50s2s/85/

Related

JQuery Highlight Row and Column in table

I want to add to my site table with highlighting row and column, but I have troubles with
column highlighting. This is my table. This is online courses and a full the table with
names such as Homework1, HW2 and etc.
%if len(students) > 0:
<div class="grades">
<table class="grade-table">
<%
templateSummary = students[0]['grade_summary']
%>
<thead>
<tr class = "table-header"> <!— Header Row —>
%for section in templateSummary['section_breakdown']:
//......
<th title="${tooltip_str}"><div class="assignment-label">${section['label']}</div></th>
%endfor
<th title="${_('Total')}"><div class="assignment-label">${_('Total')}</div></th>
</tr>
</thead>
<%def name="percent_data(fraction, label)">
//....
<td class="${data_class}" data-percent="${fraction}" title="${label}">${ "{0:.0f}".format( 100 * fraction ) }</td>
</%def>
<tbody>
%for student in students:
<tr class="table-row">
%for section in student['grade_summary']['section_breakdown']:
${percent_data( section['percent'], section['detail'] )}
%endfor
${percent_data( student['grade_summary']['percent'], _('Total'))}
</tr>
%endfor
</tbody>
</table>
This is JQuery. So in highlightRow() is making the magic with row, but I don't understand,
to add highlightColumn() and "$element.find('tr').bind('mouseover', highlightColumn);" or
to add in the function highlightRow() code for column.
var Gradebook = function($element) {
"use strict";
var $body = $('body');
var $grades = $element.find('.grades');
var $studentTable = $element.find('.student-table');
var $gradeTable = $element.find('.grade-table');
var $search = $element.find('.student-search-field');
var $leftShadow = $('<div class="left-shadow"></div>');
var $rightShadow = $('<div class="right-shadow"></div>');
var tableHeight = $gradeTable.height();
var maxScroll = $gradeTable.width() - $grades.width();
var mouseOrigin;
var tableOrigin;
var startDrag = function(e) {
mouseOrigin = e.pageX;
tableOrigin = $gradeTable.position().left;
$body.addClass('no-select');
$body.bind('mousemove', onDragTable);
$body.bind('mouseup', stopDrag);
};
var highlightRow = function() {
$element.find('.highlight').removeClass('highlight');
var index = $(this).index();
$studentTable.find('tr').eq(index + 1).addClass('highlight');
$gradeTable.find('tr').eq(index + 1).addClass('highlight');
};
$leftShadow.css('height', tableHeight + 'px');
$grades.append($leftShadow).append($rightShadow);
setShadows(0);
$grades.css('height', tableHeight);
$gradeTable.bind('mousedown', startDrag);
$element.find('tr').bind('mouseover', highlightRow);
$search.bind('keyup', filter);
$(window).bind('resize', onResizeTable);
};
It should be something like this:
$element.find('td').bind('mouseover', highlightColumn);
var highlightColumn = function() {
//remove all highlights
//not sure if it should be here may be it should happen before both highlightRow and highlightColumn function calls
$element.find('.highlight').removeClass('highlight');
var columnIndex = $(this).index(); //this should be td in this case
$studentTable.find('tr td:eq(' + columnIndex + ')').addClass('highlight');
$gradeTable.find('tr td:eq(' + columnIndex + ')').addClass('highlight');
};

jQuery/Javascript compare two tables against each other

I need to compare two HTML tables' rows assuming that data in first cell can be duplicated but data in second cell is always unique. I need to find whether first cell AND second cell in table1 is the same as data in first cell AND second cell in table2 for instance:
Table1:
<Table>
<tr>
<td>123</td>
<td>321</td>
</tr>
<tr>
<td>545</td>
<td>345</td>
</tr>
<tr>
<td>0</td>
<td>312</td>
</tr>
<tr>
<td>123</td>
<td>323331</td>
</tr>
</Table>
Second table:
<table>
<tr>
<td>545</td>
<td>345</td>
</tr>
<tr>
<td>545</td>
<td>3122</td>
</tr>
<tr>
<td>123</td>
<td>321</td>
</tr>
</table>
The result of this should be:
123 321 - good, do nothing
545 345 - good, do nothing
545 3122 - wrong its not in table1 <-
Here's what I've got so far...
$('#runCheck').click(function(){
var firstTable = $('#firstDiv table tr');
var secondTable = $('#secDiv table tr');
$(secondTable).each(function(index){
var $row = $(this);
var secTableCellZero = $row.find('td')[0].innerHTML;
var secTableCellOne = $row.find('td')[1].innerHTML;
$(firstTable).each(function(indexT){
if ($(this).find('td')[0].innerHTML === secTableCellZero){
if ($(this).find('td')[1].innerHTML !== secTableCellOne){
$('#thirdDiv').append("first: " + secTableCellZero + " second: " + secTableCellOne+"<br>");
}
}
});
});
});
Where am I going it wrong?
Just to clarify once again:
2nd table says :
row1 - john|likesCookies
row2 - peter|likesOranges
1st table says :
row1 - john|likesNothing
row2 - john|likesCookies
row3 - steward|likesToTalk
row4 - peter|likesApples
now it should say :
john - value okay
peter - value fail.
a lot alike =VLOOKUP in excel
Check this working fiddle : here
I've created two arrays which store values in each row of tables 1 and 2 as strings. Then I just compare these two arrays and see if each value in array1 has a match in array 2 using a flag variable.
Snippet :
$(document).ready(function() {
var table_one = [];
var table_two = [];
$("#one tr").each(function() {
var temp_string = "";
count = 1;
$(this).find("td").each(function() {
if (count == 2) {
temp_string += "/";
}
temp_string = temp_string + $(this).text();
count++;
});
table_one.push(temp_string);
});
$("#two tr").each(function() {
var temp_string = "";
count = 1;
$(this).find("td").each(function() {
if (count == 2) {
temp_string += "/";
temp_string = temp_string + $(this).text();
} else {
temp_string = temp_string + $(this).text();
}
count++;
});
table_two.push(temp_string);
});
var message = "";
for (i = 0; i < table_two.length; i++) {
var flag = 0;
var temp = 0;
table_two_entry = table_two[i].split("/");
table_two_cell_one = table_two_entry[0];
table_two_cell_two = table_two_entry[1];
for (j = 0; j < table_one.length; j++) {
table_one_entry = table_one[j].split("/");
table_one_cell_one = table_one_entry[0];
table_one_cell_two = table_one_entry[1];
console.log("1)" + table_one_cell_one + ":" + table_one_cell_two);
if (table_two_cell_one == table_one_cell_one) {
flag++;
if (table_one_cell_two == table_two_cell_two) {
flag++;
break;
} else {
temp = table_one_cell_two;
}
} else {}
}
if (flag == 2) {
message += table_two_cell_one + " " + table_two_cell_two + " found in first table<br>";
} else if (flag == 1) {
message += table_two_cell_one + " bad - first table has " + temp + "<br>";
} else if (flag == 0) {
message += table_two_cell_one + " not found in first table<br>";
}
}
$('#message').html(message);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<hr>
<table id="one">
<tr>
<td>123</td>
<td>321</td>
</tr>
<tr>
<td>545</td>
<td>345</td>
</tr>
<tr>
<td>0</td>
<td>312</td>
</tr>
<tr>
<td>123</td>
<td>323331</td>
</tr>
</table>
<hr>
<table id="two">
<tr>
<td>545</td>
<td>345</td>
</tr>
<tr>
<td>545</td>
<td>3122</td>
</tr>
<tr>
<td>123</td>
<td>321</td>
</tr>
</table>
<hr>
<div id="message">
</div>
</div>
If I understand your requirements, it would be easier to read the first table and store the couples as strings: 123/321, 545/345, etc...
Than you can read the second table and remove from the first list all the rows found in both.
What remains in the list are couples that do not match.
From purely an efficiency standpoint if you loop through the first table just once and create an object using the first cell value as keys and an array of values for second cells, you won't have to loop through that table numerous times
this then makes the lookup simpler also
var firstTable = $('#firstDiv table tr');
var secondTable = $('#secDiv table tr');
var firstTableData = {}
firstTable.each(function() {
var $tds = $(this).find('td'),
firstCellData = $tds.eq(0).html().trim(),
secondCellData == $tds.eq(1).html().trim();
if (!firstTableData[firstCellData]) {
firstTableData[firstCellData] = []
}
firstTableData[firstCellData].push(secondCellData)
})
$(secondTable).each(function(index) {
var $tds = $(this).find('td');
var secTableCellZero = $tds.eq(0).html().trim();
var secTableCellOne = $tds.eq(1).html().trim();
if (!firstTableData.hasOwnProperty(secTableCellZero)) {
console.log('No match for first cell')
} else if (!firstTableData[secTableCellZero].indexOf(secTableCellOne) == -1) {
console.log('No match for second cell')
}
});
I'm not sure what objective is when matches aren't found

table multiple word search in jquery

I have a jquery function that search a word in a table. e.g.
TABLE
<table>
<tr>
<th>First Name</th>
<th>Last Name</th>
<th>Band Name</th>
</tr>
<tr>
<td>John</td>
<td>Lennon</td>
<td>Beatles</td>
</tr>
<tr>
<td>Paul</td>
<td>McCartney</td>
<td>Beatles</td>
</tr>
<tr>
<td>George</td>
<td>Harrison</td>
<td>Beatles</td>
</tr>
<tr>
<td>Ringo</td>
<td>Starr</td>
<td>Beatles</td>
</tr>
now. i have an input text box that if you put any word in there based on the table e.g Paul
the result will be a table that has only paul mccartney . and all the other td elements will be hidden.
$(document).ready(function(){
if (!RegExp.escape) {
RegExp.escape = function (s) {
return s.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&")
};
}
///search this table
jQuery(function ($) {
///search this table
$(' #search ').click(function () {
var searchthis = new RegExp($(' #emp_search ').val().replace(/\s+/, '|'), 'i');
$("table").find("tr").slice(1).each(function (index) {
var text = $.trim($(this).text());
$(this).toggle(searchthis.test(text));
});
Now, what i want to happen is..
what if i input a text containg "Paul Harrison", the result should be paul mccartney and george harrison.. is that possible? like inputting a multiple words and displaying a possible result? Im just new in jquery. and the codes above is not mine.. thanks in advance. :)
here is the demo
http://jsfiddle.net/wind_chime18/D6nzC/7/
I think a regex based search will be the best fit for this
if (!RegExp.escape) {
RegExp.escape = function (s) {
return s.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&")
};
}
jQuery(function ($) {
var $table = $("table");
var bands = [];
$table.find('td:nth-child(3)').each(function () {
var text = $.trim($(this).text()).toLowerCase();
if ($.inArray(text, bands) == -1) {
bands.push(text);
}
}).get();
///search this table
$(' #search ').click(function () {
var parts = $(' #emp_search ').val().split(/\s+/);
var bns = [],
i = 0,
idx;
while (i < parts.length) {
idx = $.inArray(parts[i].toLowerCase(), bands);
if (idx >= 0) {
bns.push(parts.splice(i, 1)[0]);
} else {
i++;
}
}
var nameexp = parts.length ? new RegExp(parts.join('|'), 'im') : false;
var bnexp = bns.length ? new RegExp(bns.join('|'), 'im') : false;
$("table").find("tr").slice(1).each(function (index) {
var $this = $(this);
var name = $.trim($this.children().not(':nth-child(3)').text());
var band = $.trim($this.children(':nth-child(3)').text());
$(this).toggle((!nameexp || nameexp.test(name)) && (!bnexp || bnexp.test(band)));
});
});
});
Demo: Fiddle
You could first collapse all the rows, then split the searchthis string on space and finally add visible to rows that match one of the rows... something like this for example.
$(document).ready(function(){
///search this table
$('#search').click(function() {
var searchthis = $('#emp_search').val();
$("table").find("tr").each(function(index) {
if (index === 0) return;
$(this).css('visibility', 'collapse');
});
var searchArray = [searchthis];
if (searchthis.indexOf(' ') > -1) {
searchArray = searchthis.split(' ');
}
$("table").find("tr").each(function(index) {
if (index === 0) return;
var id = $(this).find("td").text().toLowerCase().trim();
for (var i = 0; i < searchArray.length; i++) {
var txt = searchArray[i].toLowerCase().trim();
if (id.indexOf(txt) !== -1) {
$(this).css('visibility', 'visible');
}
}
});
});
});

Jquery - Sum of each same class li value

Currently I'm Developing an Invoice app with php , mysql & jquery. I want to show some details with jquery. I have dynamically created tables with dynamic data.
<table class="report_table">
<tr>
<td class="items_id">
<ul>
<li class="KKTF0">KKTF0</li>
<li class="PEN01">PEN01</li>
</ul>
</td>
<td class="items_qty">
<ul>
<li class="KKTF0">1</li>
<li class="PEN01">2</li>
</ul>
</td>
</tr>
</table>
<table class="report_table">
<tr>
<td class="items_id">
<ul>
<li class="BKK01">BKK01</li>
<li class="KKTF0">KKTF0</li>
<li class="PEN01">PEN01</li>
</ul>
</td>
<td class="items_qty">
<ul>
<li class="BKK01">4</li>
<li class="KKTF0">2</li>
<li class="PEN01">3</li>
</ul>
</td>
</tr>
</table>
li classes are dynamically created. my jquery code
jQuery(document).ready(function() {
$('.report_table').each(function() {
$('.items_id ul li').each(function() {
$(this).addClass($(this).text());
var className = $(this).attr("class");
$(this).parents('tr').find('td.items_qty li').eq($(this).index()).addClass(className);
});
});
});
I want this result
<table>
<tr>
<th>Item Id</th>
<th>Sum of Item</th>
</tr>
<tr>
<td>KKTF0</td>
<td>3</td>
</tr>
<tr>
<td>PEN01</td>
<td>5</td>
</tr>
<tr>
<td>BKK01</td>
<td>4</td>
</tr>
</table>
I don't have any idea. please help me... Thanks.
Pretty short solution:
var data = {};
$('.report_table .items_qty li').each(function() {
data[this.className] = (data[this.className] || 0) + +$(this).text();
});
var table = '<table class="result"><tr><tr><th>Item Id</th><th>Sum of Item</th></tr>' +
$.map(data, function(qty, key) {
return '<td>' + key + '</td><td>' + qty + '</td>';
}).join('</tr><tr>') + '</tr></table>';
http://jsfiddle.net/VF7bz/
Brief explanation:
1). each collects the data into an object:
{"KKTF0":3,"PEN01":5,"BKK01":4}
2). map creates an array:
["<td>KKTF0</td><td>3</td>","<td>PEN01</td><td>5</td>","<td>BKK01</td><td>4</td>"]
3). array items are joined into a string using </tr><tr> as separator.
Create an array of "items" and increment the associated quantity of each as you loop through every li. Then output the table.
function sum() {
// This will hold each category and value
var sums = new Array();
$('li').each(function() {
var item = new Object();
// Get category
item.category = $(this).attr('class');
// Get count
if (isFinite($(this).html())) {
item.count = parseInt($(this).html());
}
else {
// Skip if not a number
return;
}
// Find matching category
var exists = false;
for (var i = 0; i < sums.length; i++) {
if (sums[i].category == item.category) {
exists = true;
break;
}
}
// Increment total count
if (exists) {
sums[i].count += item.count;
}
else {
// Add category if it doesn't exist yet
sums.push(item);
}
});
var table = '<table><tr><th>Item Id</th><th>Sum of Item</th></tr><tbody>';
// Add rows to table
for (var i = 0; i < sums.length; i++) {
table += '<tr><td>' + sums[i].category + '</td><td>'
+ sums[i].count + '</td></tr>';
}
// Close table
table += '</tbody></table>';
// Append table after the last table
$('table :last').after(table);
}
Please omit the jquery code that you have posted in your question and use the one below:
Complete Jquery Solution:
Tested and Working
$(document).ready(function() {
//Create table to fill with data after last report table
$('<table id="sumtable"><th>Item Id</th><th>Sum of Item</th></table>').insertAfter($('.report_table').last());
//Loop through each report table, fetch amount and update sum in '#sumtable'
$('.report_table').each(function(){
var currtable = $(this);
$(this).find('.items_id ul li').each(function(){
//cache obj for performance
var curritem = $(this);
var itemid = curritem.html();
var itemvalue = parseInt(currtable.find('.items_qty ul li:eq('+curritem.index()+')').html());
var sumrow = $('#sumtable tbody').find('tr.'+itemid);
if(sumrow.length == 0){
//no rows found for this item id in the sum table, let's insert it
$('#sumtable tbody').append('<tr class="'+itemid+'"><td>'+itemid+'</td><td>'+itemvalue+'</td></tr>');
} else {
//Row found, do sum of value
sumrow.find('td').eq(1).html(parseInt(sumrow.find('td').eq(1).html())+itemvalue);
console.log(sumrow.find('td').eq(1).html());
}
});
})
});
DEMO: http://jsfiddle.net/N3FdB/
I am using .each loop on all li and store the values in the Object variable as key-value pairs.
Then, looping over created object properties building the desired table.
var resultObj = {};
$('li').each(function (idx, item) {
var $item = $(item);
var prop = $item.attr('class');
if (!resultObj[prop]) {
resultObj[prop] = 0;
}
var parsedVal = parseInt($item.text(), 10);
resultObj[prop] += isNaN(parsedVal) ? 0 : parsedVal;
});
var $resultTable = $('<table />');
$resultTable.append('<tr><th>Item Id</th><th>Sum of Item</th></tr>');
for (var key in resultObj) {
var $row = $('<tr />');
$row.append($('<td />', {
text: key
}))
.append($('<td />', {
text: resultObj[key]
}));
$resultTable.append($row);
}
$('body').append($resultTable);
Have a look at this FIDDLE.

Finding column index using jQuery when table contains column-spanning cells

Using jQuery, how can I find the column index of an arbitrary table cell in the example table below, such that cells spanning multiple columns have multiple indexes?
HTML
<table>
<tbody>
<tr>
<td>One</td>
<td>Two</td>
<td id="example1">Three</td>
<td>Four</td>
<td>Five</td>
<td>Six</td>
</tr>
<tr>
<td colspan="2">One</td>
<td colspan="2">Two</td>
<td colspan="2" id="example2">Three</td>
</tr>
<tr>
<td>One</td>
<td>Two</td>
<td>Three</td>
<td>Four</td>
<td>Five</td>
<td>Six</td>
</tr>
</tbody>
</table>
jQuery
var cell = $("#example1");
var example1ColIndex = cell.parent("tr").children().index(cell);
// == 2. This is fine.
cell = $("#example2");
var example2ColumnIndex = cell.parent("tr").children().index(cell);
// == 2. It should be 4 (or 5, but I only need the lowest). How can I do this?
Here's a plugin which can calculate the 'noncolspan' index.
$(document).ready(
function()
{
console.log($('#example2').getNonColSpanIndex()); //logs 4
console.log($('#example1').getNonColSpanIndex()); //logs 2
}
);
$.fn.getNonColSpanIndex = function() {
if(! $(this).is('td') && ! $(this).is('th'))
return -1;
var allCells = this.parent('tr').children();
var normalIndex = allCells.index(this);
var nonColSpanIndex = 0;
allCells.each(
function(i, item)
{
if(i == normalIndex)
return false;
var colspan = $(this).attr('colspan');
colspan = colspan ? parseInt(colspan) : 1;
nonColSpanIndex += colspan;
}
);
return nonColSpanIndex;
};
Mine is quite similar to SolutionYogi's, minus the creation of a plugin. It took me a bit longer... but I'm still proud of it so here it is :)
cell = $("#example2");
var example2ColumnIndex2 = 0;
cell.parent("tr").children().each(function () {
if(cell.get(0) != this){
var colIncrementor = $(this).attr("colspan");
colIncrementor = colIncrementor ? colIncrementor : 1;
example2ColumnIndex2 += parseInt(colIncrementor);
}
});
console.log(example2ColumnIndex2);
There is a more concise answer here: Get Index of a td considering the colspan using jquery
In short:
var index = 0;
$("#example2").prevAll("td").each(function() {
index += this.colSpan;
});
console.log(index);
You could do something like this:
var index = 0;
cell.parent('tr').children().each(
function(idx,node) {
if ($(node).attr('colspan')) {
index+=parseInt($(node).attr('colspan'),10);
} else {
index++;
}
return !(node === cell[0]);
}
);
console.log(index);
It'd probably make sense to do it as a plugin or via extend.
Slightly modified version is here: http://jsfiddle.net/Lijo/uGKHB/13/
//INDEX
alert ( GetNonColSpanIndex ('Type'));
function GetNonColSpanIndex(referenceHeaderCellValue) {
var selectedCell = $("th").filter(function (i) {
return ($.trim($(this).html() )) == referenceHeaderCellValue;
});
alert(selectedCell.html());
var allCells = $(selectedCell).parent('tr').children();
var normalIndex = allCells.index($(selectedCell));
var nonColSpanIndex = 0;
allCells.each(
function (i, item) {
if (i == normalIndex)
return false;
var colspan = $(selectedCell).attr('colspan');
colspan = colspan ? parseInt(colspan) : 1;
nonColSpanIndex += colspan;
}
);
return nonColSpanIndex;
};
​

Categories

Resources