datepicker not working on cloned rows - javascript

i found this zebra datepicker but my problem is that dates are not functional on cloned rows ... here is my fiddle code:
html
<DIV id="mainContent_pnlEmploymentHistory">
<form id="form1" name="form1" method="post" action="value.php">
<TABLE id="dataTable">
<TBODY>
<TR>
<TD style="width: 310px; height: 20px; text-align: center;">Name of Employer</TD>
<TD style="width: 430px; height: 20px; text-align: center;"> Employer Address</TD>
<TD style="width: 150px; height: 20px; text-align: center;">FROM</TD>
<TD style="width: 150px; height: 20px; text-align: center;">TO</TD></TR>
<TR class="row_to_clone_fw_emp">
<TD style="width: 310px; height: 20px; text-align: center;">
<input type="text" id="fwemployer" name="fwemployer[]" style="width:300px"/>
</TD>
<TD style="width: 430px; height: 20px; text-align: center;">
<input type="text" id="fwempaddress" name="fwempaddress[]" style="width:100%"/></TD>
<TD>
<input id="datepicker-example7-start" type="text" name="datefrom[]"/></TD>
<TD>
<input id="datepicker-example7-end" type="text" name="dateto[]"/></TD>
</TR>
</TBODY>
</TABLE>
<table>
<tr>
<td colspan="3" align="right"><INPUT type="button" value="Add Row" id="addrow" onclick="addRowfwemp(); return false;"/></td>
<td colspan="4" align="right"><input type="submit" name="Submit" value="Submit" /></td>
</tr>
</table>
</form>
</DIV>
javascript
$(document).ready(function() {
$('#datepicker-example7-start').Zebra_DatePicker({
direction: false,
pair: $('#datepicker-example7-end')
});
$('#datepicker-example7-end').Zebra_DatePicker({
direction: true
});
});
$(document).ready(function(){
$( "#addrow" ).click(function() {
var zdp = $('#datepicker-example7-start').data('Zebra_DatePicker');
var zdp1 = $('#datepicker-example7-end').data('Zebra_DatePicker');
zdp.destroy();
zdp1.destroy();
});
});
function addRowfwemp() {
/* Declare variables */
var elements, templateRow, rowCount, row, className, newRow, element;
var i, s, t;
/* Get and count all "tr" elements with class="row". The last one will
* be serve as a template. */
if (!document.getElementsByTagName)
return false; /* DOM not supported */
elements = document.getElementsByTagName("tr");
templateRow = null;
rowCount = 0;
for (i = 0; i < elements.length; i++) {
row = elements.item(i);
/* Get the "class" attribute of the row. */
className = null;
if (row.getAttribute)
className = row.getAttribute('class');
if (className === null && row.attributes) { // MSIE 5
/* getAttribute('class') always returns null on MSIE 5, and
* row.attributes doesn't work on Firefox 1.0. Go figure. */
className = row.attributes['class'];
if (className && typeof(className) === 'object' && className.value) {
// MSIE 6
className = className.value;
}
}
/* This is not one of the rows we're looking for. Move along. */
if (className !== "row_to_clone_fw_emp")
continue;
/* This *is* a row we're looking for. */
templateRow = row;
rowCount++;
}
if (templateRow === null)
return false; /* Couldn't find a template row. */
/* Make a copy of the template row */
newRow = templateRow.cloneNode(true);
/* Change the form variables e.g. price[x] -> price[rowCount] */
elements = newRow.getElementsByTagName("input");
for (i = 0; i < elements.length; i++) {
element = elements.item(i);
s = null;
s = element.getAttribute("name");
if (s === null)
continue;
t = s.split("[");
if (t.length < 2)
continue;
s = t[0] + "[" + rowCount.toString() + "]";
element.setAttribute("name", s);
element.value = "";
}
/* Add the newly-created row to the table */
templateRow.parentNode.appendChild(newRow);
return true;
}
http://jsfiddle.net/jakecruz011/ZvsZm/ ... it might be a little broken since i cant upload all external resources but definitely the cloning methods and how datepicker is called is in there ...
the original code can be found here (exxample 7): http://stefangabos.ro/jquery/zebra-datepicker/
files on github is downloadable here: https://github.com/stefangabos/Zebra_Datepicker/
thanks so much for the help! would be much appreciated ...

You need to call the datepicker function again, after append the new elements to DOM
I would suggest you to add a common class for the datepicker input fields.
<TD>
<input id="datepicker-example7-start" type="text" name="datefrom[]" class="dp-start"/>
</TD>
<TD>
<input id="datepicker-example7-end" type="text" name="dateto[]" class="dp-end"/>
</TD>
and call the datepicker function like this just after append the new row.
$('.dp-start:last').Zebra_DatePicker({
direction: false,
pair: $('.dp-end:last')
});
$('.dp-end:last').Zebra_DatePicker({
direction: true
});
I have not tried this. Hope it will work.

Related

How do i get the dynamic table displayed as a popup?

