Table Cell (td) child? - javascript

I am trying to search a table cell that has a child (textarea) in it. I have tried
td.children.value,
td.childNodes.value,
td.firstChild.value,
td.lastChild.value,
td.textarea.value... none of these have worked. here is my snippet:
addCell = function() {
var table = document.getElementById('myTable');
var tr = document.createElement('tr');
var td = document.createElement('td');
var txt = document.createElement('textarea');
table.appendChild(tr);
tr.appendChild(td);
td.appendChild(txt);
}
searchT = function() {
var table = document.getElementById('myTable');
var search = document.getElementById('search');
var tr = document.getElementsByTagName('tr');
var td = document.getElementsByTagName('td');
if (search.value === td.textarea.value) {
alert('hello');
}
/* I have tried:
td.childNodes.value
td.children.value
td.firstChild.value
td.lastChild.value
td.textarea.value
*/
}
td {
background-color: #ccc;
width: 100px;
height: 20px;
}
textarea {
resize: none;
}
.search {
width: 100px;
}
<button onclick="addCell()">
add
</button>
<input id="search" placeholder="search">
<button onclick="searchT()">
search
</button>
<table id="myTable">
<tr>
<td>
<textarea></textarea>
</td>
</tr>
</table>

When you do document.getElementsByTagName(), this returns a list of all the items on the document which contain that tag name. In order to find out if it exists in that list (I'm assuming that's what you want) then you have to loop for the list returned by getElementsByTagName().
I'm also assuming that you want to add a table with whatever you entered in the <input> so I added that in the addCell().
addCell = function() {
var table = document.getElementById('myTable');
var tr = document.createElement('tr');
var td = document.createElement('td');
var txt = document.createElement('textarea');
var search = document.getElementById('search'); // Get value in input field
table.appendChild(tr);
tr.appendChild(td);
txt.innerHTML = search.value; // Set value to table
td.appendChild(txt);
}
searchT = function() {
var search = document.getElementById('search');
var textareas = document.getElementsByTagName('textarea'); // Get the textareas instead
for(var i = 0; i < textareas.length; i++) {
if(search.value === textareas[i].innerHTML) { // If the text matches the search field
console.log("Found: " + search.value + " at index: " + i);
}
}
}
td {
background-color: #ccc;
width: 100px;
height: 20px;
}
textarea {
resize: none;
}
.search {
width: 100px;
}
<button onclick="addCell()">
add
</button>
<input id="search" placeholder="search">
<button onclick="searchT()">
search
</button>
<table id="myTable">
<tr>
<td>
<textarea readonly="readonly">Template</textarea> <!-- This doesn't have to be readonly but I made it Note: readonly="readonly" is only for valid XHTML. It could be left as readonly without the assignment for valid HTML -->
</td>
</tr>
</table>
If you're curious, you can read more about getElementsByTagName() here.

I might start with something like this. The comments should explain what's going on.
// as both functions are using them,
// I can define these outside the functions.
var myTable = document.getElementById("myTable");
var search = document.getElementById('search');
addCell = function() {
// create the references to the new els.
var tr = document.createElement('tr');
var td = document.createElement('td');
var txt = document.createElement('textarea');
// append the new els to my table.
myTable.appendChild(tr);
tr.appendChild(td);
td.appendChild(txt);
}
searchT = function() {
// Get all the td els in my table.
let tdEls = myTable.getElementsByTagName("td");
// Iterate over the array of td els, and
for (let i = 0; i < tdEls.length; i++) {
// get the textarea node if they have one
let textareaEl = tdEls[i].getElementsByTagName("textarea")[0];
// compare the textarea to the search
if (textareaEl.value.includes(search.value)) {
// They match -- do something with them.
console.log(textareaEl.value);
}
}
}
td {
background-color: #ccc;
width: 100px;
height: 20px;
}
textarea {
resize: none;
}
.search {
width: 100px;
}
<button onclick="addCell()">
add
</button>
<input id="search" placeholder="search">
<button onclick="searchT()">
search
</button>
<table id="myTable">
<tr>
<td>
<textarea></textarea>
</td>
</tr>
</table>

Related

Read values from text field individually

