So I have the following HTML table on my site
<div class="timecard">
<table>
<tr class = "display-even-row">
<td align="left" style="color:#000099">In</td>
<td align="left" class="job_code">2400-Duffy's</td>
<td align="left" class="hrs">00:04</td>
</tr>
<tr class = "display-odd-row">
<td align="left" style="color:#009900">In</td>
<td align="left" class="job_code">1500-Orchard</td>
<td align="left" class="hrs">01:00</td>
</tr>
<tr class = "display-even-row">
<td align="left" style="color:#000099">In</td>
<td align="left" class="job_code">32-Black</td>
<td align="left" class="hrs">10:00</td>
</tr>
<tr class = "display-odd-row">
<td align="left" style="color:#009900">In</td>
<td align="left" class="job_code">1500-Orchard</td>
<td align="left" class="hrs">4</td>
</tr>
</table>
</div>
<div id="total">
</div>
And I have the following jquery script to calculate the total hours of each individual job code. It is designed dynamically to allow for more job codes to be added later. However, it is not adding up hours properly, but not displaying if a job has minutes.
$(document).ready(function(){
var timeString = $(this).next('td.hrs').text();
var components = timeString.split(':');
var seconds = components[1] ? parseInt(components[1], 10) : 0;
var hrs = parseInt(components[0], 10) + seconds / 60;
total += hrs;
var temp = [];
$('.job_code').each(function(index, element){
var text = $(this).text();
temp.push(text);
});
// remove duplicates
var job_code = [];
$.each(temp, function(index, element){
if($.inArray(element, job_code) === -1) job_code.push(element);
});
var sum = {};
$.each(job_code, function(index, element){
var total = 0;
$('.job_code:contains('+element+')').each(function(key, value){
total += parseInt($(this).next('td.hrs').text());
sum[index] = {'job_code' : element, 'total': total};
});
});
console.log(sum);
$.each(sum, function(index, element){
$('#total').append('<p>Total for '+element.job_code+': '+element.total+'</p>');
});
});
Any thoughts on what changes need to be made to make this work with 00:00 instead of just whole integers? Thanks in advance.
Short of using a date/time parsing library, you'll probably want to extract the integer strings on either side of the colon before you attempt to parse them.
var timeString = $(this).next('td.hrs').text();
var components = timeString.split(':');
var seconds = components[1] ? parseInt(components[1], 10) : 0;
var hrs = parseInt(components[0], 10) + seconds / 60;
total += hrs;
You could also use a regular expression to do this, but the split should work just fine.
Related
I'm making a simple weather site using HTML CSS and Javascript.
I've searched a lot of different questions but i can't figure out how to create 2 things.
For the temprature rows in my table I want to generate and insert random numbers for the temprature on each refresh of the page. id's "mNum" and "maNum".
On each page refresh I want to randomly show the weather picto's.
I want to do this both using Javascript, but I just can't find and figure out how to do that.
If someone could point me in the right direction that would be great! Thanks in advance.
My Table in HTML:
<table class="week" id="weer">
<tr class="days" id="header" >
<th class="r1">Vandaag</th>
<th class ="r2">Morgen</th>
<th class = "r3">Overmorgen</th>
<th class="r4">Daarna</th>
</tr>
<tr class="picto" id="pics">
<td class="r1"><img src="picto/rain%20(1).png" alt="regen" height="40"></td>
<td class="r2"><img src="picto/rainsun.png" alt="regen" height="40"></td>
<td class="r3"><img src="picto/cloudy.png" alt="wolk" height="40"></td>
<td class="r4"><img src="picto/sun.png" alt="zon" height="40"></td>
</tr>
<tr class="min" id="mTemp">
<td class="r1">Min. Temperatuur</td>
<td class="r2">Min. Temperatuur</td>
<td class="r3">Min. Temperatuur</td>
<td class="r4">Min. Temperatuur</td>
</tr>
<tr class="mintemp" id="mNum">
<td class="r1">5°</td>
<td class="r2">7°</td>
<td class="r3">9°</td>
<td class="r4">11°</td>
</tr>
<tr class="max" id="maTemp">
<td class="r1" >Max. Temperatuur</td>
<td class="r2">Max. Temperatuur</td>
<td class="r3">Max. Temperatuur</td>
<td class="r4">Max. Temperatuur</td>
</tr>
<tr class="maxtemp" id="maNum">
<td class="r1">16°</td>
<td class="r2">19°</td>
<td class="r3">21°</td>
<td class="r4">25°</td>
</tr>
<tr class="wind" id="wind">
<td colspan="4">Wind is niet van toepassing deze week</td>
</tr>
</table>
My only javascript so far to generate the random numbers for minimum temp and maximum temp.
function randomMax(){
var min = 9;
var max = 21;
return Math.floor(Math.random() * (+max - +min)) + +min;
}
function randomMin(){
var min = -6;
var max = 8;
return Math.floor(Math.random() * (+max - +min)) + +min;
}
A picture of how my weather table looks like:
Thanks in advance!
You can add the values by innerHtml and querySelectors:
//get all children of max temperature div and add some html into
document.querySelector("#maNum").children.map( (element) => {
element.innerHTML = `${randomMax()}°`;
});
//get all children of min temperature div and add some html into
document.querySelector("#mNum").children.map( (element) => {
element.innerHTML = `${randomMin()}°`;
});
//add the pics into list
const picsList = [
'<img src="picto/rain%20(1).png" alt="regen" height="40">',
'<img src="picto/rainsun.png" alt="regen" height="40">',
'<img src="picto/cloudy.png" alt="wolk" height="40">',
'<img src="picto/sun.png" alt="zon" height="40">'
];
//add random image html to elements on pics
document.querySelector("#pics").children.map( (element) => {
element.innerHTML = picsList[Math.floor(Math.random() * picsList.length];//ramdom index of array
});
The code I used to get random numbers in my table for the temprature:
function randomMax(){
var min = 9;
var max = 21;
return Math.floor(Math.random() * (+max - +min)) + +min;
}
document.getElementById('n5').innerHTML = randomMax() + '°';
document.getElementById('n6').innerHTML = randomMax() + '°';
document.getElementById('n7').innerHTML = randomMax() + '°';
document.getElementById('n8').innerHTML = randomMax() + '°';
function randomMin(){
var min = -6;
var max = 8;
return Math.floor(Math.random() * (+max - +min)) + +min;
}
document.getElementById('n1').innerHTML = randomMin() + '°';
document.getElementById('n2').innerHTML = randomMin() + '°';
document.getElementById('n3').innerHTML = randomMin() + '°';
document.getElementById('n4').innerHTML = randomMin() + '°';
This code got me random numbers in all of the table boxes where it was needed, I got every box with a different ID, when refreshing the page the value changes.
The code I used to get random images in my table:
var picsList = [
'picto/rain%20(1).png',
'picto/rainsun.png',
'picto/cloudy.png',
'picto/sun.png'
];
function randImg() {
const size = picsList.length;
document.getElementById('i1').src = picsList[Math.floor(size * Math.random())];
document.getElementById('i2').src = picsList[Math.floor(size * Math.random())];
document.getElementById('i3').src = picsList[Math.floor(size * Math.random())];
document.getElementById('i4').src = picsList[Math.floor(size * Math.random())];
}
randImg()
This code worked for me, I get each table box by id and then give them a random image for the list. So all 4 images in the table are different.
I am trying to create a function that will colorize the contents of the table based on the values of the row.
I am able to get the data from each row into an array and save the low and high values to a variable. How can I add a class low or high to the low and high values in each row?
In each tr I only want to compare the 1st,2nd,and 3rd position as the zero position is the index.
function showRows(s) {
var t = s.options[s.selectedIndex].text;
var rows = document.getElementById('mytab').getElementsByTagName('tr'),
i = 0,
r, c;
while (r = rows[i++]) {
if (t == 'All') {
r.style.display = ''
} else {
c = r.getElementsByTagName('td')[0].firstChild.nodeValue;
sxval = r.getElementsByTagName('td')[1].firstChild.nodeValue;
fcval = r.getElementsByTagName('td')[2].firstChild.nodeValue;
sgval = r.getElementsByTagName('td')[3].firstChild.nodeValue;
unval = r.getElementsByTagName('td')[4].firstChild.nodeValue;
array = [sxval, fcval, sgval, unval]
var low = Math.min(...array)
var high = Math.max(...array)
console.log("lowest" + " " + low)
console.log("highest" + " " + high)
console.log(c)
console.log(t)
r.style.display = parseInt(c) == parseInt(t) ? '' : 'none';
}
}
}
<body>
<table align="center" border="1" width="50%" cellspacing="0" cellpadding="4">
<tr>
<th>
<select name="mylist" onchange="showRows(this)">
<option value="m1">All</option>
<option value="m2">4</option>
<option value="m3">4.5</option>
<option value="m4">5</option>
</select>
</th>
</tr>
<br>
<table id="mytab" align="center" border="1" width="50%" cellspacing="0" cellpadding="4">
<tr class="content">
<td class="cj-has-text-centered contentcheck">
4 </td>
<td class="cj-has-text-centered">
50 </td>
<td class="cj-has-text-centered">
100 </td>
<td class="cj-has-text-centered">
200 </td>
<td class="cj-has-text-centered">
300 </td>
</tr>
<tr class="content">
<td class="cj-has-text-centered contentcheck">
4.5 </td>
<td class="cj-has-text-centered">
50 </td>
<td class="cj-has-text-centered">
100 </td>
<td class="cj-has-text-centered">
200 </td>
<td class="cj-has-text-centered">
300 </td>
</tr>
<tr class="content">
<td class="cj-has-text-centered contentcheck">
5 </td>
<td class="cj-has-text-centered">
50 </td>
<td class="cj-has-text-centered">
100 </td>
<td class="cj-has-text-centered">
200 </td>
<td class="cj-has-text-centered">
300 </td>
</tr>
</table>
You can use Jquery to do this. Here is the sample. Hope to help, my friend :))
<style>
.highest{
background-color:blue;
}
.lowest{
background-color:red;
}
</style>
function showRows(s) {
var t = s.options[s.selectedIndex].text;
var rows = document.getElementById('mytab').getElementsByTagName('tr'),
i = 0,
r, c;
while (r = rows[i++]) {
if (t == 'All') {
r.style.display = ''
} else {
c = r.getElementsByTagName('td')[0].firstChild.nodeValue;
sxval = r.getElementsByTagName('td')[1].firstChild.nodeValue;
fcval = r.getElementsByTagName('td')[2].firstChild.nodeValue;
sgval = r.getElementsByTagName('td')[3].firstChild.nodeValue;
unval = r.getElementsByTagName('td')[4].firstChild.nodeValue;
array = [sxval, fcval, sgval, unval]
var low = Math.min(...array)
var high = Math.max(...array)
console.log("lowest" + " " + low)
console.log("highest" + " " + high)
console.log(c)
console.log(t)
r.style.display = parseInt(c) == parseInt(t) ? '' : 'none';
//Skip the first column, use :not(:first-child)
$('tr').each(function(){
var vals = $('td:not(:first-child)',this).map(function () {
return parseInt($(this).text(), 10) ? parseInt($(this).text(), 10) : null;
}).get();
// then find their minimum
var min = Math.min.apply(Math, vals);
var max = Math.max.apply(Math, vals);
// tag any cell matching the min and max value
$('td', this).filter(function () {
return parseInt($(this).text(), 10) === min;
}).addClass('highest');
$('td', this).filter(function () {
return parseInt($(this).text(), 10) === max;
}).addClass('lowest');
});
}
}
};
How can I get the highest value in a table column by class? I have tried the following:
HTML
<table>
<tr><td class="speed">1.1</td></tr>
<tr><td class="speed">3.1</td></tr>
<tr><td class="speed">5.5</td></tr>
<tr><td class="speed">2.0</td></tr>
</table>
jQuery/Javascript
function gethighestspeeds(){
var speeds = $(".speed").map(function() {
return parseFloat(this.text, 10);
}).get();
var highestspeed = Math.max.apply(Math, speeds);
alert(highestspeed)
}
Also, how can I get all values if > than a certain number?
this.text is undefined for the td element, you need to parse parseFloat($(this).text(), 10);
function gethighestspeeds() {
var speeds = $(".speed").map(function() {
return parseFloat($(this).text(), 10);
}).get();
var highestspeed = Math.max.apply(Math, speeds);
snippet.log('high: ' + highestspeed);
var num = 2.3;
var array = $(".speed").map(function() {
var flt = parseFloat($(this).text(), 10);
return flt > num ? flt : undefined;
}).get();
snippet.log('array: ' + array)
//if you already have the speeds array
var array2 = speeds.filter(function(val) {
return num < val;
});
snippet.log('array2: ' + array)
}
gethighestspeeds();
<!-- Provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr>
<td class="speed">1.1</td>
</tr>
<tr>
<td class="speed">3.1</td>
</tr>
<tr>
<td class="speed">5.5</td>
</tr>
<tr>
<td class="speed">2.0</td>
</tr>
</table>
Try this........
var certainNumber=2.2; //Whatever you want to set
function gethighestspeeds(){
var speeds = $(".speed").map(function() {
return parseFloat(this.text, 10) > parseFloat(certainNumber);
}).get();
}
You have to use : $(this).text() instead of this.text in your map function:
return parseFloat($(this).text(), 10);
i am writing a code to select/remove the product from display table, and when the product is selected,then product with its price mus be displayed in some other table where at the end sum total is also needed which get updated as per selected product prices
<table id="table-example" class="table">
<thead>
<tr>
<th>Cause</th>
<th>Monthly Charge</th>
</tr>
</thead>
<tbody>
<tr>
<div id="selectedServices"></div>
<td id="myDiv"></td>
</tr>
</tbody>
</table>
<p> </p>
<p> </p>
<p> </p>
<p> </p>
<table id="table-example" class="table">
<thead>
<tr>
<th>Cause</th>
<th>Monthly Charge</th>
</tr>
</thead>
<div>
<tbody>
<p>
<tr>
<td>
<input type="checkbox" onclick="ToggleBGColour(this);" />
<label>table</label>
</td>
<td>80</td>
</tr>
<tr>
<td>
<input type="checkbox" onclick="ToggleBGColour(this);" />
<label>chair</label>
</td>
<td>45</td>
</tr>
<tr>
<td>
<input type="checkbox" onclick="ToggleBGColour(this);" />
<label>set</label>
</td>
<td>10</td>
</tr>
</tbody>
</div>
</table>
script
$(function() {
$(":checkbox").change(function() {
var arr = $(":checkbox:checked").map(function() { return $(this).next().text(); }).get();
$("#myDiv").text(arr.join(','));
});
});
function ToggleBGColour(item) {
var td = $(item).parent();
if (td.is('.rowSelected'))
td.removeClass("rowSelected");
else
td.addClass("rowSelected");
}
Here is the corresponding fiddle.
Based on your comment for my other answer, this should work for you then:
$(":checkbox").change(function () {
// Toggle class of selected row
$(this).parent().toggleClass("rowSelected");
// Get all items name, sum total amount
var sum = 0;
var arr = $(":checkbox:checked").map(function () {
sum += Number($(this).parents('tr').find('td:last').text());
return $(this).parents('tr').clone();
}).get();
// Display selected items and their sum
$("#selectedServices").html(arr).find('input').remove();
$("#total").text(sum);
});
This avoids the need for creating new HTML elements in the JavaScript code, and reduces the number of .maps() and .each() loops to one.
http://jsfiddle.net/samliew/uF2Ba/
Here is the javascript for but u need to remove onClick attrs :
$(function() {
$(":checkbox").change(function() {
ToggleBGColour(this);
var arr = $(":checkbox:checked").map(function() {
return $(this).next().text();
}).get();
var nums = $(":checkbox:checked").map(function() {
return parseInt($(this).parent().next().html());
}).get();
var total = 0;
for (var i = 0; i < nums.length; i++) {
total += nums[i] << 0;
}
$("#myDiv").text(arr.join(',') + 'total : '+total);
});
});
function ToggleBGColour(item) {
var td = $(item).parent();
if (td.is('.rowSelected'))
td.removeClass("rowSelected");
else
td.addClass("rowSelected");
}
I updated your fiddle with my answer : http://jsfiddle.net/A2SKr/9/
Here's what i've changed.
Slightly better formatted.
i removed the onclick attribute. Its bad practice to use this because of performance issues. Use delegates
Ive also changed a lil bit of your HTML. the output is now a table
added a total element to the output as well
javascript code :
$(":checkbox").change(function () {
var total = 0;
var check = $(":checkbox:checked");
var causes = check.map(function () {
return $(this).next().text();
}).get();
var costs = check.map(function () {
return $(this).parent().next().text()
}).get();
var tbody = $("#table-example tbody").empty();
$.each(causes, function (i, cause) {
tbody.append("<tr><td>" + cause + "</td><td id='" + i + "'><td/></tr>");
});
$.each(costs, function (i, cost) {
$('#' + i + '').html(cost);
total += parseInt(cost, 10);
});
tbody.append("<tr><td>Total</td><td>" + total + "<td/></tr>");
});
});
please refer to previous question here: Sum total for column in jQuery
i used Aymen's solution, but i edited it to suite my need. It stopped working, my code as below as seen at jsfiddle: http://jsfiddle.net/unKDk/15/
<table id="sum_table" width="300" border="1">
<tr class="titlerow">
<td>Apple</td>
<td>Orange</td>
<td>Watermelon</td>
<td>Strawberry</td>
<td>Total By Row</td>
</tr>
<tr>
<td class="rowAA">1</td>
<td class="rowAA">2</td>
<td class="rowBB">3</td>
<td class="rowBB">4</td>
<td class="totalRow"></td>
</tr>
<tr>
<td class="rowAA">1</td>
<td class="rowAA">2</td>
<td class="rowBB">3</td>
<td class="rowBB">4</td>
<td class="totalRow"></td>
</tr>
<tr>
<td class="rowAA">1</td>
<td class="rowAA">5</td>
<td class="rowBB">3</td>
<td class="rowBB">4</td>
<td class="totalRow"></td>
</tr>
<tr class="totalColumn">
<td class="totalCol">Total:</td>
<td class="totalCol">Total:</td>
<td class="totalCol">Total:</td>
<td class="totalCol">Total:</td>
<td class="totalCol">Total:</td>
</tr>
</table>
Jquery part is
var totals=[0,0,0,0,0];
$(document).ready(function(){
var $dataRows=$("#sum_table tr:not('.totalColumn, .titlerow')");
$dataRows.each(function() {
$(this).find('.rowAA').each(function(i){
totals[i]+=parseInt( $(this).html());
});
$(this).find('.rowBB').each(function(i){
totals[i]+=parseInt( $(this).html());
});
});
$("#sum_table td.totalCol").each(function(i){
$(this).html("total:"+totals[i]);
});
});
how to solve the problem that caused the jquery calculate wrongly.
how to calculate total by row
i need the class name exactly same.
I am not quite sure what you want, but if you just want to sum all rows by column then see below..
var totalsByRow = [0, 0, 0, 0, 0];
var totalsByCol = [0, 0, 0, 0, 0];
$(document).ready(function() {
var $dataRows = $("#sum_table tr:not('.totalColumn, .titlerow')");
$dataRows.each(function(i) {
$(this).find('td:not(.totalRow)').each(function(j) {
totalsByCol[j] += parseInt($(this).html());
totalsByRow[i] += parseInt($(this).html());
});
});
for (var i = 0; i < totalsByCol.length - 1; i++) {
totalsByCol[totalsByCol.length - 1] += totalsByCol[i];
}
$("#sum_table td.totalCol").each(function(i) {
$(this).html("total:" + totalsByCol[i]);
});
$("#sum_table td.totalRow").each(function(i) {
$(this).html("total:" + totalsByRow[i]);
});
});
DEMO
Essentially you want to target all of the td elements that are in the middle rows. Each time you cycle over a new td, you want to add its value to both the last td in its row (unless it is the last td in the row), and also to the td in the last row that shares its index.
$("#sum_table tr:not(:first,:last)").each(function(c,row) {
$("td",row).text(function(i,t) {
var n = parseInt( t, 10 ) || 0;
$(this).nextAll(":last-child").text(function(a,o) {
return n + ( parseInt( o, 10 ) || 0 );
});
$(row).nextAll("tr:last").find("td:nth-child("+(++i)+")").text(function(a,o){
return "Total: " + ( n + ( parseInt( o.replace(/[^\d]/g,""), 10 ) || 0 ) );
});
});
});
This should work for any table of any size, not restricting you to x columns, or y rows.
Fiddle: http://jsfiddle.net/unKDk/34/
With Commentary
I would encourage you to read the comments in the example below as they will help you understand what is going on with each line.
// For each table row that is not first or last
$("#sum_table tr:not(:first,:last)").each(function(c,row) {
// For each td within this row
$("td",row).text(function(i,t) {
// Determine numerical value of this td's content
var n = parseInt( t, 10 ) || 0;
// Find last td in this row, change its text
$(this).nextAll(":last-child").text(function(a,o) {
// Increment its value with the value of current TD
return n + ( parseInt( o, 10 ) || 0 );
});
// Find last row, and td within of same index as current td, change its text
$(row).nextAll("tr:last").find("td:nth-child("+(++i)+")").text(function(a,o){
// Increment its value (removing non-numbers) with the value of current td
return "Total: " + ( n + ( parseInt( o.replace(/[^\d]/g,""), 10 ) || 0 ) );
});
// End our td loop
});
// End our tr loop
});