So I have an HTML table that looks like the following.
<div class="timecard">
<h3>tommytest</h3>
<table class="misc_items timecard_list" border="0" cellpadding="2" cellspacing="0" style="margin:0 auto;">
<tbody>
<tr class="display_row odd">
<td align="left" class="job_code" style="color:#000099">2400-Orchard</td>
<td align="right">9:47am</td>
<td align="right">5/19/2014</td>
<td align="right" class="hrs">01:00</td>
</tr>
<tr class="display_odd row">
<td align="left" class="job_code" style="color:#000099">1200-Duffy's</td>
<td align="right">12:37am</td>
<td align="right">5/17/2014</td>
<td align="right" class="hrs">2:00</td>
</tr>
</tbody>
</table>
</div>
<div class="timecard">
<h3>testtest</h3>
<table class="misc_items timecard_list" border="0" cellpadding="2" cellspacing="0" style="margin:0 auto;">
<tbody>
<tr class="display_row odd">
<td align="left" class="job_code" style="color:#000099">2400-Orchard</td>
<td align="right">9:47am</td>
<td align="right">5/19/2014</td>
<td align="right" class="hrs">01:00</td>
</tr>
<tr class="display_odd row">
<td align="left" class="job_code" style="color:#000099">1200-Duffy's</td>
<td align="right">12:37am</td>
<td align="right">5/17/2014</td>
<td align="right" class="hrs">2:00</td>
</tr>
</tbody>
</table>
</div>
<div id="total"></div>
Then I have a jquery script that takes the total "job_code" hours and adds them up for each individual one. However, right now the script combines "tommytest" and "testtest" job codes together. I'm trying to get it to calculate each one individually and print it underneath each's respected table. Any ideas are greatly appreciated.
$(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();
if (text != 'Out') {
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) {
var timeString = $(this).siblings('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;
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>');
});
});
Link to jsFiddle: http://jsfiddle.net/Ha546/2/
If at all possible I'd like this to be dynamic as there will be more than just these two tables. Thanks ahead of time for the help.
When you query for the TD tags, $(this).next('td.hrs') you are not being specific enough about which table you want the TD tags from. If you are more specific, for example, adding an id to the tables,
<table id="tommytest">...</table>
<table id="testtest">...</table>
then you can query by table like so:
var tdsFromTommytest = $(this).next('#tommytest td.hrs')
var tdsFromTesttest = $(this).next('#testtest td.hrs')
Now that you have the two separate TD lists, you can process how you want. That, I think is the crux of your problem. But hopefully that helps you enough to see how you'd update a separate total tag under each table.
You could do this for tommyTest and subsequently for testtest :
Add id to the individual table
<table id="tommyTest">
And in javascript create different method for calculating the value :
$('#tommyTest').find('.job_code').each(function (index, element) {
var text = $(this).text();
if (text != 'Out') {
temp.push(text);
}
});
Related
I have mockup like this
The HTML table to work with
The table above will calculate subtotal and total_harga using the entered value in jumlah. Calculations work fine, but my code is still using static JavaScript.
If there are a lot of rows in the table, it will be troublesome, if you have to write the getElementById code for all the inputs. How to use looping so that all the inputs can be handled without describing the table rows one by one. This is my HTML and JavaScript.
<div class="container">
<table class="tg" id="sales">
<thead>
<tr>
<th class="tg-0lax">No.</th>
<th class="tg-0lax">Item</th>
<th class="tg-0lax">Jumlah</th>
<th class="tg-0lax">Harga Satuan</th>
<th class="tg-0lax">Diskon Satuan</th>
<th class="tg-0lax">Sub-Total</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tg-0lax">1</td>
<td class="tg-0lax">MIE INSTAN</td>
<td class="tg-keyup"> <input type="text" id="input1" name="fname" onkeyup="CalculationPrice()" placeholder="Masukan jumlah"><br></td>
<td class="tg-0lax" id="harga_satuan1">5000</td>
<td class="tg-0lax" id="diskon_satuan1">500</td>
<td class="tg-0lax" id="sub_total1"></td>
</tr>
<tr>
<td class="tg-0lax">2</td>
<td class="tg-0lax">SUSU UHT</td>
<td class="tg-keyup"><input type="text" id="input2" name="fname" onkeyup="CalculationPrice()" placeholder="Masukan jumlah"><br></td>
<td class="tg-0lax" id="harga_satuan2">6000</td>
<td class="tg-0lax" id="diskon_satuan2">1000</td>
<td class="tg-0lax" id="sub_total2"></td>
</tr>
<tr>
<td class="tg-0lax">3</td>
<td class="tg-0lax">KERIPIK</td>
<td class="tg-keyup"> <input type="text" id="input3" name="fname" onkeyup="CalculationPrice()" placeholder="Masukan jumlah"><br></td>
<td class="tg-0lax" id="harga_satuan3">8000</td>
<td class="tg-0lax" id="diskon_satuan3">500</td>
<td class="tg-0lax" id="sub_total3"></td>
</tr>
<tr>
<td class="tg-0lax"></td>
<td class="tg-1lax" colspan="4">TOTAL HARGA</td>
<td class="tg-0lax" id="total_price"></td>
</tr>
</tbody>
</table>
this is my code javascript :
function CalculationPrice() {
let input1 = document.getElementById("input1").value;
let input2 = document.getElementById("input2").value;
let input3 = document.getElementById("input3").value;
let hargaSatuan1 = document.getElementById("harga_satuan1").innerText;
let hargaSatuan2 = document.getElementById("harga_satuan2").innerText;
let hargaSatuan3 = document.getElementById("harga_satuan3").innerText;
let diskonSatuan1 = document.getElementById("diskon_satuan1").innerText;
let diskonSatuan2 = document.getElementById("diskon_satuan2").innerText;
let diskonSatuan3 = document.getElementById("diskon_satuan3").innerText;
if(input1.length == 0){
let total1 = document.getElementById("sub_total1").innerHTML = 0;
}else if(input1.length > 0){
let subinput = (parseInt(hargaSatuan1) - parseInt(diskonSatuan1)) * parseInt(input1)
let total1 = document.getElementById("sub_total1").innerHTML = subinput;
}
if(input2.length == 0){
let total2 = document.getElementById("sub_total2").innerHTML = 0;
}
else if(input2.length > 0){
let subinput2 = (parseInt(hargaSatuan2) - parseInt(diskonSatuan2)) * parseInt(input2)
let total2 = document.getElementById("sub_total2").innerHTML = subinput2;
}
if(input3.length == 0){
let total3 = document.getElementById("sub_total3").innerHTML = 0;
}
else if(input3 !== null){
let subinput3 = (parseInt(hargaSatuan3) - parseInt(diskonSatuan3)) * parseInt(input3)
let total3 = document.getElementById("sub_total3").innerHTML = subinput3;
}
let total1 = document.getElementById("sub_total1").innerText
let total2 = document.getElementById("sub_total2").innerText
let total3 = document.getElementById("sub_total3").innerText
let total_price = parseInt(total1) + parseInt(total2) + parseInt(total3)
let totalPriceHtml = document.getElementById("total_price").innerHTML = formatRupiah(total_price, "Rp.");
}
function formatRupiah(angka, prefix) {
let number_string = angka.toString().replace(/[^,\d]/g, ""),
split = number_string.split(","),
sisa = split[0].length % 3,
rupiah = split[0].substr(0, sisa),
ribuan = split[0].substr(sisa).match(/\d{3}/gi);
if (ribuan) {
separator = sisa ? "." : "";
rupiah += separator + ribuan.join(".");
}
rupiah = split[1] != undefined ? rupiah + "," + split[1] : rupiah;
return prefix == undefined ? rupiah : rupiah ? "Rp. " + rupiah : "";
}
Using ids on a table makes a lot of unnecessary work, it's much easier to rely on the structure of a static table. And, instead of inline event handlers, we can benefit from event delegation. Here's an example of how to listen input event on tbody and a simple reduce loop to calculate the total sum of subtotals.
const tbody = document.querySelector('#sales'),
rows = Array.from(tbody.rows), // All the rows of the tbody
total = rows.pop().cells[2]; // The TOTAL HARGA cell
function calcTot(e) {
const value = +e.target.value || 0,
rowIndex = e.target.closest('tr').rowIndex - 1, // Constant 1 = the amount of the rows in thead
cells = Array.from(rows[rowIndex].cells),
harga = +cells[3].textContent,
diskon = +cells[4].textContent,
sub = cells[5];
sub.textContent = harga - diskon * value;
total.textContent = rows.reduce((acc, row) => {
return acc += +row.cells[5].textContent;
}, 0);
}
// Calculate the first sums
rows.forEach(row => {
// Call calcTot with a fake event object
calcTot({target: row.cells[2]});
});
tbody.addEventListener('input', calcTot);
<div class="container">
<table class="tg">
<thead>
<tr>
<th class="tg-0lax">No.</th>
<th class="tg-0lax">Item</th>
<th class="tg-0lax">Jumlah</th>
<th class="tg-0lax">Harga Satuan</th>
<th class="tg-0lax">Diskon Satuan</th>
<th class="tg-0lax">Sub-Total</th>
</tr>
</thead>
<tbody id="sales">
<tr>
<td class="tg-0lax">1</td>
<td class="tg-0lax">MIE INSTAN</td>
<td class="tg-keyup"> <input type="text" name="fname[]" placeholder="Masukan jumlah"></td>
<td class="tg-0lax">5000</td>
<td class="tg-0lax">500</td>
<td class="tg-0lax"></td>
</tr>
<tr>
<td class="tg-0lax">2</td>
<td class="tg-0lax">SUSU UHT</td>
<td class="tg-keyup"><input type="text" name="fname[]" placeholder="Masukan jumlah"></td>
<td class="tg-0lax">6000</td>
<td class="tg-0lax">1000</td>
<td class="tg-0lax"></td>
</tr>
<tr>
<td class="tg-0lax">3</td>
<td class="tg-0lax">KERIPIK</td>
<td class="tg-keyup"> <input type="text" name="fname[]" placeholder="Masukan jumlah"></td>
<td class="tg-0lax">8000</td>
<td class="tg-0lax">500</td>
<td class="tg-0lax"></td>
</tr>
<tr>
<td class="tg-0lax"></td>
<td class="tg-1lax" colspan="4">TOTAL HARGA</td>
<td class="tg-0lax"></td>
</tr>
</tbody>
</table>
</div>
Notice also, that I've moved the sales id from the table tag to the tbody tag, and how the event handler function is used to calculate the subtotal and total sums without an actual event by passing an object which contains the needed information of the event object.
First, you should have the data source (in an array of objects). Such as:
var dataSource = [
{ id: 1, item: "MIE INSTAN", HargaSatuan: 5000, DiskonSatuan: 500 },
{ id: 2, item: "SUSU UHT", HargaSatuan: 6000, DiskonSatuan: 1000 },
{ id: 3, item: "KERIPIK", HargaSatuan: 8000, DiskonSatuan: 500 },
]
Then, you can loop through this array to construct your table, using either JQuery or JavaScript's "insertRow()".
Reference link for JavaScript's insertRow()
<html>
<head>
<style>
table {
border-collapse: collapse;
}
table, td, th {
border: 1px solid black
}
</style>
</head>
<body>
<table id="myTable">
<tr>
<th class="tg-0lax">No.</th>
<th class="tg-0lax">Item</th>
<th class="tg-0lax">Jumlah</th>
<th class="tg-0lax">Harga Satuan</th>
<th class="tg-0lax">Diskon Satuan</th>
<th class="tg-0lax">Sub-Total</th>
</tr>
</table>
<br>
<script>
function myFunction() {
var dataSource = [{
id: 1,
item: "MIE INSTAN",
hargaSatuan: 5000,
diskonSatuan: 500
},
{
id: 2,
item: "SUSU UHT",
hargaSatuan: 6000,
diskonSatuan: 1000
},
{
id: 3,
item: "KERIPIK",
hargaSatuan: 8000,
diskonSatuan: 500
},
]
var table = document.getElementById("myTable");
dataSource.forEach(function(data, index) {
var row = table.insertRow(index + 1);
var noCell = row.insertCell(0);
var itemCell = row.insertCell(1);
var jumlahCell = row.insertCell(2);
var hargaSatuanCell = row.insertCell(3);
var diskonSatuanCell = row.insertCell(4);
var subTotalCell = row.insertCell(5);
noCell.innerHTML = data.id;
itemCell.innerHTML = data.item;
hargaSatuanCell.innerHTML = data.hargaSatuan;
diskonSatuanCell.innerHTML = data.diskonSatuan
})
}
myFunction()
</script>
</body>
</html>
You only need to modify the datasource and refresh the table if there are any new data.
This might not be the best method of doing this, but this will give you a basic understanding on the algorithm and steps required for your needs.
I wants to change the output of the <p id="demo> to <table> with <tr> and <td>but it involved Javascript in the output so it doesn't on what I've tried.
<button onclick="myFunction()">Predict</button>
<div id="demo" align="center"></div>
<script type="text/javascript">
var selectedprg = '';
var selectedcount = '';
var selectedcity = '';
var average = '';
function myFunction() {
document.getElementById("demo").innerHTML = `
<table>
<tr>
<td style="padding: 5px;">Selected program</td>
<td style="padding: 5px;">${selectedprg}</td>
</tr>
<tr>
<td style="padding: 5px;">Total number of students</td>
<td style="padding: 5px;">${selectedcount}</td>
</tr>
</table>'
}
$(document).ready(function(){
$("#prg").change( function(){
selectedprg = $('#prg option:selected').text();
selectedcount = $('#prg option:selected').data('prgcount');
selectedcity = $('#prg option:selected').data('citycount');
if(selectedcount > 5){
average = selectedcount / 3 + 5;
} else{
average = selectedcount / 3 - 5;
}
});
});
</script>
Current output
Expected output
Could someone assist on this? Thank you.
You can do something like this:
document.getElementById("demo").innerHTML = `
<table>
<tr>
<td style="padding: 5px;">Selected program</td>
<td style="padding: 5px;">${selectedprg}</td>
</tr>
<tr>
<td style="padding: 5px;">Total number of students</td>
<td style="padding: 5px;">${selectedcount}</td>
</tr>
</table>
`
the styling should be writing with css ofcourse.
I am trying to loop through all my currently displayed tables using the td attribute.
var name = "";
var theCell = "";
var width1 = "";
var width2 = "";
var intX = 0;
$("td").each(function (inx) {
name = $(this).data("colname");
theCell = $('[data-colname="' + name + '"]')[0];
console.log(theCell);
if (typeof theCell != 'undefined') {
width1 = theCell.scrollWidth;
width2 = theCell.clientWidth;
//console.log(width1);
if (width1 > width2) {
//console.log(theCell);
$(theCell).ellipsis({ lines: 1 });
$(theCell).css({ 'background-color': '#000' });
}
}
});
The output of console.log(theCell):
<td data-colname="number_0" class="jsgrid-cell jsgrid-align-left" style="width: 80px;">1</td>
<td data-colname="line_0" class="jsgrid-cell jsgrid-align-left" style="width: 80px;">1</td>
<td data-colname="network_0" class="jsgrid-cell jsgrid-align-left" style="width: 80px;">Welcome 1</td>
...more here...
<td data-colname="number_0" class="jsgrid-cell jsgrid-align-left" style="width: 80px;">45</td>
<td data-colname="line_0" class="jsgrid-cell jsgrid-align-left" style="width: 80px;">2</td>
<td data-colname="network_0" class="jsgrid-cell jsgrid-align-left" style="width: 80px;">Welcome 2</td>
...more here...
<td data-colname="number_0" class="jsgrid-cell jsgrid-align-left" style="width: 80px;">23</td>
<td data-colname="line_0" class="jsgrid-cell jsgrid-align-left" style="width: 80px;">775</td>
<td data-colname="network_0" class="jsgrid-cell jsgrid-align-left" style="width: 80px;">Welcome 3</td>
...more here...etc etc...
And on the page it looks like this:
However, It seems to just loop through the first td and that's all. I figured its due to the [0] but I'm not sure what needs to be done in order for it to loop through each td?
It is loop through each TD since I have it all wrapped inside the jquery each function but it just keeps looping at the first td row. Each row is named the same thing (aka data-colname="number_0", data-colname="line_0", etc...) so I cant look for that to distinguish from one row to another..
My guess is that you want to do this:
$('td').each(function (index, elem) {
if (elem.scrollWidth > elem.clientWidth) {
// console.log(elem);
$(elem).ellipsis({ lines: 1 }).css({ 'background-color': '#000' });
}
});
Including the second parameter in the .each handler gives you direct access to the element being looped over.
This line in your code:
theCell = $('[data-colname="' + name + '"]')[0];
will only ever pull back the first td because of the [data-colname="' + name + '"] selector as each row in your table appears to share the same data-colname attribute.
I'm creating a userscript that collects and displays text from the following table using javascript / jQuery:
<table id="table-cours">
<tbody>
<tr>
<td class="calendar-time"> time1 </td>
<td>
<div class = popup-calendar-event> popup content 1 </div>
<div class = "link-event"> event 1 </div>
</td>
</tr>
<tr>
<td class="calendar-time"> time2 </td>
<td>
<div class = popup-calendar-event> popup content 2 </div>
<div class = "link-event"> event 2 </div>
</td>
</tr>
<tr>
<td class="calendar-time"> time3 </td>
<td>
<div class = popup-calendar-event> popup content 3 </div>
<div class = "link-event"> event 3 </div>
</td>
</tr>
</tbody>
</table>
I want to collect all the text contained in this table except that which is contained within the div.popup-calendar-event elements.
My objective is to display it like this:
time 1 : event 1
time 2 : event 2
time 3 : event 3
The problem is that the number of lines of the table can change, here I put 3 lines but they can be 1 or 10 or any other number.
I tried many ways like using the not() method, or a for() loop with an array of "tr" elements but it never works.
$('tr').each(function(data) {
var calTime = $(this).find('.calendar-time')[0].innerHTML;
var linkEvent = $(this).find('.link-event')[0].innerHTML;
$("#result").append('<li><b>' + calTime + '</b> : ' + linkEvent + '</li>');
console.log('<li><b>' + calTime + '</b> : ' + linkEvent + '</li>');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<table id="table-cours">
<tbody>
<tr>
<td class="calendar-time">time1</td>
<td>
<div class=p opup-calendar-event>popup content 1</div>
<div class="link-event">event 1</div>
</td>
</tr>
<tr>
<td class="calendar-time">time2</td>
<td>
<div class=p opup-calendar-event>popup content 2</div>
<div class="link-event">event 2</div>
</td>
</tr>
<tr>
<td class="calendar-time">time3</td>
<td>
<div class=p opup-calendar-event>popup content 3</div>
<div class="link-event">event 3</div>
</td>
</tr>
</tbody>
</table>
<ul id="result"></ul>
You can use something like this to parse table content and obtain an array of objects
var data = $('#table-cours > body > tr').map(function($i, $r) {
var $row = $(this);
return {
title: $row.find('.calendar-time').text(),
event: $row.find('.link-event').text()
};
}).get();
After that you can use data array for whatever you need.
You can try something like
$(".calendar-time").each(function () {
console.log($(this).html() + '-' + $(this).next('td').find('.link-event').html());
});
fiddle demo-http://jsfiddle.net/bL644p7b/
$(function(){
$("#table-cours .popup-calendar-event").each(function(iter, item){
$(".result").append("<div> time "+(iter+1) +" "+ $(this).text() +"</div>");
});
});
You just each a each method to iterate. The first argument is the iterator.
http://jsfiddle.net/qufgyh3c/
var rows = $('#table-cours > tr');
var map = {};
rows.each(function(row){
var key = $(row).find('td.calendar-time');
var value = $(row).find('td > div.link-event');
map[key]=value;
});
$(document).ready(function() {
$(".calendar-time").each(function() {
var output = "";
output += $(this).text() + " : ";
output += $(this).next().find(".link-event").text();
$(".output").append(output);
});
});
JSFiddle: https://jsfiddle.net/cq772j9s/
I would do:
$.each($('#table-cours tr'), function (i, val) {
$('#results ul').append('<li><strong>' + $(val).find('td.calendar-time').text() + '</strong>:' + $(val).find('.link-event').text() + '</li>');
});
example fiddle here
I have this variable:
var number = "1,10,25,60";
How can I parse it inside a view into this form?
<tr>
<td ng-click="ctrl.set(1)>1</td>
<td ng-click="ctrl.set(10)>10</td>
<td ng-click="ctrl.set(25)>25</td>
<td ng-click="ctrl.set(60)>60</td>
</tr>
In normal js I would just do var numbers = number.split(","); and then some loop like so:
var html;
for (i = 0; i <= numbers.length; i++) {
html += "<td ng-click='ctrl.set" + numbers[i] + "'>" + numbers[i] + "</td>";
}
Maybe some directive?
Assign it to a $scope var (the split result)
var number = "1,10,25,60";
$scope.numbers = number.split(",");
And the view:
<tr ng-repeat="num in numbers">
<td ng-click="ctrl.set(num)>{{num}}</td>
</tr>
ng-repeat will iterate through an array:
<html>
<head>
<script data-require="angular.js#1.3.x" src="https://code.angularjs.org/1.3.17/angular.js"></script>
</head>
<body ng-app >
<input ng-model="$scope.numbers" ng-init="$scope.numbers = [1,10,25,60]"/>
<table>
<tbody>
<tr>
<td ng-repeat="n in $scope.numbers track by $index"
ng-click="console.log(n);$scope.selected = n">{{n}}
</td>
</tr>
</tbody>
</table>
<div>{{$scope.selected}}</div>
</body>
</html>