JavaScript logic error - javascript

I am trying to get JavaScript to generate a table with data from an array for me however when I run this code it enters the same data twice. Does anyone know what mistake I am making?
The HTML:
<body>
<div class="container">
<h1 class="page-header">Bookings</h1>
<table id="bookTable" class="table table-bordered">
<thead>
<tr>
<th>First Name</th>
<th>Second Name</th>
<th>Email</th>
<th>From</th>
<th>To</th>
</tr>
<tr>
<td type="text" id="firstName"></td>
<td type="text" id="secondName"></td>
<td type="text" id="email"></td>
<td type="text"id="dateFrom"></td>
<td type="text"id="dateTo"></td>
</tr>
</thead>
</table>
</div>
The JavaScript is using a guide I found that I have adapted. In reality, the array comes from a python file that is fed in as a variable when Flask displays the template. I have used the same data that python prints out when looking at the contents of the variable that is passed.
<script>
var listOfBookings = [John`Doe`jd#gmail.com`03/01/2018`18/01/2018`John`Doe`jd#gmail.com`26/12/2017`27/12/2017]
var array = listOfBookings.split("`");
var count = 1
for (var i = 0; i < array.length; i++){
if (1%(i+1) == 0){
var firstName = array[i];
}
if (2%(i+1) == 0){
var secondName = array[i];
}
if (3%(i+1) == 0){
var email = array[i];
}
if (4%(i+1) == 0){
var dateFrom = array[i];
}
if (5%(i+1) == 0){
var dateTo = array[i];
}
// Addapted from http://talkerscode.com/webtricks/add-edit-and-
delete-rows-from-table-dynamically-using-javascript.php
if(count%5 == 0){
var table=document.getElementById("bookTable");
var table_len=(table.rows.length)-1;
var row = table.insertRow(table_len).outerHTML="<tr
id='row"+table_len+"'><td id='date_row"+table_len+"'>"+firstName+"</td><td
id='name_row"+table_len+"'>"+secondName+"</td><td
id='country_row"+table_len+"'>"+email+"</td><td
id='country_row"+table_len+"'>"+dateFrom+"</td><td
id='country_row"+table_len+"'>"+dateTo+"</td></tr>";
}
count += 1
}
</script>

Your code seems overly complicated. Here's a working example of how you might do it: (Note: I've added a tbody to your table, rather than have all these rows inserted into the thead)
var listOfBookings = "John`Doe`jd#gmail.com`03/01/2018`18/01/2018`John`Doe`jd#gmail.com`26/12/2017`27/12/2017";
var array = listOfBookings.split("`");
var count = 1;
var table = document.getElementById("bookTable").getElementsByTagName('tbody')[0];
var row = table.insertRow(-1); //appends initial row
row.id = "row_" + (count)
for (var i = 0; i < array.length; i++) {
if (i % 5 == 0 && i > 0) {
row = table.insertRow(-1); //appends a row
row.id = "row_" + (++count)
}
var cell = row.insertCell(-1); //appends a cell
var text = document.createTextNode(array[i]); //create the textNode
cell.appendChild(text); //fill the cell with the text
//(you could also set the cell id and other attributes at this point too)
}
<div class="container">
<h1 class="page-header">Bookings</h1>
<table id="bookTable" class="table table-bordered">
<thead>
<tr>
<th>First Name</th>
<th>Second Name</th>
<th>Email</th>
<th>From</th>
<th>To</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>