I would like to read all values from a text field/text box individually and then write them to a table:
Example:
This is an example of a text I want to read out.
Output:
This
is
an
example
of
a
text
I
want
to
read
out
How can I use a loop to read the text field/textbox?
That is, whenever a space comes the new subsequent value must be in a new line.
String:
var table = document.getElementById("table");
var phrase = "This is an example of a text I want to read out";
var words = phrase.split(" ");
for (var i = 0; i < words.length; i++) {
var tableCol =
`<tr>
<td>${i+1}:</td>
<td>${words[i].replace(/[\.,!\?]/g," ")}<td>
</tr>`;
document.querySelector('table tbody').innerHTML += tableCol;
}
#table {
border: 1px solid;
}
th {
border: 1px solid;
padding: 5px;
}
<table id="table">
<thead>
<th>Number:</th>
<th>Word:</th>
<thead>
<tbody>
</tbody>
</table>
Input:
var table = document.getElementById("table");
var myBtn = document.getElementById("myBtn");
var myInput = document.getElementById("myInput");
myBtn.addEventListener('click', () => {
document.querySelector('tbody').innerHTML = '';
var phrase = myInput.value;
var words = phrase.split(" ");
for (var i = 0; i < words.length; i++) {
var tableCol =
`<tr>
<td>${i+1}:</td>
<td>${words[i].replace(/[\.,!\?]/g," ")}<td>
</tr>`;
document.querySelector('tbody').innerHTML += tableCol;
}
});
input {
margin-bottom: 10px;
width: 300px;
height: 25px;
}
#table {
border: 1px solid;
}
th {
border: 1px solid;
padding: 5px;
}
<input id="myInput" type="text">
<button id="myBtn">Create Table</button>
<table id="table">
<thead>
<th>Number:</th>
<th>Word:</th>
<thead>
<tbody>
</tbody>
</table>
Shorter and removing punctuation
const str = `This is an example of a text I want to read out.`;
document.querySelector('table tbody').innerHTML = str.split(" ")
.map((word,i) => `<tr><td>${i+1}:</td><td>${word.replace(/[\.,!\?]/g,"")}<td></tr>`)
.join("");
<table id="table">
<thead>
<th>Number:</th>
<th>Word:</th>
<thead>
<tbody>
</tbody>
</table>

How to correctly select a div inside a table cell

I have created a function that inserts table row and data by user's request. I was asked to add a small red square (div) in the right corner of table cell, which when clicked, deletes the table row.
I've got so far that I've written a function that removes the table row, but the problem is - it only needs to be done, when the small red div is clicked, not when the table cell is clicked. How could this be achieved? I've tried several ways how to address the div, but none have worked so far.
Would be really grateful for your assistance.
<button class="btn" onclick="createNewTableElement()">Add</button>
<input id="new-item" type="text" value="item">
<table id="main-table" onclick="deleteRow(obj)">
function createNewTableElement() {
var inputField = document.getElementById("new-item");
if (inputField.value == "") {
return;
}
var row = document.createElement("tr");
var cell = document.createElement("td");
var div = document.createElement("div");
var cellText = document.createTextNode(inputField.value);
cell.appendChild(div);
cell.appendChild(cellText);
row.appendChild(cell);
obj = document.getElementById("main-table");
obj.appendChild(row);
}
function deleteRow(e) {
document.getElementById('main-table').deleteRow(e);
}
I made some changes in your code. Removed deleteRow binded on table and add event only on div element, then find parent row element and removed it from table
Does this help you?
function createNewTableElement() {
var inputField = document.getElementById("new-item");
if (inputField.value == "") {
return;
}
var row = document.createElement("tr");
var cell = document.createElement("td");
var div = document.createElement("div");
div.onclick = deleteRow;
var cellText = document.createTextNode(inputField.value);
cell.appendChild(div);
cell.appendChild(cellText);
row.appendChild(cell);
obj = document.getElementById("main-table");
obj.appendChild(row);
}
function deleteRow(e) {
document.getElementById('main-table').removeChild(e.target.parentElement.parentElement);
}
#main-table div {
height: 10px;
width: 10px;
border: 1px solid;
display: inline-block;
margin-right: 10px;
}
<button class="btn" onclick="createNewTableElement()">Add</button>
<input id="new-item" type="text" value="item">
<table id="main-table">
Remove onclick from table:
<button class="btn" onclick="createNewTableElement()">Add</button>
<input id="new-item" type="text" value="item">
<table id="main-table">
Then in same function you are creating row create also red div and event:
function createNewTableElement() {
var inputField = document.getElementById("new-item");
if (inputField.value == "") {
return;
}
var row = document.createElement("tr");
var cell = document.createElement("td");
var div = document.createElement("div");
div.addEventListener('click', function(event) {
// the row call parent (table) and tell removes him self
row.parentNode.removeChild(row);
});
var cellText = document.createTextNode(inputField.value);
cell.appendChild(div);
cell.appendChild(cellText);
row.appendChild(cell);
obj = document.getElementById("main-table");
obj.appendChild(row);
}
my way..
const mainTable = document.querySelector('#main-table tbody')
, btAdd = document.getElementById('btn-Add')
, newItem = document.getElementById('new-item')
;
newItem.oninput=()=>
{
btAdd.disabled = (newItem.value === '')
}
btAdd.onclick=()=>
{
let newCell = mainTable.insertRow().insertCell()
;
newCell.textContent = newItem.value
newCell.appendChild( document.createElement('div'))
newItem.value = ''
btAdd.disabled = true
}
mainTable.onclick=e=>
{
if (!e.target.matches('td div')) return
mainTable.deleteRow( e.target.closest('tr').rowIndex -1 )
}
#main-table {
border-collapse: collapse;
margin: 1em;
}
#main-table thead {
background-color: cadetblue;
}
#main-table th {
padding: .7em;
width:20em;
}
#main-table td {
border: 1px solid grey;
padding: .5em;
}
#main-table td div {
display: block;
float: right;
width: 1em;
height: 1em;
background-color: crimson;
cursor: pointer;
}
#main-table td div:hover {
border: 1px solid blue;
}
<button id="btn-Add" disabled >Add</button>
<input id="new-item" type="text" placeholder="item">
<table id="main-table">
<thead> <th>items list</th> </thead>
<tbody> </tbody>
</table>