I have this piece of code which computes the difference between the rows of two selected tables and display the result on click of button. How can I display the result in a pop up? Basically I want the resultant table to come as popup, so that when we close the popup the tables checkbox are again reset.
Edit: I tried using modals but it seems to be not working. Can anyone please help where I am going wrong
var selectedRows = document.getElementsByClassName('selected');
limit = 0; //set limit
checkboxes = document.querySelectorAll('.checkboxdiv input[type="checkbox"]');
function checker(elem) {
if (elem.checked) {
limit++;
} else {
limit--;
}
for (i = 0; i < checkboxes.length; i++) {
if (limit == 2) {
if (!checkboxes[i].checked) {
checkboxes[i].disabled = true;
}
} else {
if (!checkboxes[i].checked) {
checkboxes[i].disabled = false;
}
}
}
}
for (i = 0; i < checkboxes.length; i++) {
checkboxes[i].onclick = function () {
checker(this);
}
}
var checkedArray;
function myFunction(event) {
event.target.parentElement.parentElement.className =
event.target.checked ? 'selected' : '';
var elements = document.getElementsByTagName("INPUT");
checkedArray = new Array();
for (var i = 0; i < elements.length; i++) {
if (elements[i].type === 'checkbox' && elements[i].checked) {
checkedArray.push(elements[i].id);
}
}
console.log(checkedArray);
}
$(".btn[data-target='#myModal']").click(function() {
var modalBody = $('<div id="modalContent"></div>');
var table;
const buildTable = (arr) => {
table = document.querySelector("#diff-table");
if (table) table.remove();
table = document.createElement("table");
table.id = "diff-table";
const thead = document.createElement("thead"),
thA = document.createElement("th"),
thB = document.createElement("th"),
thDiff = document.createElement("th");
thA.innerText = "Plan A";
thB.innerText = "Plan B";
thDiff.innerText = "Difference";
thead.append(thA, thB, thDiff);
table.append(thead);
arr.forEach((i) => {
const tr = document.createElement("tr"),
tdA = document.createElement("td"),
tdB = document.createElement("td"),
tdDiff = document.createElement("td");
tdA.innerText = "$" + i["planA"];
tdB.innerText = "$" + i["planB"];
tdDiff.innerText = "$" + i["diff"];
tr.append(tdA, tdB, tdDiff);
table.append(tr);
});
document.body.append(table);
};
const checked = document.querySelectorAll(":checked"),
arr = [];
if (checked.length !== 2) return;
const plans = document.querySelectorAll(":checked"),
planA = plans[0].closest("table").querySelectorAll("td"),
planB = plans[1].closest("table").querySelectorAll("td");
planA.forEach((cell, i) => {
const valA = +cell.innerText.replace(/[^\d.-]/g, '');
const valB = +planB[i].innerText.replace(/[^\d.-]/g, '');
arr.push({ planA: valA, planB: valB, diff: valA - valB });
});
buildTable(arr);
modalBody.append(table);
$('.modal-body').html(modalBody);
})
.table_container {
float: left;
width: 25%;
}
.container::after {
content: "";
clear: both;
display: table;
}
table {
margin: 0 auto;
border-radius: 10px;
}
tr {
padding: 15px;
text-align: center;
}
td {
color: black;
text-align: center;
vertical-align: middle;
border: 1px double white;
height: 50px;
background-color: light-grey;
width: 272px;
}
.sub_text {
font-size: 12px;
font-style: italic;
color: #0071ce;
font-weight: 100;
}
th {
background-color: #0071ce;
text-align: center;
padding: 10px;
border-top-left-radius: 10px;
border-top-right-radius: 10px;
color: white;
font-weight: bold;
}
.header {
color: #0071ce;
font-weight: bold;
padding: 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<div class="container">
<div class="table_container">
</div>
<div class="table_container">
<table id="table1" class="checkboxdiv">
<tr>
<th>Tab A<input type="checkbox" id=" 1" name="table1" value="table1"
onchange="myFunction(event)"> </th>
</tr>
<tr>
<td>$133.90</td>
</tr>
<tr>
<td>$161.30</td>
</tr>
<tr>
<td>$53.30</td>
</tr>
<tr>
<td>$186.20</td>
</tr>
<tr>
<td>HSA match:up to $350</td>
</tr>
<tr>
<td>HSA match:up to $700</td>
</tr>
<tr>
<td>$3000</td>
</tr>
</table>
</div>
<div class="table_container">
<table id="table2" class="checkboxdiv">
<tr>
<th>Tab B <input type="checkbox" id="2" name="table2" value="table2"
onchange="myFunction(event)"></th>
</tr>
<tr>
<td>$33.90</td>
</tr>
<tr>
<td>$161.30</td>
</tr>
<tr>
<td>$53.30</td>
</tr>
<tr>
<td>$186.20</td>
</tr>
<tr>
<td>HSA match:up to $350</td>
</tr>
<tr>
<td>HSA match:up to $700</td>
</tr>
<tr>
<td>$3000</td>
</tr>
</table>
</div>
<div class="table_container">
<table id="table3" class="checkboxdiv">
<tr>
<th>Tab C<input type="checkbox" id="3" name="table3" value="table3"
onchange="myFunction(event)"> </th>
</tr>
<tr>
<td>$33.90</td>
</tr>
<tr>
<td>$161.30</td>
</tr>
<tr>
<td>$53.30</td>
</tr>
<tr>
<td>$186.20</td>
</tr>
<tr>
<td>HSA match:up to $350</td>
</tr>
<tr>
<td>HSA match:up to $700</td>
</tr>
</table>
</div>
</div>
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#myModal">
Launch demo modal
</button>
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel"
aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content"></div>
</div>
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-body"></div>
</div>
</div>
</div>
You can use modals to display your differences between your tables as a popup when they selected. Assign modals' close button as a reset button as well via JS.
modals: https://getbootstrap.com/docs/4.0/components/modal/
Edit:
I couldn't find the line for calling your js file in your code. Can you add this line to the end of your html-body section?
You can add a console.log() line to your js file, so you can see if your js and html files are connected or not on the browser. (via insperctor-console)
Also, I couldn't find the line that you're activating your modal. You should change its class list. fade means it will not display on the browser. You should remove it and add show instead.
Edit-2:
I am not familiar with $ so I am adding the JS which is working. Please try the below things and if there will be a problem, edit your code below and leave me a comment.
in your js file, follow the steps I wrote. You should see an alarm when you click your modal button. You need to fill it up:
document.getElementById('modalButton').addEventListener('click', function() {
alert('hi');
// step - 1: clean the inner of previous modal, if it has
// step - 2: add the result of comparing two table elements
// step - 3: remove 'fade' from modal's class and add 'show'
})
in your html (add an id to your modal button, it will be easier to select):
<button type="button" id="modalButton" class="btn btn-primary" data-toggle="modal" data-target="#myModal">Launch demo modal</button>

Changing Background color of a table and rows dynamically using Javascript

Snippet code copied from this link jsfiddle.net/facgwbsm
I have an app whereby when the user clicks on Add New Item button rows are added dynamically which works fine. When any number on the table is clicked it is populated dynamically in the rows. When I hover over the 1st row the background color changes to green including the corresponding match on the table which works fine.
I want when other rows are hovered on the effect on the 1st row applies to proceeding rows whereby the background color changes to green on the whole row and the corresponding inputs on the table..
//Code to add child and input fields dynamically
// Starting number of inputs
let count = 5;
// Wrapper
const wrapper = document.querySelector('#wrapper');
document.querySelector('#btn').addEventListener('click', () => {
const container = document.createElement('div');
for (let i = 0; i < 5; i++) {
// Increment the count to ensure that it is unique
count++;
// Create your new `<input>` element
const input = document.createElement('input');
input.type = 'text';
input.name = count;
input.size = '4';
input.id = `inp${count}`;
container.appendChild(input);
// Optional: add empty whitespace after each child
container.append(document.createTextNode(' '));
}
wrapper.appendChild(container);
});
//END code
let currentInput = 1;
let bonusInput = 1;
$("#table1 td").on('click', function(event) {
//gets the number associated with the click
let num = $(this).text();
//set it to input's value attribute
$("#inp" + currentInput++).attr("value", num);
});
//Bonus input
$("#table2").on('click', function(event) {
let bon = event.target.textContent;
$("#bonus" + bonusInput++).attr("value", bon);
});
$("input").hover(function(event) {
//alert($('#selection1 input').serialize());
//let num = $(this).attr("value");
let parent = $(this).parent();
$(parent.children()).each(function(index, element) {
let num = $(element).val();
//console.log(num);
if (num) {
//Change input color on hover
$(this).css("backgroundColor", "green");
//Change tables bgcolor on hover
$("#table1 td").each(function() {
if ($(this).text() === num) $(this).css("backgroundColor", "green");
});
// $("#table2 td").each(function() {
// if ($(this).text() === num) $(this).css("backgroundColor","green");
// });
}
});
},
function(event) {
//Change input color on hover out
let parent = $(this).parent();
$(parent.children()).each(function(index, element) {
$(element).css("backgroundColor", "white");
});
//Change tables bgcolor on hover out
$("#table1 td").each(function() {
$(this).css("backgroundColor", "orange");
});
});
table {
border-collapse: collapse;
border: 5px solid black;
width: 100%;
}
td {
width: 50%;
height: 2em;
border: 1px solid #ccc;
background-color: orange;
text-align: center;
vertical-align: middle;
font-weight: bold;
cursor: pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<!--Table on the left -->
<div style="width: 140px; float: left;">
<table id="table1">
<tbody>
<tr>
<td>1</td>
<td>2</td>
</tr>
<tr>
<td>3</td>
<td>4</td>
</tr>
<tr>
<td>5</td>
<td>6</td>
</tr>
<tr>
<td>7</td>
<td>8</td>
</tr>
<tr>
<td>9</td>
<td>10</td>
</tr>
</tbody>
</table>
</div>
<!-- Rows on the right-->
<!--2nd table-->
<div style="width: 140px; float: left; margin-left: 12px;">
<table id="table2">
<tbody>
<tr>
<td>1</td>
<td>2</td>
</tr>
<tr>
<td>3</td>
<td>4</td>
</tr>
<tr>
<td>5</td>
<td>6</td>
</tr>
<tr>
<td>7</td>
<td>8</td>
</tr>
<tr>
<td>9</td>
<td>10</td>
</tr>
</tbody>
</table>
</div>
<!-- Rows on the right-->
<!-- Make sure each input has a unique id-->
<div style="width: 600px; float: right;">
<div id="wrapper">
<div>
<input type="text" name="1" size="4" id="inp1" value="">
<input type="text" name="2" size="4" id="inp2" value="">
<input type="text" name="3" size="4" id="inp3" value="">
<input type="text" name="4" size="4" id="inp4" value="">
<input type="text" name="5" size="4" id="inp5" value=""> +
<input style="margin-left: 20px;" type="text" name="6" size="4" id="bonus1" value="">
</div>
</div>
<button type="button" id="btn">Add new input group</button>
</div>
Javascript code
//Code to add child and input fields dynamically
// Starting number of inputs
let count = 5;
// Wrapper
const wrapper = document.querySelector('#wrapper');
document.querySelector('#btn').addEventListener('click', () => {
const container = document.createElement('div');
for (let i = 0; i < 5; i++) {
// Increment the count to ensure that it is unique
count++;
// Create your new `<input>` element
const input = document.createElement('input');
input.type = 'text';
input.name = count;
input.size = '4';
input.id = `inp${count}`;
container.appendChild(input);
// Optional: add empty whitespace after each child
container.append(document.createTextNode(' '));
}
wrapper.appendChild(container);
});
//END code
let currentInput = 1;
let bonusInput = 1;
$("#table1 td").on('click',function(event){
//gets the number associated with the click
let num = $(this).text();
//set it to input's value attribute
$("#inp" + currentInput++).attr("value",num);
});
//Bonus input
$("#table2").on('click',function(event){
let bon = event.target.textContent;
$("#bonus" + bonusInput++).attr("value",bon);
});
$("input").hover( function(event) {
//alert($('#selection1 input').serialize());
//let num = $(this).attr("value");
let parent = $(this).parent();
$(parent.children()).each(function (index, element) {
let num = $(element).val();
//console.log(num);
if (num) {
//Change input color on hover
$(this).css("backgroundColor","red");
//Change tables bgcolor on hover
$("#table1 td").each(function() {
if ($(this).text() === num) $(this).css("backgroundColor","green");
});
// $("#table2 td").each(function() {
// if ($(this).text() === num) $(this).css("backgroundColor","green");
// });
}
});
},
function(event) {
//Change input color on hover out
let parent = $(this).parent();
$(parent.children()).each(function (index, element) {
$(element).css("backgroundColor","white");
});
//Change tables bgcolor on hover out
$("#table1 td").each(function() {
$(this).css("backgroundColor","orange");
});
});
</script>
The functions regarding the input hover and hover out only apply on the first row because the second row isn't created when the code lodes. You can fix it by adding the last part of your code to the button click:
document.querySelector('#btn').addEventListener('click', () => {
const container = document.createElement('div');
for (let i = 0; i < 5; i++) {
// Increment the count to ensure that it is unique
count++;
// Create your new `<input>` element
const input = document.createElement('input');
input.type = 'text';
input.name = count;
input.size = '4';
input.id = `inp${count}`;
container.appendChild(input);
// Optional: add empty whitespace after each child
container.append(document.createTextNode(' '));
}
wrapper.appendChild(container);
$("input").hover( function(event) {
//alert($('#selection1 input').serialize());
//let num = $(this).attr("value");
let parent = $(this).parent();
$(parent.children()).each(function (index, element) {
let num = $(element).val();
//console.log(num);
if (num) {
//Change input color on hover
$(this).css("backgroundColor","green");
//Change tables bgcolor on hover
$("#table1 td").each(function() {
if ($(this).text() === num) $(this).css("backgroundColor","green");
});
// $("#table2 td").each(function() {
// if ($(this).text() === num) $(this).css("backgroundColor","green");
// });
}
});
},
function(event) {
//Change input color on hover out
let parent = $(this).parent();
$(parent.children()).each(function (index, element) {
$(element).css("backgroundColor","white");
});
//Change tables bgcolor on hover out
$("#table1 td").each(function() {
$(this).css("backgroundColor","orange");
});
});
});
Also, you have another issue:
When clicking on numbers before adding a new row, the new row gets empty input boxes.
I am not sure if you really need the id's, I put that in but do not use it functionally as I used classes and thus I had no need to keep the global variables you had. I showed how to namespace those but commented them out.
I had question regarding the new row of inputs and how to determine when you click the tables where the click should place its value thus I added the concept of a focused input row delineated by the class focus-row - I gave it a border color to demonstrate which row is focused. When any input in that row is clicked or focused, it sets that focus-row that contains that input.
As for the second table and the "bonus" input - I simply used that to highlight using the value from the row being hovered there, not sure how exactly you wished to handle that but this seemed to make the most sense to me.
Now, as to the point where you add a new input row, rather than keeping track of the global variables, I simply cloned the first input row and cleared its values and set the id and name attribute there. Since I attached the event handlers to the wrapper, you are able to add new input rows without dealing with re-attaching.
NOTE: you could put the hover on the row using input-group instead of the inputs to avoid "flash" when moving from input to input on the same row but I left that as you had it.
I used myApp.wrapper.on('mouseenter', and the mouseleave it really is functionally the same as the .hover but it made it a bit cleaner when I chained in the .on('click focus' for the row focus. You could for example add a button to the input row <button class="set-row-focus">Focus Row</button> or add that class to the input-group and then trigger a custom event on a click of that to the focus/click event handler like this:set event: .on('click focus setfocus' then trigger it $('.set-row-focus').on('click',function(){$(this).siblings('.normal-input').first().trigger('setfocus');});
$(function() {
// namespace globals
var myApp = myApp || {
//count: 5,
//currentInput: 1,
// bonusInput: 1,
wrapper: $('#wrapper'),
table1: $("#table1"),
table2: $("#table2")
};
$('#btn').on('click', function(event) {
//Code to add child and input fields dynamically
const groups = myApp.wrapper.find('.input-group');
const newGroup = groups.first().clone(true).removeClass('focus-row');
newGroup.find('input')
//only if you really need id's
.each(function(index) {
let newId = $(this).is(".normal-input") ? "inp" + groups.length + index : "bonus" + groups.length;
$(this).attr("name", newId)
.attr("id", newId).val('');
});
newGroup.appendTo(myApp.wrapper);
});
myApp.table1.on('click', 'td', function(event) {
//gets the number associated with the click
let num = $(this).text();
$('.focus-row').find('.normal-input').filter(function() {
return this.value.length === 0;
}).first().val(num);
});
//Bonus input
myApp.table2.on('click', 'td', function(event) {
let bon = $(this).text();
$('.focus-row').find('.bonus-input').val(bon);
});
myApp.wrapper.on('mouseenter', 'input', function(event) {
let inputs = $(this).closest('.input-group')
.find('input')
.filter(function(index) {
return !!($(this).val());
})
.each(function(index) {
let num = $(this).val();
//Change input color on hover
$(this).toggleClass('mark-hover', true);
let pairTable = {};
if ($(this).is('.normal-input')) {
pairTable = myApp.table1;
}
if ($(this).is('.bonus-input')) {
pairTable = myApp.table2;
}
pairTable.find('td')
.filter(function(index) {
return $(this).text() == num;
})
.toggleClass('mark-hover', true);
});
}).on('mouseleave', 'input', function(event) {
//remove class on hover out
$(this).closest('.input-group')
.find('input')
.toggleClass('mark-hover', false);
//removes class in tables on hover out
myApp.table1.add(myApp.table2)
.find('td')
.toggleClass("mark-hover", false);
})
// sets the focus row
.on('click focus', 'input', function() {
$('.input-group').removeClass('focus-row');
$(this).closest('.input-group')
.addClass('focus-row')
});
});
table {
border-collapse: collapse;
border: 5px solid black;
width: 100%;
}
.table-wrapper {
width: 140px;
float: left;
}
.inputs-container {
width: 100%;
float: right;
}
.inputs-container input {
margin-right: 0.3em;
}
.inputs-container .bonus-input {
margin-left: 20px;
}
.focus-row {
border: solid 1px lime;
}
td {
width: 50%;
height: 2em;
border: 1px solid #ccc;
background-color: orange;
text-align: center;
vertical-align: middle;
font-weight: bold;
cursor: pointer;
}
td.mark-normal {
background-color: orange;
}
.mark-hover {
background-color: lightgreen;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<!--Table on the left -->
<div class="table-wrapper">
<table id="table1">
<tbody>
<tr>
<td>1</td>
<td>2</td>
</tr>
<tr>
<td>3</td>
<td>4</td>
</tr>
<tr>
<td>5</td>
<td>6</td>
</tr>
<tr>
<td>7</td>
<td>8</td>
</tr>
<tr>
<td>9</td>
<td>10</td>
</tr>
</tbody>
</table>
</div>
<!-- Rows on the right-->
<!--2nd table-->
<div class="table-wrapper" style="margin-left: 12px;">
<table id="table2">
<tbody>
<tr>
<td>1</td>
<td>2</td>
</tr>
<tr>
<td>3</td>
<td>4</td>
</tr>
<tr>
<td>5</td>
<td>6</td>
</tr>
<tr>
<td>7</td>
<td>8</td>
</tr>
<tr>
<td>9</td>
<td>10</td>
</tr>
</tbody>
</table>
</div>
<!-- Rows on the right-->
<!-- Make sure each input has a unique id-->
<div class="inputs-container">
<div id="wrapper">
<div class="input-group focus-row">
<input class="normal-input" type="text" name="1" size="4" id="inp1" value="">
<input class="normal-input" type="text" name="2" size="4" id="inp2" value="">
<input class="normal-input" type="text" name="3" size="4" id="inp3" value="">
<input class="normal-input" type="text" name="4" size="4" id="inp4" value="">
<input class="normal-input" type="text" name="5" size="4" id="inp5" value=""> +
<input class="bonus-input" type="text" name="6" size="4" id="bonus0" value="">
</div>
</div>
<button type="button" id="btn">Add new input group</button>
</div>

filtering a html table based on a condition entered in textbox javascript

i have a html table that displays student name and the number of leaves he has taken.how do i filter giving a constraint on the no of leaves and display it
,like if enter 5 in the text box,students with leave of 5 or more should be filtered and displayed.
the code i have now display the records with the entered value
function myFunction1() {
var input, filter, table, tr, td, i;
input = document.getElementById("myInput1");
filter = input.value.toUpperCase();
table = document.getElementById("myTable");
tr = table.getElementsByTagName("tr");
for (i = 0; i < tr.length; i++) {
td = tr[i].getElementsByTagName("td")[6];
if (td) {
if (td.innerHTML.toUpperCase().indexOf(filter) > -1) {
tr[i].style.display = "";
} else {
tr[i].style.display = "none";
}
}
}
}
A jQuery version
var filter = $('#myInput1').val.toUpperCase();
$("#myTable tr td:eq(6)").each( function() {
var str = $(this).html().toUpperCase()
if( str.indexOf(filter) > -1)
$(this).parent('tr').css('display','')
else
$(this).parent('tr').css('display','none')
})
quick knock-together that does what you're looking for, from what I can understand. I have also used the same filter function to allow me to screen by name or by student-year. It's a flexible filter routine, wish I'd taken the time to avoid hard-wiring the handling of strings vs numbers, but for your purposes, that'd be overkill, I think.
A strange gotcha with table rows: you can't simply display="none" and display="block" them, it garbles the table structure. That's why it's display="none and display="" below. A few sources pointed that out, and I'm glad they did. I was beating my head on that wall for a while...
Best of luck!
// Store all the inputs...
var filterByName = document.getElementById("filter-by-name");
var filterByYear = document.getElementById("filter-by-year");
var filterByLeaves = document.getElementById("filter-by-leaves");
// And store the table itself.
var studentInfoTable = document.getElementsByClassName("student-info")[0];
// these functions will be called in the event listeners.
// By doing this, I only have a single filter function.
function byName() {
var filterString = filterByName.value;
filterBy("name", filterString);
};
function byYear() {
var filterString = filterByYear.value;
filterBy("year", filterString);
};
function byLeaves() {
var filterString = filterByLeaves.value;
filterBy("leaves", filterString);
};
/**
* The filter function itself, accepts the field to filter
* by and the string to use as the filter data.
* In essence, we take each row of the body, find the td
* to filter by, compare that with the filter data itself.
* There are two types of compare: either text or numeric.
*
**/
function filterBy(filter, filterString) {
var selector = ".student-" + filter;
var rows = studentInfoTable.querySelectorAll("tbody tr");
for (var i = 0; i < rows.length; i++) {
var filterEl = rows[i].querySelector(selector);
switch(filter) {
case "name":
if (filterEl.textContent.indexOf(filterString) == -1) {
rows[i].style.display = "none";
} else {
rows[i].style.display = "";
};
break;
case "year":
case "leaves":
if (parseInt(filterEl.textContent) >= parseInt(filterString) || filterString.length == 0) {
rows[i].style.display = "";
} else {
rows[i].style.display = "none";
};
break;
}
}
};
// The event listeners for each input.
filterByName.addEventListener("keyup", byName);
filterByYear.addEventListener("keyup", byYear);
filterByLeaves.addEventListener("keyup", byLeaves);
.student-info {
font-family: Arial, sans-serif;
width: 100%;
table-layout: fixed;
}
thead {
font-weight: bold;
}
label {
display: block;
}
.student-name {
width: 40%;
}
.student-id,
.student-year,
.student-leaves {
width: 20%;
text-align: center;
}
<table class="student-info">
<thead>
<td class="student-name">Name</td>
<td class="student-id">S. Id</td>
<td class="student-year">Year</td>
<td class="student-leaves">Leaves</td>
</thead>
<tbody>
<tr>
<td class="student-name">Abraham Abas</td>
<td class="student-id">00141</td>
<td class="student-year">2018</td>
<td class="student-leaves">4</td>
</tr>
<tr>
<td class="student-name">Billy Bragg</td>
<td class="student-id">00143</td>
<td class="student-year">2018</td>
<td class="student-leaves">7</td>
</tr>
<tr>
<td class="student-name">Conor Chace</td>
<td class="student-id">00147</td>
<td class="student-year">2019</td>
<td class="student-leaves">5</td>
</tr>
<tr>
<td class="student-name">Daniel Daye</td>
<td class="student-id">00150</td>
<td class="student-year">2019</td>
<td class="student-leaves">0</td>
</tr>
<tr>
<td class="student-name">Edward Eppington</td>
<td class="student-id">00151</td>
<td class="student-year">2018</td>
<td class="student-leaves">6</td>
</tr>
<tr>
<td class="student-name">Frank Ford</td>
<td class="student-id">00153</td>
<td class="student-year">2020</td>
<td class="student-leaves">9</td>
</tr>
</tbody>
</table>
<div class="student-filter">
<h2>
Filter by...
</h2>
<label>Name:
<input type="text" id="filter-by-name">
</label>
<label>Year:
<input type="text" id="filter-by-year">
</label>
<label>Leaves:
<input type="text" id="filter-by-leaves">
</label>
</div>
Search Textbox:-
<label>Search:<input class="form-control input-sm" placeholder="" aria-controls="DataTables_Table_0" type="search" id="txtSearch" onkeyup="filter(this);"></label>
Script:-
function filter(element) {
var value = $(element).val();
$("#DataTables_Table_1 tr").each(function () {
if ($(this).text().search(value) > -1) {
$(this).show();
}
else {
$(this).hide();
}
});
}

dynamically added dom-elements not responding to jQuery-function

Consider the following code:
$(document).ready(function(){
var table1 = $("table").eq(0);
var row_list;
var rows;
var x;
var y;
$("#mybutton").click(function(){
row_list = table1.find("tr");
rows = row_list.length;
x = $("#field_x").val();
y = $("#field_y").val();
if(x>rows || y>rows){
var num;
if(x>y) num=x;
else num=y;
var n = num-rows;
var row; table1.find("tr").eq(0).clone();
while(1){
row = table1.find("tr").eq(0).clone();
table1.append(row);
n--;
if(n===0) break;
}
n = num-rows;
var td;
while(1){
td = table1.find("td").eq(0).clone();
table1.find("tr").append(td);
n--;
if(n===0) break;
}
}
var text = $("#text").val();
var css = $("#css").val();
$("table:eq(0) tr:eq(" + (x-1) + ") td:eq(" + (y-1) + ")").text(text).css("color", css);
});
table1.find("td").click(function(){
$(this).html("");
});
});
* {
font: 14px normal Arial, sans-serif;
color: #000000;
}
table {
margin: 50px auto;
}
table, td {
border: 1px solid #aaa;
border-collapse: collapse;
}
th {
padding: 10px;
font-weight: bold;
}
td {
background-color: #eeeeee;
width: 80px;
height: 80px;
}
table:first-child tr td {
cursor: pointer;
}
td[colspan="4"]{
text-align:center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tbody>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
</tbody>
</table>
<table>
<thead>
<tr>
<th colspan="4">Fill a field:</th>
</tr>
</thead>
<tbody>
<tr>
<td>Text: <br/><input type="text" id="text" value=""></td>
<td>Field X: <br/><input type="text" id="field_x" value=""></td>
<td>Field Y: <br/><input type="text" id="field_y" value=""></td>
<td>CSS: <br/><input type="text" id="css" value=""></td>
</tr>
<tr>
<td colspan="4"><button id="mybutton">Fill</button></td>
</tr>
</tbody>
</table>
What the program does is the following:
The user can choose a field by giving an x-value and a y-value. In this field the content from the input field with label "Text" is displayed.
- This part of the program works fine.
If the user chooses an x-value or a y-value larger than the current number of rows (columns), rows and columns are added until the number of rows/columns is equal to the value in the x-(or y-) field.
- This part of the program also works fine.
The only functionality that does not work is the following:
If the user clicks on one of the non-empty fields in the table, the content of the table is supposed to go back to its natural (empty) state.
To this end, the following function was added to the code (see last couple of lines in the javascript part of the code):
table1.find("td").click(function(){
$(this).html("");
});
This piece of code basically means:
If the user clicks on any box ("td") in the table, the content of this box should disappear.
This is more or less the most simple part of the code. But it's also the one aspect that doesn't work. More precisely: It works for the original boxes, but it doesn't work for any boxes that were added. - And I don't get why it behaved that way.
If you are dynamically adding elements to the DOM and expect to be attaching events to them, you should consider using event delegation via the on() function :
// This will wire up a click event for any current AND future 'td' elements
$(table1).on('click', 'td', function(){
$(this).html("");
});
Simply using click() on it's own will only wire up the necessary event handlers for elements that exist in the DOM at the time of that function being called.
You're assigning the event handlers before the user has a chance to input any data. This means that if an additional row or column is added, the new <td>s need event handlers added manually.
Alternately, you can add a single click handler to the entire table:
table1.click(function (ev) { $(ev.target).html(''); }
The ev.currentTarget property will be the <table> element because that's the element the event handler is registered to, but the ev.target property will be the <td> element that you're looking for.
Here's a JSFiddle to experiment with.
Hey there here's what I thought the answer might be,
HTML File:
<!DOCTYPE html>
<html lang="de-DE">
<head>
<meta charset="UTF-8" />
<style>
* {
font: 14px normal Arial, sans-serif;
color: #000000;
}
table {
margin: 50px auto;
}
table, td {
border: 1px solid #aaa;
border-collapse: collapse;
}
th {
padding: 10px;
font-weight: bold;
}
td {
background-color: #eeeeee;
width: 80px;
height: 80px;
}
table:first-child tr td {
cursor: pointer;
}
td[colspan="4"]{
text-align:center;
}
.pre-height {
min-height: 80px;
}
</style>
</head>
<body>
<table>
<tbody>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td class="pre-height"></td>
<td class="pre-height"></td>
<td class="pre-height"></td>
<td class="pre-height"></td>
</tr>
</tbody>
</table>
<table>
<thead>
<tr>
<th colspan="4">Fill a field:</th>
</tr>
</thead>
<tbody>
<tr>
<td>Text: <br/><input type="text" id="text" value=""></td>
<td>Field X: <br/><input type="text" id="field_x" value=""></td>
<td>Field Y: <br/><input type="text" id="field_y" value=""></td>
<td>CSS: <br/><input type="text" id="css" value=""></td>
</tr>
<tr>
<td colspan="4"><button id="myButton">Fill</button></td>
</tr>
</tbody>
</table>
<script src="jquery.min.js"></script>
<script src="jack.js"></script>
</body>
</html>
JACK.JS file:
window.onload = function() {
'use strict';
/**
* Appends 'n' number of rows to the table body.
*
* #param {Number} n - Number of rows to make.
*/
var makeRows = function(n) {
let tbody= document.getElementsByTagName("table")[0].getElementsByTagName("tbody")[0],
tr = document.querySelector("table:first-of-type tbody tr");
for (let i = 0; i < n; i++) {
let row = Node.prototype.cloneNode.call(tr, true);
tbody.appendChild(row);
}
};
/**
* Appends 'n' number of cells to each row.
*
* #param {Number} n - Number of cells to add to each row.
*/
var makeColumns = function(n) {
let addNCells = (function(n, row) {
for (let i = 0; i < n; i++) {
let cell = Node.prototype.cloneNode.call(td, true);
row.appendChild(cell);
}
}).bind(null, n);
let tbody= document.getElementsByTagName("table")[0].getElementsByTagName("tbody")[0],
td = document.querySelector("table:first-of-type tbody tr td"),
rows = document.querySelectorAll("table:first-of-type tbody tr");
rows.forEach(function(row) {
addNCells(row);
});
};
document.getElementById("myButton").addEventListener("click", () => {
let x = document.getElementById("field_x").value,
y = document.getElementById("field_y").value;
makeColumns(x);
makeRows(y);
});
/**
* Newly added code
*/
(function() {
let table = document.querySelector("table");
// We will add event listener to table.
table.addEventListener("click", (e) => {
e.target.innerHTML = "";
e.target.style.backgroundColor = "orange";
});
})();
};
Edit: And I didn't even answer the question completely. You might wanna attach event listener to the nearest non-dynamic parent so that click event will bubble up and you can capture that, check the code under the comment newly added code.

Changes in <td> input texts doesn't reflect in text-area while the Javascript function works fine

function table_to_text() {
var j;
var z = '';
var k = 4;
var article1 = new Array();
for (j = 1; j <= k; j++) {
article1[j] = document.getElementById("c" + j).value;
z = z + article1[j];
}
document.getElementById("batch_full").innerText = z;
}
function text_to_table() {
var batch_text = document.getElementById("batch_full").value;
var length_covered = 0;
var n = 4;
var article = new Array();
var temp;
var length;
for (var i = 1; i <= n; i++) {
article[i] = document.getElementById("c" + i);
length = article[i].getAttribute('maxlength');
temp = batch_text.substr(length_covered, length);
article[i].value = temp;
length_covered = Number(length_covered) + Number(length);
}
}
#batch_full {
height: 200px;
width: 500px;
}
table {
border-collapse: collapse;
}
table,
th,
td {
padding: 0px 10px 0px 10px;
}
td {
border: 1px solid black;
}
th {
text-align: left;
text-indent: -2.5%;
}
td>input {
resize: horizontal;
width: 100%;
}
<textarea id="batch_full" onchange="text_to_table()">Batch input here</textarea>
<table id="results_table" onchange="table_to_text()">
<tr>
<th>S.No</th>
<th>Account Number</th>
<th>First Name</th>
<th>Last Name</th>
</tr>
<tr>
<td><input type="text" maxlength="2" id="c1"></td>
<td><input type="text" maxlength="10" id="c2"></td>
<td><input type="text" maxlength="10" id="c3"></td>
<td><input type="text" maxlength="10" id="c4"></td>
</tr>
</table>
<input type="button" onclick="text_to_table()" value="Text to Table">
<input type="button" onclick="table_to_text()" value="Table to Text">
When I enter some text in the element, the changes are reflected in the table elements, but when I try to edit the text in the element, the changes are not reflected in the element.
Please help me in resolving this issue. I'm using Codepen to write this code.
There are no bugs in your code.For instant reflection of your data which you are entering in either Textarea or Table, replace "onchange" event with "oninput" event in the TextArea and table elements and, Since you are using codepen the "innerText" attribute will not be rendered instead use "value" attribute.
That should do the trick.
Change the innterText to innerHTML. Seems to work: http://codepen.io/anon/pen/gLvqMN

Categories

Resources