Your array seems to have 10 values and from all your if statements none of them will have their condition equal true when i is bigger then 4.
All the variables (firstName, secondName, email, dataFrom, dateTo) will have the same value when count is 10 as they had when it was 5
You could do something like this:
var array = ["John","Doe","jd#gmail.com","03/01/2018","18/01/2018","John","Doe","jd#gmail.com","26/12/2017","27/12/2017"];
var table=document.getElementById("bookTable");
for (var i = 0; array.length % 5 === 0 && i < array.length;){
var firstName = array[i++];
var secondName = array[i++];
var email = array[i++];
var dateFrom = array[i++];
var dateTo = array[i++];
var table_len = (table.rows.length)-1;
var row = table.insertRow(table_len).outerHTML="<tr id='row"+table_len+"'><td id='date_row"+table_len+"'>"+firstName+"</td><td id='name_row"+table_len+"'>"+secondName+"</td><td id='country_row"+table_len+"'>"+email+"</td><td id='country_row"+table_len+"'>"+dateFrom+"</td><td id='country_row"+table_len+"'>"+dateTo+"</td></tr>";
}
<body>
<div class="container">
<h1 class="page-header">Bookings</h1>
<table id="bookTable" class="table table-bordered">
<thead>
<tr>
<th>First Name</th>
<th>Second Name</th>
<th>Email</th>
<th>From</th>
<th>To</th>
</tr>
<tr>
<td type="text" id="firstName"></td>
<td type="text" id="secondName"></td>
<td type="text" id="email"></td>
<td type="text"id="dateFrom"></td>
<td type="text"id="dateTo"></td>
</tr>
</thead>
</table>
</div>

Related

JavaScript Getting second <td> cell value when clicked on a button on the same row

How can I get email cell value when I click on the button which is located at the last cell of the same row.
Please check this screenshot for better understanding what I mean
So when I click Button 1, I want to get Email1 value or when click Button 2, I want to get N2 cell value.
My HTML Mockup:
function renderCustomers(tasks) {
customerList.innerHTML += `
<tr >
<th >Name</th>
<th >Email</th>
<th >Contacts</th>
<th >Address</th>
<th >Country</th>
<th >Action</th>
</tr>`;
tasks.forEach((t) => {
customerList.innerHTML += `
<tr class=" animated bounceInUp">
<td >${t.Name}</td>
<td >${t.Email}</td>
<td >${t.Contacts}</td>
<td >${t.Address}</td>
<td >${t.Country}</td>
<td ><button class="btn btn-success btn-xs" id="getCustomerEmail">
Get Customer Email
</button></td>
</tr>`;
});
}
I found this function but it return the clicked cell value not the one I need:
function getElementID(){
var tbl = document.getElementById("Results");
if (tbl != null) {
for (var i = 0; i < tbl.rows.length; i++) {
for (var j = 0; j < tbl.rows[i].cells.length; j++)
tbl.rows[i].cells[j].onclick = function () { getval(this); };
}
}
function getval(cel) {
alert(cel.innerHTML);
}
}
Any help is really appreciated
I found this function but it return the clicked cell value not the one I need:
function getElementID(){
var tbl = document.getElementById("MyTable");
if (tbl != null) {
for (var i = 0; i < tbl.rows.length; i++) {
for (var j = 0; j < tbl.rows[i].cells.length; j++)
tbl.rows[i].cells[j].onclick = function () { getval(this); };
}
}
function getval(cel) {
alert(cel.innerHTML);
}
}
I think you simply bind a class to your td and then reference it based on the context of the clicked button.
function getEmail(el) {
const tr = el.closest('tr');
const tds = tr.getElementsByClassName('email');
console.log(tds[0].innerHTML);
}
<table>
<thead>
<th>Name</th>
<th>Email</th>
<th>Action</th>
</thead>
<tbody>
<tr>
<td>Salvino</td>
<td class="email">salvino#example.com</td>
<td><button onclick="getEmail(this)">Button</button></td>
</tr>
<tr>
<td>Someone</td>
<td class="email">someone#example.com</td>
<td><button onclick="getEmail(this)">Button</button></td>
</tr>
</tbody>
</table>

Get summary number from only visible table rows

