My table looks like this:
<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>
The searching javascript as follows:
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();
});
Look at this example to understand my problem better:
http://jsfiddle.net/7BUmG/4398/
I filter table rows with the first input field. Then, when I use the second input field, results of first search are not included. How can I fix it?
When you are applying your filter, you are first showing all the rows, negating any previous filtering on them. This is one solution to that problem... it stores the filters and applies both on either input's keyup event, based on your fiddle.
var $rows = $('#table tr');
var filters = { col1: '', col2: ''};
$('#search1').keyup(function() {
var val = $.trim($(this).val()).replace(/ +/g, ' ').toLowerCase();
filters.col1 = val;
applyFilters();
});
$('#search2').keyup(function() {
var val = $.trim($(this).val()).replace(/ +/g, ' ').toLowerCase();
filters.col2 = val;
applyFilters();
});
function applyFilters() {
$rows.show();
$rows.filter(function() {
var text = $(this).find('td:nth-child(1)').text().replace(/\s+/g, ' ').toLowerCase();
return !~text.indexOf(filters.col1);
}).hide();
$rows.filter(function() {
var text = $(this).find('td:nth-child(2)').text().replace(/\s+/g, ' ').toLowerCase();
return !~text.indexOf(filters.col2);
}).hide();
};
Your current logic is a little confused. You are re-showing and re-hiding the filtered items for every search field. What you really want is to filter it all in one go like so:
var $rows = $('#table tr');
$('#search1, #search2').on('input', function() {
var val1 = $.trim($('#search1').val()).replace(/ +/g, ' ').toLowerCase();
var val2 = $.trim($('#search2').val()).replace(/ +/g, ' ').toLowerCase();
$rows.show().filter(function() {
var text1 = $(this).find('td:nth-child(1)').text().replace(/\s+/g, ' ').toLowerCase();
var text2 = $(this).find('td:nth-child(2)').text().replace(/\s+/g, ' ').toLowerCase();
return !~text1.indexOf(val1) || !~text2.indexOf(val2);
}).hide();
});
body {padding: 20px;}
input {margin-bottom: 5px; padding: 2px 3px; width: 98px;}
td {padding: 4px; border: 1px #CCC solid; width: 100px;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" id="search1" placeholder="Type to search">
<input type="text" id="search2" placeholder="Type to search">
<table id="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>
That's of course assuming non-dynamic number of columns and filter fields. If that's what you're after, you need to check the index rather than hard coding td:nth-child(1) and td:nth-child(2)
You can accomplish it using each(). This code will collect the value of each input for each keyup(), then if this value exists in the corresponding td by using indexOf(), it will show the tr which contains this td and hide others, otherwise it will show all tr's
http://jsfiddle.net/7BUmG/4399/
var $rows = $('#table tr'),
searchVal1,
searchVal2,
td1,
td2;
$('input').keyup(function () {
searchVal1 = $('#search1').val(),
searchVal2 = $('#search2').val();
$rows.each(function (index, tr) {
td1 = $(tr).find('td:nth-of-type(1)').text().toLowerCase(),
td2 = $(tr).find('td:nth-of-type(2)').text().toLowerCase();
if ( (td1.indexOf(searchVal1) != -1) && (td2.indexOf(searchVal2) != -1) ) {
$(this).show();
} else {
$(this).hide();
}
});
if ((searchVal1 === '') && (searchVal2 === '')) {
$rows.show();
}
});
body {padding: 20px;}
input {margin-bottom: 5px; padding: 2px 3px; width: 98px;}
td {padding: 4px; border: 1px #CCC solid; width: 100px;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" id="search1" placeholder="Type to search">
<input type="text" id="search2" placeholder="Type to search">
<table id="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>
Related
I have a table with cells that are not contentEditable. However, using a JavaScript loop or function, I would like to make them so.
I understand that it is very simple to do this manually for each cell, and this would probably be easier for a table with only a few cells, but I would like to quicken this process with a loop/function for the table could become much larger, and the time spent manually setting each cell to be contentEditable would be tedious.
Below is a quick example that displays a table calculator, un-editable at present. But using a loop or function, I'd like to make every cell in the right column set to .contentEditable = true in the DOM. I imagine that the parameters would look something like (var i = 0; l != rows.length; i < l; i+2), but I'm struggling with what the statements following the argument would have to be for the loop/function to work. Any help would be much appreciated!
function myFunction() {
var jack2 = document.getElementById("jack").innerText;
var john2 = document.getElementById("john").innerText;
var joe2 = document.getElementById("joe").innerText;
var total2 = (parseInt(jack2) || 0) + (parseInt(john2) || 0) + (parseInt(joe2) || 0);
document.getElementById("total").innerHTML = total2;
}
table {
width: 100%;
}
table,
tr,
th,
td {
border: 1px solid gray;
border-collapse: collapse;
font-family: Arial;
margin: 5px;
}
<table>
<caption>Weight Calculator</caption>
<tr class="cell">
<th>Person</th>
<th>Weight (kg)</th>
</tr>
<tr class="cell">
<td>Jack</td>
<td id="jack" oninput="myFunction()">1</td>
</tr>
<tr class="cell">
<td>John</td>
<td id="john" oninput="myFunction()">2</td>
</tr>
<tr class="cell">
<td>Joe</td>
<td id="joe" oninput="myFunction()">3</td>
</tr>
<tr class="cell">
<td>Total</td>
<td id="total"></td>
</tr>
</table>
Get all cell in the tabel that have a left neigbour (the header is not effected because there are th and not td). Add to each of these cells your attribute.
Edited: For getting the totalsum add an eventlistener on each td that calls the calc-function if the content changes.
function myFunction() {
let weightCells = document.querySelectorAll("table tr:not(:last-child) td ~ td");
weightCells.forEach(td => {
td.setAttribute('contentEditable', true);
td.addEventListener ("change", calcSum());
});
}
function calcSum() {
let sum=0;
let weightCells = document.querySelectorAll("table tr td ~ td");
let count = weightCells.length-1;
for (i=0; i<count; i++) {
sum += parseInt(weightCells[i].innerHTML) || 0;
}
weightCells[count].innerHTML = sum;
}
myFunction();
table {
width: 100%;
}
table,
tr,
th,
td {
border: 1px solid gray;
border-collapse: collapse;
font-family: Arial;
margin: 5px;
}
<table>
<caption>Weight Calculator</caption>
<tr class="cell">
<th>Person</th>
<th>Weight (kg)</th>
</tr>
<tr class="cell">
<td>Jack</td>
<td id="jack" oninput="myFunction()">1</td>
</tr>
<tr class="cell">
<td>John</td>
<td id="john" oninput="myFunction()">2</td>
</tr>
<tr class="cell">
<td>Joe</td>
<td id="joe" oninput="myFunction()">3</td>
</tr>
<tr class="cell">
<td>Total</td>
<td id="total"></td>
</tr>
</table>
You can select the whole table, then use querySelectorAll to get all rows then for each rows change the contenteditable for the second td like this
codepen
let table = document.getElementById('table')
let rows = table.querySelectorAll('tr')
rows.forEach(row => {
let tds = row.querySelectorAll('td')
// all the cells of the row
if (tds.length > 0) { // if it is not the header
tds[1].contentEditable = true
// change the contenteditable
}
})
(you need to add an id to your table in case you have more than one table)
<table id="table">
...
</table>
I am trying to get the text which is in the next element of searched element by string.Let me explain by code
<table id="myTable">
<tbody>
<tr>
<th>Name</th>
<td>foo</td>
</tr>
<tr>
<th>age</th>
<td>20</td>
</tr>
</tbody>
</table>
I have to search string if "age" exist. then return 20 as its value.
I tried to search string by contains: But unable to access value
You could use jQuery next() and contains selector to achieve what you need.
$(document).ready(function() {
console.log($("th:contains(age)").next().html());
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="myTable">
<tbody>
<tr>
<th>Name</th>
<td>foo</td>
</tr>
<tr>
<th>age</th>
<td>20</td>
</tr>
</tbody>
</table>
This solution will go through all the elements that are children of trs and check to see that their text is equal to the search. If it is equal, it assigns the next element to nextElem.
let search = "age";
let nextElem;
$('#myTable tr').children().each(function() {
if ($(this).text() === search)
nextElem = $(this).next();
});
console.log(nextElem.text())
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="myTable">
<tbody>
<tr>
<th>Name</th>
<td>foo</td>
</tr>
<tr>
<th>age</th>
<td>20</td>
</tr>
</tbody>
</table>
You've already set up the table to display name-value pairs, where each name is contained within <th>...</th> and its corresponding value is contained within <td>...</td>.
So one approach to this is straightforward Document Object Model navigation, using:
getElementsByTagName('th')
getElementsByTagName('td')
var table = document.getElementsByTagName('table')[0];
var button = document.getElementsByTagName('button')[0];
var summary = document.getElementsByClassName('summary')[0];
var searchedFor = summary.getElementsByTagName('p')[0];
var correspondingResult = summary.getElementsByTagName('p')[1];
function displayResult() {
var returnValue = '';
var searchString = document.getElementsByTagName('input')[0].value;
var lowerCaseSearchString = searchString.toLowerCase();
var tableRows = document.getElementsByTagName('tr');
for (var i = 0; i < tableRows.length; i++) {
var name = tableRows[i].getElementsByTagName('th')[0].textContent.toLowerCase();
if (name === lowerCaseSearchString) {
returnValue = tableRows[i].getElementsByTagName('td')[0].textContent;
}
if (returnValue === '') {
returnValue = 'No Matches';
}
}
searchedFor.textContent = 'You searched for... ' + '"' + searchString + '"';
correspondingResult.textContent = 'The corresponding result is... ' + '"' + returnValue + '"';
}
button.addEventListener('click',displayResult,false);
table, .search-panel {
display: inline-block;
vertical-align: top;
margin-right: 24px;
}
table {
border: 2px solid rgb(127,127,127);
}
th, td {
padding: 12px;
}
th {
text-align: left;
background-color: rgb(191,191,191);
}
th::after {
content:':';
}
.search-results p span {
font-weight:bold;
}
<table>
<tbody>
<tr>
<th>Name</th>
<td>Foo</td>
</tr>
<tr>
<th>Age</th>
<td>20</td>
</tr>
</tbody>
</table>
<div class="search-panel">
<form>
<input type="text" placeholder="Enter your string here..." value="" />
<button type="button">Search for String</button>
</form>
<div class="summary">
<p>You searched for... </p>
<p>The corresponding result is... </p>
</div>
</div>
I have tables which are updating via dynamic ways. I want to change specific texts to colorful ones, during search operation in real time.
In this example, as you can see, it's possible to make them colorful for all document via smart way.
And this second example shows perfectly that how you can create a real time search engine for table.
Now, here is the question: Is it possible to make that real time search's results colorfull? Not the whole column or row. I just need to change color value of input 's matched value. Long story short, how can I modify the 2nd example for this?
Here is the code: http://jsfiddle.net/e2106b62/2/
Classic tables I've used in HTML:
<table style="width:100%">
<tr>
<td>Jill</td>
<td>Smith</td>
<td>50</td>
</tr>
<tr>
<td>Eve</td>
<td>Jackson</td>
<td>94</td>
</tr>
</table>
<input id="search">
JS I'm trying to use for search (You can find this on 2nd example link):
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();
});
And another JS which I need to implement in search module:
$(this).css('color', 'red');
Building off your examples, this does the trick.
Working fiddle
var $cells = $('#table td');
$('#search').keyup(function() {
var input = $(this).val();
var val = '^(?=.*\\b' + $.trim(input).split(/\s+/).join('\\b)(?=.*\\b') + ').*$',
reg = RegExp(val, 'i'),
text;
$cells.show().filter(function() {
text = $(this).text().replace(/\s+/g, ' ');
if(!reg.test(text) || input == ''){
$(this).css('color','black');
} else {
$(this).css('color','green');
}
});
});
body {padding: 20px;}
input {margin-bottom: 5px; padding: 2px 3px; width: 209px;}
td {padding: 4px; border: 1px #CCC solid; width: 100px;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" id="search" placeholder="Type to search">
<table id="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>
Just wanted to add a different highlight option. This way it will highlight only the matched text, case insensitive. You can change the css class to higlight it the way you want, like changing background-color too.
Working JSFiddle
$('#search').keyup(function() {
$(".highlight").removeClass("highlight");
var val = $.trim($(this).val()).replace(/ +/g, ' ').toLowerCase();
$('table tr').hide().filter(function() {
var text = $(this).text().replace(/\s+/g, ' ').toLowerCase();
return ~text.indexOf(val);
}).show().find("td").each(function(){
var start = $(this).text().toLowerCase().indexOf(val);
if(start !== -1){
var end = val.length;
var start_text = start != 0 ? $(this).text().substring(0,start) : "";
var end_text = $(this).text().substring(start + end);
var match = $(this).text().substring(start, start + end);
$(this).html(start_text+'<span class="highlight">'+match+'</span>'+end_text);
}
});
});
I have Add button and 6 columns. When I click on add button it generates row dynamically, and delete likewise. problem is I want to use 2 columns to copy the content of one textbox into another. I can do simply for fixed columns but how can I do this for dynamic textbox.
If i write 2 in Amount column and keyup tab, then 2 should come in Total Column. It should happen in every dynamic row.
Kindly tell.
I have done it using jQuery. Please have a look at it. Please check keyup event handler which works with dynamically added rows also. Hope it will help you.
function addRow(){
//for adding rows dynamically
var tableElement = document.getElementById("mytable");
var currentTrLength = tableElement.getElementsByTagName("tr").length;
var currentTrIndex = currentTrLength-1; //id are ending with _0, _1 and so on
var rowRef = tableElement.getElementsByTagName("tr")[1].cloneNode(true);
var amountTextElement = rowRef.getElementsByClassName("Amount")[0];
var totalTextElement = rowRef.getElementsByClassName("Total")[0];
amountTextElement.id = "Amount_"+currentTrIndex;
totalTextElement.id = "Amount_"+currentTrIndex;
amountTextElement.value = "";
totalTextElement.value = "";
document.getElementById("mytable").appendChild(rowRef)
}
function copy(obj){
var current = obj;
var currentTr = current.parentElement.parentElement;
var currentTotalElem = currentTr.getElementsByClassName("Total")[0];
currentTotalElem.value = current.value;
}
function calculatesum(){
}
table, th, td {
border: 1px solid black;
border-collapse: collapse;
}
th, td {
padding: 5px;
}
<button class="addRow" onclick="addRow()">Add Row</button>
<br/><br/>
<table id="mytable" style="width:90%">
<tr>
<th>Column1</th>
<th>Column2</th>
<th>Column3</th>
<th>Column4</th>
<th>Amount</th>
<th>Total</th>
</tr>
<tr>
<td>Eve</td>
<td>Jackson</td>
<td>94</td>
<td>Test</td>
<td><input name='Amount[]' class='form-control Amount' style='width:180px' type='text' onblur='calculatesum();' onkeyup='copy(this);' id='Amount_0' size='10' /></td>
<td><input name='Total[]' style='width:180px' class='form-control Total' type='text' id='Total_0' size='10' /></td>
</tr>
</table>
</body>
</html>
Have a look at below code:
in your <td> code you have call to copy() on onblur event as onkeyup='calculatesum();' onblur='copy(this);' I have passed current element's reference by this
var cc = 1;
function addTableRow(jQtable){
var id=cc;
jQtable.each(function() {
var data = "<tr><td class='Arial_4C8966'><input name='Amount[]' class='form-control Amount[]' style='width:180px' type='text' onkeyup='calculatesum();' onblur='copy(this);' id='Amount_" + cc + "' size='10' /></td><td class='Arial_4C8966'><input name='Total[]' style='width:180px' class='form-control Total' type='text' id='Total_" + cc + "' size='10' /></td></tr>";
var $table = $(this);
var n = $('tr:last td', this).length;
var tds = data;
cc++;
if ($('tbody', this).length > 0)
{
$('tbody', this).append(tds);
}
else
{
$(this).append(tds);
}
});
}
function copy(obj){
var current = obj;
var currentTr = current.parentElement.parentElement;
var currentTotalElem = currentTr.getElementsByClassName("Total")[0];
currentTotalElem.value = current.value;
}
function calculatesum(){
}
table, th, td {
border: 1px solid black;
border-collapse: collapse;
}
th, td {
padding: 5px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js"></script>
<div class="row clearfix"> <div class="col-md-12 column">
<table class="table table-bordered table-hover" id="dynamicInput">
<tr class="Form_Text_Label">
<td align="center" >AMOUNT*</td>
<td align="center" >TOTAL*</td>
</tr>
</table>
</div>
<fieldset style="width:95%;">
<div>
<div class="col-sm-6">
<input type="button" value="Add" class="frmBtns" onClick="addTableRow($('#dynamicInput'));" style="font-family:Calibri; font-size:15px; " > <br>
</div>
</div>
</fieldset>
I'm trying to use a few lines of code from another StackOverflow user to get a simple live search on my phonenumber table. (How to perform a real time search and filter on a HTML table)
I have added jQuery to my script, and copied and pasted every single line of code (the fruits as in the example) but Chrome nor IE does the job. I'm pretty stuck, but I think that there is something that I simply don't see.
Here is my code:
<html>
<head>
<title>Test</title>
<script src="//code.jquery.com/jquery-1.11.3.min.js"></script>
<script src="//code.jquery.com/jquery-migrate-1.2.1.min.js"></script>
<script>
var $rows = $('#table tr');
$('#search').keyup(function() {
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();
});
</script>
<style>
body {padding: 20px;}
input {margin-bottom: 5px; padding: 2px 3px; width: 209px;}
td {padding: 4px; border: 1px #CCC solid; width: 100px;}
</style>
</head>
<body>
<input type="text" id="search" placeholder="Type to search">
<table id="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>
</body>
</html>
The demo posted on JsFiddle works inside of JsFiddle. If I go to the Full-Screen JsFiddle Demo it doesn't, same as my own piece of code on my webserver... Any help?
This is not an answer to your question, but perhaps a solution to your problem.
Try this alternate example:
jsFiddle Demo
HTML:
<label for="kwd_search">Search:</label> <input type="text" id="kwd_search" value=""/>
<table id="myTable" class="test1" border="1" style="border-collapse:collapse">
<thead>
<tr>
<th>Name</th>
<th>Sports</th>
<th>Country</th>
</tr>
</thead>
<tbody>
<tr>
<td>Sachin Tendulkar</td>
<td>Cricket</td>
<td>India</td>
</tr>
<tr>
<td>Tiger Woods</td>
<td>Golf</td>
<td>USA</td>
</tr>
<tr>
<td>Maria Sharapova</td>
<td>Tennis</td>
<td>Russia</td>
</tr>
<tr>
<td>Mario Andretti</td>
<td>Formula One</td>
<td>Italy</td>
</tr>
</tbody>
</table>
javascript/jQuery:
$(document).ready(function(){
// Write on keyup event of keyword input element
$("#kwd_search").keyup(function(){
// When value of the input is not blank
var term=$(this).val()
if( term != "") {
// Show only matching TR, hide rest of them
console.log( $(this).val())
$("table tbody>tr").hide();
var term=
$("td").filter(function(){
return $(this).text().toLowerCase().indexOf(term ) >-1
}).parent("tr").show();
} else {
// When no input or clean again, show everything
$("tbody>tr").show();
}
});
});
Here is a JSFiddle Fullscreen
All I did was update the jQuery reference to 1.10.1 as you have 1.7.1
$('#search').on('keyup', function () {
var $rows = $('#table tr');
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();
});