sending attachment in javascript object server-side Google Code.gs

Anyone know how I can send an array of objects that includes an attachment?
I'm working on a WebApp that captures weekly mileage entries. At the end of the week, a user can submit their miles driven and attach a parking receipt.
I was able to send the array of object to the server-side Code.gs UNTIL I tried to include a file input for each day.
document.addEventListener("DOMContentLoaded", function() {
document.getElementById("tripPost").addEventListener("click", addLine);
document.getElementById("submitAll").addEventListener("click", addRecord);
});
//global variables for next functions
var submit = document.getElementById("tripPost");
var submittedTable = document.getElementById("submitted-data");
var mainEntry = document.getElementById("entry-table");
var submitAll = document.getElementById("submitAll");
submittedTable.addEventListener("click", addLine);
submittedTable.addEventListener("change", fileUpload);
function addLine() {
document.getElementById("table-container").style.display = "block";
var date = document.getElementById("date1").value;
var efirst = document.getElementById("efirst").value;
var elast = document.getElementById("elast").value;
var row = document.createElement("tr");
var col1 = document.createElement("td");
col1.appendChild(document.createTextNode(date));
col1.className = "postDateClass";
var col2 = document.createElement("td");
col2.appendChild(document.createTextNode(efirst));
col2.className = "postEfirstClass";
var col3 = document.createElement("td");
col3.appendChild(document.createTextNode(elast));
col3.className = "postElastClass";
var col4 = document.createElement("td");
row.appendChild(col1);
row.appendChild(col2);
row.appendChild(col3);
row.appendChild(col4);
submittedTable.appendChild(row);
var uniqueID = "id" + new Date().getTime();
var upload = document.createElement("input");
upload.type = "file";
upload.id = uniqueID;
upload.name = "myReceipt";
upload.className = "uploadClass";
var label = document.createElement("label");
label.innerHTML = "upload me please!";
label.htmlFor = uniqueID;
label.className = "custom-file-upload";
var form = document.createElement("form");
form.appendChild(upload);
form.appendChild(label);
col4.appendChild(form);
}
function fileUpload(e) {
if (e.target.className === "uploadClass") {
if (e.target.value) {
var span = document.createElement("span");
span.className = "uploadSpanText";
span.innerHTML = e.target.value.match(/[\/\\]([\w\d\s\.\-\(\)]+)$/)[1];
e.target.parentElement.appendChild(span);
e.target.nextElementSibling.innerHTML = "uploaded!";
e.target.nextElementSibling.style.border = "1px solid #a8e0b4";
e.target.nextElementSibling.style.color = "#8bca9e";
}
}
}
function getFile(file) {
return new Promise(resolve => {
const fr = new FileReader();
fr.onload = e => {
const data = e.target.result.split(",");
const obj = {
fileName: file.name,
mimeType: data[0].match(/:(\w.+);/)[1],
data: data[1]
};
resolve(obj);
};
if (file) {
fr.readAsDataURL(file);
} else {
reject("No File");
}
});
}
//gathers inputs and stores values in an object and runs the "addLine" function
async function addRecord(e) {
var dateLines = document.querySelectorAll(".postDateClass");
var eFirstLines = document.querySelectorAll(".postEfirstClass");
var eLastLines = document.querySelectorAll(".postElastClass");
var attachmentLines = document.querySelectorAll(".uploadClass");
var mileageData = [];
for (var i = 0; i < dateLines.length; i++) {
var mileageLines = {};
mileageLines.travelDate = dateLines[i].textContent;
mileageLines.firstName = eFirstLines[i].textContent;
mileageLines.lastName = eLastLines[i].textContent;
mileageLines.receipt = await getFile(attachmentLines[i].parentNode);
mileageData.push(mileageLines);
}
//send object to google. resets input elements
google.script.run.userMileageSubmit(mileageData);
}
Here is the HTML for the code that I'm working with.
<div id="entry-table">
<table>
<h3 style="text-align:left"><u><b>Enter mileage information below.</b></u><br></h3>
<thead>
<tr>
<th >Date</th>
<th >First:</th>
<th >Last:</th>
</tr>
</thead>
<tbody id="table-data">
<tr>
<td>
<div class="disabled-results" id="date">
<input placeholder="Start Date" id="date1" type="text" class="datekeeper" required>
<label for="date1" class="active">Date:</label>
</div>
<td>
<div class="disabled-results">
<input id ="efirst" type="text" class="validate" >
<label for="efirst" class="active">First:</label>
</div>
</td>
<td>
<div class="disabled-results">
<input id ="elast" type="text" class="validate" >
<label for="elast" class="active">Last:</label>
</div>
</td>
<td>
<div id="status">
<button id="tripPost" class="waves-effect waves-light btn-small blue darken-3">Add Trip</button>
</div>
</td>
</tr>
</tbody>
</table>
</div><!---CLOSE ROW --->
<div class="autocomplete" id="table-container" style=display:none>
<table>
<thead>
<tr id="header-titles">
<th >Date</th>
<th >First:</th>
<th >Last:</th>
<th >Receipt </th>
</tr>
</thead>
<form>
<tbody class="form" id="submitted-data">
<div>
<p>Thank you!</p>
</div>
</form>
</tbody>
</table>
<br><br>
</div>
<center>
<div class="row">
<button id="submitAll" class="waves-effect waves-light btn btn-large blue darken-3"><i class="material-icons left">directions_car</i>Submit All Mileage!</button>
</div>
</center>
Here is the CSS
body {
background-color: lightblue;
margin-top: 80px;
margin-bottom: 80px;
margin-right: 80px;
margin-left: 80px;
}
h1{
color: black;
text-align: center;
}
div.disabled-results{
width: 175px;
height: 80px;
padding: 5px;
margin: 5px;
display: inline-table;
box-sizing: border-box;
text-align: center;
}
input[type="file"]{
display: none;
}
.custom-file-upload{
border: 2px solid #000;
width: 85px;
display: inline-block;
padding: 2px 1px;
cursor: pointer;
text-align: center;
}
div.autocomplete{
width: 55px;
height: 80px;
padding: 5px;
margin: 5px;
display: inline-table;
box-sizing: border-box;
text-align: center;
}
I got everything else to work, except sending the attachment (if any) in each line as part of the object.
I am sure that it can be done. I tried to implement the solution from this video which shows you how to upload a file, but I don't use the onclick or this.parentNode since I'm not uploading immediately after selecting a file and instead doing a bulk upload when a user has made numerous entries.
Any help in understanding how this should work would be greatly appreciated.
Thank you.
Please see https://developers.google.com/apps-script/guides/html/communication#forms. You'll want to send the form element to the server side script.
Given that you push several mileageLines into the array mileageData, your data will look like this:
[{...,claimMiles=claimMilesLines[0].textContent; receipt=attachmentLines[0].files[0]}, {...,claimMiles=claimMilesLines[1].textContent;, receipt=attachmentLines[1].files[0]},...]
This means that you need to access your data as array elements
var file1 = responses[0].receipt;
var file2 = responses[1].receipt;
Or
for( var i = 0; i < responses.length; i++){
var file = responses[i].receipt;
...
var createFile = mainFolder.createFile("formfile", file);
}