I have a code which counts a total summary of all price table cells. This is not exactly what do I need. I need to count the summary from only visible rows. I use filtering by date range, once I change date it displays only dates from the selected date range, but the summary price is from the all rows. I need to implement the part of the code for visible table rows only and update the summary price in the span.
Any advice?
function filterRows() {
var from = jQuery("#datefilterfrom").val();
var to = jQuery("#datefilterto").val();
if (!from && !to) { // no value for from and to
return;
}
from = from || "1970-01-01"; // default from to a old date if it is not set
to = to || "2999-12-31";
var dateFrom = moment(from);
var dateTo = moment(to);
jQuery("#table tr").each(function(i, tr) {
var val = jQuery(tr).find("td:nth-child(2)").text();
var dateVal = moment(val, "DD.MM.YYYY");
var visible = (dateVal.isBetween(dateFrom, dateTo, null, [])) ? "" : "none"; // [] for inclusive
jQuery(tr).css("display", visible);
//summary start
var table = document.getElementById("table"),
sumVal = 0;
for (var i = 1; i < table.rows.length; i++) {
sumVal = sumVal + parseInt(table.rows[i].cells[2].innerHTML);
}
document.getElementById("val").innerHTML = "Sum Value = " + sumVal;
console.log(sumVal);
});
//summary end
}
jQuery("#datefilterfrom").on("change", filterRows);
jQuery("#datefilterto").on("change", filterRows);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.4/moment.min.js"></script>
<div class="row">
<div class="col-md-3">
<h4>Date from</h4>
<input type="date" class="form-control" id="datefilterfrom" data-date-split-input="true">
<h4>Date to</h4>
<input type="date" class="form-control" id="datefilterto" data-date-split-input="true">
</div>
</div>
<span id="val"></span>
<table id="table" class="sortable">
<tr>
<th>Name</th>
<th>Date</th>
<th>Price</th>
</tr>
<tr>
<td>Name</td>
<td>20.10.2020</td>
<td>20</td>
</tr>
<tr>
<td>Name</td>
<td>21.10.2020</td>
<td>25</td>
</tr>
<tr>
<td>Name</td>
<td>22.10.2020</td>
<td>30</td>
</tr>
</table>
This is how it looks like when I select date range in HTML (so I need to get summary from only this selected tr)
I think there need to be some condition added here
sumVal = sumVal + parseInt(table.rows[i].cells[2].innerHTML);
You don't need two loops. You're already looping through the rows with .each() to make them visible or invisible, you can calculate the total in that same loop. After you determine if the row should be visible, use that variable in an if statement to add to the total.
jQuery has a built-in function .toggle() that will switch the visibility of an element. You can make visible a boolean variable instead of a display style value, then use that as the argument to .toggle(). Then you can use this same value in the if condition.
Make your access to columns less dependent on the table layout by using classes instead of column indexes. Use jQuery(tr).find(".price") to access the price column, for instance.
Use <thead> and <tbody> to distinguish the headings from the table data, then use tbody in the .each() loop to only process data rows.
function filterRows() {
var from = jQuery("#datefilterfrom").val();
var to = jQuery("#datefilterto").val();
if (!from && !to) { // no value for from and to
return;
}
from = from || "1970-01-01"; // default from to a old date if it is not set
to = to || "2999-12-31";
var dateFrom = moment(from);
var dateTo = moment(to);
var sumVal = 0;
jQuery("#table tbody tr").each(function(i, tr) {
var val = jQuery(tr).find(".date").text();
var dateVal = moment(val, "DD.MM.YYYY");
var visible = (dateVal.isBetween(dateFrom, dateTo, null, []));
jQuery(tr).toggle(visible);
if (visible) {
sumVal += parseInt(jQuery(tr).find(".price").text());
}
$("#val").text("Sum Value = " + sumVal);
});
}
jQuery("#datefilterfrom, #datefilterto").on("change", filterRows);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.4/moment.min.js"></script>
<div class="row">
<div class="col-md-3">
<h4>Date from</h4>
<input type="date" class="form-control" id="datefilterfrom" data-date-split-input="true">
<h4>Date to</h4>
<input type="date" class="form-control" id="datefilterto" data-date-split-input="true">
</div>
</div>
<span id="val"></span>
<table id="table" class="sortable">
<thead>
<tr>
<th>Name</th>
<th>Date</th>
<th>Price</th>
</tr>
<thead>
<tbody>
<tr>
<td>Name</td>
<td class="date">20.10.2020</td>
<td class="price">20</td>
</tr>
<tr>
<td>Name</td>
<td class="date">21.10.2020</td>
<td class="price">25</td>
</tr>
<tr>
<td>Name</td>
<td class="date">22.10.2020</td>
<td class="price">30</td>
</tr>
<tbody>
</table>

How to get the HTML TABLE Particular row Values using java script?

I created a table and put it data retrieving from fire base.
<table width="100%" class="table table-striped table-bordered table-hover">
<thead>
<tr>
<td class="th">Title</td>
<td class="th">First Name</td>
<td class="th">Last Name</td>
<td class="th">Hospital</td>
<td class="th">Spciality</td>
<td class="th">Doctor Fee</td>
<td class="th">Mobile Number</td>
<td class="th">Address</td>
<td class="th">Actions</td>
</tr>
</thead>
<tbody id="doctorlist">
<script>
var rootRef = firebase.database().ref("User/doctor");
rootRef.on("child_added",snap =>{
var fname=snap.child("Firstname").val();
var lname=snap.child("Lastname").val();
var id=snap.child("DoctorID").val();
var dob=snap.child("DOB").val();
var address=snap.child("Doctor_Address").val();
var email=snap.child("E-mail").val();
var mobile=snap.child("Mobile_no").val();
var hometp=snap.child("Home_no").val();
var sex=snap.child("Sex").val();
var hospital=snap.child("Hospital").val();
var slmcno=snap.child("SLMC_Number").val();
var speciality=snap.child("Spciality").val();
var emargancyperson=snap.child("Emargency_person").val();
var emargancyrelationship=snap.child("Emargency_reletionship").val();
var emargancymobile=snap.child("Emargency_TP").val();
var fee=snap.child("Doctor_fee").val();
var nic=snap.child("NICNo").val();
var title=snap.child("Title").val();
//var lname=snap.child("DocotID").val();
$("#doctorlist").append("<tr><td>"+title+"</td><td>"+fname+"</td><td>"+lname+"</td><td>"+hospital+"</td><td>"+speciality+"</td><td>"+"Rs."+fee+".00"+"</td><td>"+mobile+"</td><td>"+address+"</td><td><button>Remove</button></td></tr>");
});
</script>
This is working perfectly.But I want to get cell data to variables, when i click on specific row.
I used this script
<script>
var table = document.getElementById('doctorlist');
for (var i = 1; i < table.rows.length; i++) {
table.rows[i].onclick = function() {
//rIndex = this.rowIndex;
alert(this.cells[0].innerHTML + this.cells[1].innerHTML + this.cells[2].innerHTML...........);
};
}
</script>
It is ok to hard-cored tale but is doesn't work for this. how can I solve this?

Get column value of repeating table?

I have this table:
var table = document.getElementById('tableID'),
cells = table.getElementsByTagName('td');
for (var x = 0, len = cells.length; x < len; x++) {
cells[x].onclick = function () {
console.log(this.innerHTML);
};
}
<table class="table table-striped" id="tableID">
<tbody>
<tr ng-repeat="cup in cups">
<td>{{cup.cupnum}}</td>
<td>{{::cup.contents.model}}</td>
<td>{{::cup.contents.woa}}</td>
<td>{{::cup.contents.perfBy}}</td>
<td>{{::cup.contents.perfAt}}</td>
<td>{{::cup.contents.loadEvent}}</td>
<td>{{samples[cup.contents.sampleID-1].contents.name}}</td>
<td>{{holders[cup.contents.holderID-1].contents.type}}</td>
</tr>
</tbody>
</table>
How can I make it so that i'm just getting the value of the last column for each row without having to click? The: <td>{{holders[cup.contents.holderID-1].contents.type}}</td>
column
try to use:
cells = table.querySelector('td:last-child')
This will always return the last td of the rows.
To access the last columns, query all td:last-child
var cells = document.querySelectorAll('#tableID td:last-child');
var result = document.getElementById("result");
result.innerHTML="";
for (var x = 0, len = cells.length; x < len; x++) {
result.innerHTML+=cells[x].innerHTML+"<br>";
};
<table class="table table-striped" id="tableID" border="1">
<tbody>
<tr ng-repeat="cup in cups">
<td>{{cup.cupnum}}</td>
<td>{{::cup.contents.model}}</td>
<td>{{::cup.contents.woa}}</td>
<td>{{::cup.contents.perfBy}}</td>
<td>{{::cup.contents.perfAt}}</td>
<td>{{::cup.contents.loadEvent}}</td>
<td>{{samples[cup.contents.sampleID-1].contents.name}}</td>
<td>{{holders[cup.contents.holderID-1].contents.type}}</td>
</tr>
<tr ng-repeat="cup in cups">
<td>{{cup.cupnum}}</td>
<td>{{::cup.contents.model}}</td>
<td>{{::cup.contents.woa}}</td>
<td>{{::cup.contents.perfBy}}</td>
<td>{{::cup.contents.perfAt}}</td>
<td>{{::cup.contents.loadEvent}}</td>
<td>{{samples[cup.contents.sampleID-1].contents.name}}</td>
<td>{{holders[cup.contents.holderID-1].contents.type}}</td>
</tr>
</tbody>
</table>
<hr>
<h2>Result</h2>
<div id="result"></div>