Add/Delete table rows using JavaScript

Hello I'm trying to follow this
Add/Delete table rows dynamically using JavaScript
My goal is to scan/enter in barcodes that will make an HTML table. The "user", the "station" will be a variable. The "container" will be entered in once and saved. The only changing item will be scan which is the new row. I've gotten it to add the row but I can't add the variables into their respective columns. Any guidance on this would be great!
Here is my HTML FORM
<form id="trackForm"
autocomplete='off'>
<div class="row">
<div class="col col-lg">
<div id="s1group" class="input-group mb-2">
<div class="input-group-prepend">
<div class="input-group-text">
<b>CONTAINER: </b>
</div>
</div>
<input id="container" class="form-control"
type="text"
placeholder="Scan container."
onpropertychange="checkScanInput();">
</input>
<div class="invalid-feedback">
This field cannot be empty!
</div>
</div>
<div id="s2group" class="input-group">
<div class="input-group-prepend">
<div id="s2label" class="input-group-text font-weight-bold">
SCAN:
</div>
</div>
<input id="scan" class="form-control"
type="text"
placeholder="Scan entry or code."
onpropertychange="checkScanInput();">
</input>
<div class="invalid-feedback">
This field cannot be empty!
</div>
</div>
</div>
</div>
<div class="col-sm-2">
<button id="trackSubmit" class="btn btn-dark font-weight-bold"
type="submit"
style="background-color: #005997; display:none;">
</button>
</div>
</form>
This is the table:
<table id="resultTable" class="table display compact">
<thead>
<tr>
<th>User</th>
<th>Station</th>
<th>Scan</th>
<th>Container</th>
<th>Date/Time</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
Below is the Javascript
var thisStation = stationList[ssv][1];
var sessionUser = document.getElementById('userDisplay').textContent;
var table = document.getElementById("resultTable");
var rowCount = table.rows.length;
var colCount = table.rows[0].cells.length;
var row = table.insertRow(rowCount);
for(var i = 0; i < colCount; i++) {
var newcell = row.insertCell(i);
newcell.innerHTML = table.rows[0].cells[i].innerHTML;
}
row = table.insertRow(table.rows.length);
for(var i = 0; i < colCount; i++) {
var newcell = row.insertCell(i);
if(i == (colCount - 1)) {
newcell.innerHTML = "<INPUT type=\"button\" value=\"Delete Row\" onclick=\"removeRow(this)\"/>";
} else {
newcell.innerHTML = table.rows[3].cells[i].innerHTML;
}
}
Check out the code snippet, run it and see if this works for you. Obviously, you can/ should adjust it to your (specific) needs, but you have your table with the ability to add rows, input data, remove correct rows as you please, and also the ability to "submit" your data.
// ARRAY FOR HEADER.
const arrHead = ['#', 'One', 'Two', 'Three'];
// SIMPLY ADD OR REMOVE VALUES IN THE ARRAY FOR TABLE HEADERS.
// FIRST CREATE A TABLE STRUCTURE BY ADDING A FEW HEADERS AND
// ADD THE TABLE TO YOUR WEB PAGE.
function createTable() {
var empTable = document.createElement('table');
empTable.setAttribute('id', 'empTable'); // SET THE TABLE ID.
var tr = empTable.insertRow(-1);
for (var h = 0; h < arrHead.length; h++) {
var th = document.createElement('th'); // TABLE HEADER.
th.innerHTML = arrHead[h];
tr.appendChild(th);
}
var div = document.getElementById('cont');
div.appendChild(empTable); // ADD THE TABLE TO YOUR WEB PAGE.
}
// ADD A NEW ROW TO THE TABLE
function addRow() {
var empTab = document.getElementById('empTable');
var rowCnt = empTab.rows.length; // GET TABLE ROW COUNT.
var tr = empTab.insertRow(rowCnt); // TABLE ROW.
tr = empTab.insertRow(rowCnt);
for (var c = 0; c < arrHead.length; c++) {
var td = document.createElement('td'); // TABLE DEFINITION.
td = tr.insertCell(c);
if (c == 0) { // FIRST COLUMN.
// ADD A BUTTON.
var button = document.createElement('input');
// SET INPUT ATTRIBUTE.
button.setAttribute('type', 'button');
button.setAttribute('value', 'Remove');
button.setAttribute('id', 'rm');
// ADD THE BUTTON's 'onclick' EVENT.
button.setAttribute('onclick', 'removeRow(this)');
td.appendChild(button);
}
else {
// CREATE AND ADD TEXTBOX IN EACH CELL.
var ele = document.createElement('input');
ele.setAttribute('type', 'text');
ele.setAttribute('value', '');
td.appendChild(ele);
}
}
}
// DELETE TABLE ROW.
function removeRow(oButton) {
var empTab = document.getElementById('empTable');
empTab.deleteRow(oButton.parentNode.parentNode.rowIndex); // BUTTON -> TD -> TR.
}
// EXTRACT AND SUBMIT TABLE DATA.
function sumbit() {
var myTab = document.getElementById('empTable');
var values = new Array();
// LOOP THROUGH EACH ROW OF THE TABLE.
for (row = 1; row < myTab.rows.length - 1; row++) {
for (c = 0; c < myTab.rows[row].cells.length; c++) { // EACH CELL IN A ROW.
var element = myTab.rows.item(row).cells[c];
if (element.childNodes[0].getAttribute('type') == 'text') {
values.push(element.childNodes[0].value);
}
}
}
console.log('Data send:\n' + values);
}
table {
width: 70%;
font: 17px Calibri;
}
table, th, td
{
border: solid 1px #DDD;
border-collapse: collapse;
padding: 2px 3px;
text-align: center;
color: grey;
}
#addRow {
color: green;
font-weight: bold;
}
#bt {
color: blue;
font-style: italic;
font-weight: bold;
}
#rm {
color: red;
font-weight: bold;
}
<body onload="createTable()">
<p>
<input
type="button"
id="addRow"
value="Add New Row"
onclick="addRow()" />
</p>
<!--THE CONTAINER WHERE WE'll ADD THE DYNAMIC TABLE-->
<div id="cont"></div>
<p>
<input
type="button"
id="bt"
value="Sumbit Data"
onclick="sumbit()" />
</p>
</body>