How to Get InnerHTML for Table Cell instead of an object or NaN

I am attempting to create a string that contains all of the data within an HTML table using JavaScript (open to changing to JQuery). By using this method below, I receive an NaN value, instead of the data (numbers).
function Ard() {
var table = document.getElementById("tblData");
var dataStr = "";
for (var i = 0, row; row = table.rows[i]; i++) {
for (var j = 0, col; col = row.cells[j]; j++) {
var toAdd = col;
dataStr += toAdd;
}
}
};
I have also tried a jQuery method but it only returned an HTML object. It should be noted that when printing the 'col' value to the console, the data is collected properly (actual values).
The table I'm using is editable by the user, but it saves as a standard HTML table. Here is the basic code for the table below if it helps solve the problem.
<table id="tblData" class="table table-hover">
<thead>
<tr>
<th>Date</th>
<th>Time</th>
<th>Treatment Number</th>
<th>Cell Number</th>
<th>Waste Container Number</th>
</tr>
</thead>
<tbody></tbody>
</table>
Any ideas towards how to get the innerHTML and add it properly to the string?
I would also like to do this with a row by column loop (set of two for or each loops maybe?) so that I know what column I'm grabbing from.
Since you are OK to use jquery,
var dataStr = "";
$('#tblData > tbody').each(function(e) {
dataStr += $(this).text();
});
console.log(dataStr);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<table id="tblData" class="table table-hover">
<thead>
<tr>
<th>Date</th>
<th>Time</th>
<th>Treatment Number</th>
<th>Cell Number</th>
<th>Waste Container Number</th>
</tr>
</thead>
<tbody>
<tr>
<td>10101</td>
<td>20202</td>
<td>30303</td>
<td>40404</td>
<td>50505</td>
</tr>
<tr>
<td>wowowo</td>
<td>sksksk</td>
<td>alalal</td>
<td>qpqpqp</td>
<td>zmzmzm</td>
</tr>
</tbody>
</table>
If you want the dataStr to have the <td> tags also, you should use,
dataStr += $(this).html()
EDIT
If you also want to access the current column index, you can use this. But here, the dataStr would finally contain a single line string concatenating all the texts inside <td> tags.
$('#tblData > tbody > tr > td').each(function(e) {
var currentColNo = $(this).index();
dataStr += $(this).html();
});
With jQuery you could select all rows and the iterate over them and get the text:
var str = "", values = [];
$("#tblData").find('tbody').find('tr').each(function() {
//You can concatenate a string or push the values to an array
str += $(this).text();
values.push($(this).text());
});
console.log(str, values);
You can do it with pure js:
function Ard() {
var table = document.querySelectorAll("#tblData tr th");
var dataStr = "";
for (var i = 0; i < table.length; i++) {
dataStr += table[i].innerHTML;
}
};
JSFiddle Demo
This will get you all text from the table <td>s and post it into a textarea (just for demonstration purposes):
$('#out').val($('#tblData td').text())
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="tblData" class="table table-hover">
<thead>
<tr>
<th>Date</th>
<th>Time</th>
<th>Treatment Number</th>
<th>Cell Number</th>
<th>Waste Container Number</th>
</tr>
</thead>
<tbody>
<tr>
<td>some</td><td>extra</td><td>data</td>
</tr>
</tbody>
</table>
<textarea id="out" rows=10 cols=60></textarea>
Update:
If you "just" want to put the <td> contents into a single variable you could do:
var str=$('#tblData td').text()
I extended your example so you will actually get a result.

Categories

Resources