How to change the color of particular characters of string using JavaScript?

I am using table search functionality using this code -
https://www.w3schools.com/howto/tryit.asp?filename=tryhow_js_filter_table.
When user search for any row data using some search characters like "Jac", I want to change the color of these 3 characters only and want to show entire row. How can I change the color of these 3 characters? Or search input characters?
EDIT - My code is:
$("#searchBox").keyup(function() {
var input, filter, table, tr, td, i;
input = document.getElementById("searchBox");
filter = input.value.toUpperCase();
if (filter.length > 1) {
table = document.getElementById("myTable");
tr = table.getElementsByTagName("tr");
for (i = 0; i < tr.length; i++) {
td = tr[i].getElementsByTagName("td")[1];
if (td) {
if (td.innerHTML.toUpperCase().indexOf(filter) > -1) {
var regx = new RegExp(filter, "g");
var newstring = td.innerHTML.replace(regx, '<span class="highlight">' + filter + '</span>');
td.innerHTML = newstring;
tr[i].style.display = "";
} else {
tr[i].style.display = "none";
}
}
}
} else {
table = document.getElementById("myTable");
tr = table.getElementsByTagName("tr");
for (i = 0; i < tr.length; i++) {
tr[i].style.display = "";
}
}
});
Output of above code is not correct. It will work only when length of search string is more than 1. If I enter 3 characters it failed.
Might be an overkill approach. But this how I got it working.
The technique:
1- Get the original table (as a whole DOM) into a JS variable
2- Clone that variable into another JS variable.
3- The clone is used as a reference. Will remain intact never be modified.
4- The highlight works by extracting the found phrase, wrap with a <span> having that span is given a certain CSS to stand out from the rest of the text.
The reason behind this is that, if we edit the original table, and then we try to search again, the HTML tag that got inserted will be included in the searched terms and therefore, the search will break down.
We will be searching the clone always, then will get the text from the clone, process it, and then apply the new processed phrase to the original table. In other words, If the searched phrase is found in the clone object, its content will be copied over to the original table.
If I were to do this again, I would replace the whole thing with JQuery. But anyhow, this code needs to be optimized.
var originalTable = document.getElementById("myTable");
var realTr = originalTable.getElementsByTagName("tr");
var cloneTable = originalTable.cloneNode(true);
var cloneTr = cloneTable.getElementsByTagName("tr");
function myFunction() {
var input, filter, cloneTd, cloneTdValue, realTd, i, inputValue, inputValueUpper;
input = document.getElementById("myInput");
inputValue = input.value;
inputValueUpper = inputValue.toUpperCase();
for (i = 0; i < cloneTr.length; i++) {
cloneTd = cloneTr[i].getElementsByTagName("td")[0];
if (cloneTd) {
var cloneTdValue = cloneTd.innerHTML;
var cloneTdValueUpper = cloneTdValue.toUpperCase();
var index = cloneTdValueUpper.indexOf(inputValueUpper);
if (index > -1) {
var newStr = wrapStuff(inputValue, cloneTdValue, index);
realTr[i].style.display = "";
realTd = realTr[i].getElementsByTagName("td")[0];
realTd.innerHTML = newStr;
} else {
realTr[i].style.display = "none";
}
}
}
}
function wrapStuff(input, tdStr, index) {
if (input.length === 0)
{
return tdStr;
}
var before, after, searched, extractLen, extractedVal, newString;
extractLen = index + input.length;
before = tdStr.substring(0, index);
after = tdStr.substring(extractLen, tdStr.length);
var newIndex = after.indexOf(input);
//Recursive function: yeah, my head got spinning.
//this is to apply the same code to the second half of the spliced string, because indexOf will only find the first occurance.
if (newIndex > -1) {
after = wrapStuff(input, after, newIndex);
}
extractedVal = tdStr.substring(index, extractLen);
newString = before + "<span class=\"highlight\">" + extractedVal + "</span>" + after;
return newString;
}
* {
box-sizing: border-box;
}
#myInput {
background-image: url('/css/searchicon.png');
background-position: 10px 10px;
background-repeat: no-repeat;
width: 100%;
font-size: 16px;
padding: 12px 20px 12px 40px;
border: 1px solid #ddd;
margin-bottom: 12px;
}
#myTable {
border-collapse: collapse;
width: 100%;
border: 1px solid #ddd;
font-size: 18px;
}
#myTable th, #myTable td {
text-align: left;
padding: 12px;
}
#myTable tr {
border-bottom: 1px solid #ddd;
}
#myTable tr.header, #myTable tr:hover {
background-color: #f1f1f1;
}
.highlight {
color: red;
}
<body>
<h2>My Customers</h2>
<input type="text" id="myInput" onkeyup="myFunction()" placeholder="Search for names.." title="Type in a name">
<table id="myTable">
<tr class="header">
<th style="width:60%;">Name</th>
<th style="width:40%;">Country</th>
</tr>
<tr>
<td>Alfreds Futterkiste</td>
<td>Germany</td>
</tr>
<tr>
<td>Berglunds snabbkop</td>
<td>Sweden</td>
</tr>
<tr>
<td>Island Trading</td>
<td>UK</td>
</tr>
<tr>
<td>Koniglich Essen</td>
<td>Germany</td>
</tr>
<tr>
<td>Laughing Bacchus Winecellars</td>
<td>Canada</td>
</tr>
<tr>
<td>Magazzini Alimentari Riuniti</td>
<td>Italy</td>
</tr>
<tr>
<td>North/South</td>
<td>UK</td>
</tr>
<tr>
<td>Paris specialites</td>
<td>France</td>
</tr>
</table>
<script>
</script>
</body>
Capture the search phrase (the word you are searching or looking for). Capture the search area (the table or paragraph you are searching into). Look into the search area to see if you can find the search phrase. Once it exists, replace with a string that has an HTML element tag surrounding it.
Replace the searched word with the same word but wrapped in a span that has certain CSS class. Use CSS to customize the look.
var toLookInto = $("#toLookInto").html();
$("#toFind").on("keyup", function() {
var toFind = $("#toFind").val();
var regx = new RegExp(toFind, "g");
var newstring = toLookInto.replace(regx, '<span class="highlight">' + toFind + '</span>')
$("#toLookInto").html(newstring)
});
.highlight {
color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<p id="toLookInto">
dummy text foo bar cat mewo dummy text foo bar cat mewo dummy text foo something odd bar cat mewo dummy text foo bar cat mewo
</p>
<br>
<input type "text" id="toFind" />
<lable>The text field will be triggered on every key pressed</label>

Categories