Javascript can't add an argument to a function with loop - javascript

i have a code that should do heatmap when applied to html table:
html table code:
<table class='table' id='js-datatable' cellspacing="0.9" cellpadding="8" border="1">
<tr>
<th align=center style="white-space: nowrap;" bgcolor=grey>product</th>
<th align=center style="white-space: nowrap;" bgcolor=grey>Jan</th>
<th align=center style="white-space: nowrap;" bgcolor=grey>Feb</th>
<th align=center style="white-space: nowrap;" bgcolor=grey>Mar</th>
<th align=center style="white-space: nowrap;" bgcolor=grey>Apr</th>
<th align=center style="white-space: nowrap;" bgcolor=grey>May</th>
</tr>
<tr class='heatmap-stable'>
<td align=center>K22</td>
<td align=center>655$</td>
<td align=center>365$</td>
<td align=center>265$</td>
<td align=center>125$</td>
<td align=center>36$</td>
</tr>
<tr class='heatmap-stable'>
<td align=center>K52</td>
<td align=center>90</td>
<td align=center>50</td>
<td align=center>120</td>
<td align=center>80</td>
<td align=center>190</td>
</tr>
<tr class='heatmap-stable'>
<td align=center>J42</td>
<td align=center>1267</td>
<td align=center>1567</td>
<td align=center>347</td>
<td align=center>697</td>
<td align=center>70</td>
</tr>
<script src='https://cdn.bootcdn.net/ajax/libs/jquery/2.1.3/jquery.js'></script>
<script type='text/javascript' src='script.js'></script>
</table>
javаscript file code:
function clean_formatted_data(str) {
return parseFloat (str.replace (/([%,$,\,])+/g, ''));
}
function col_to_array(tbl_col, target) {
// Returns column `n` (zero indexed) in table id `target` as an array
var colArray = $ ('#' + target + ' td:nth-child(' + tbl_col + ')').map (function () {
return clean_formatted_data ($ (this).text ());
}).get ();
return colArray;
}
//------ new schtuff ------------------------//
function get_pos_of_max(col_data) {
return $.inArray (Math.max.apply (Math, col_data), col_data)
}
function generate_opacities(col_data, max) {
var opacity_array = [];
var increment = max / (col_data.length);
for (i = col_data.length; i >= 1; i--) {
opacity_array.push (i * increment / 100);
}
return opacity_array;
}
function process_col_best_performing(tbl_col, target) {
var col_data = col_to_array (tbl_col, target);
var opacity_array = generate_opacities (col_data, 50);
var row_count = col_data.length;
for (var i = 1; i <= row_count; i++) {
$ ('#' + target + ' tr:nth-child(' + (get_pos_of_max (col_data) + 1) + ') td:nth-child(' + tbl_col + ')').css ('background', 'rgba(0,0,255,' + opacity_array[0] + ')');
col_data[get_pos_of_max (col_data)] = null;
for (const spliceElement of opacity_array.splice (0, 1)) {
}
}
}
lets say i have 5 columns, so my javascript function can be applied in this way:
process_col_best_performing (tbl_col:1, target:'js-datatable');
process_col_best_performing (tbl_col:2, target:'js-datatable');
process_col_best_performing (tbl_col:3, target:'js-datatable');
But because this is only an example, real html table can have any amount of columns i want to make this with a for loop, i tried with code below, but its not working
var cols_qty = document.getElementById ('js-datatable').rows[0].cells.length
var i;
for(i = 1; i < 4; i++) {
console.log(i)
process_col_best_performing(tbl_col=i,'js-datatable');
}
*I'm totally new in javascript, so if you know the answer, please explain it in the simplest way as possible.

Not sure if this helps, but try the below code, the first thing do not declare as global var i; before the for loop, I am not sure if you are doing the same in your code, but the same i is getting changed inside the function and affecting the loop where you are calling process_col_best_performing. Check the below code and see if this make sense.
var cols_qty = document.getElementById ('js-datatable').rows[0].cells.length
for(var i = 1; i < 4; i++) {
console.log(i)
process_col_best_performing(i,'js-datatable');
}
function clean_formatted_data(str) {
return parseFloat (str.replace (/([%,$,\,])+/g, ''));
}
function col_to_array(tbl_col, target) {
// Returns column `n` (zero indexed) in table id `target` as an array
var colArray = $ ('#' + target + ' td:nth-child(' + tbl_col + ')').map (function () {
return clean_formatted_data ($ (this).text ());
}).get ();
return colArray;
}
//------ new schtuff ------------------------//
function get_pos_of_max(col_data) {
return $.inArray (Math.max.apply (Math, col_data), col_data)
}
function generate_opacities(col_data, max) {
var opacity_array = [];
var increment = max / (col_data.length);
for (var i = col_data.length; i >= 1; i--) {
opacity_array.push (i * increment / 100);
}
return opacity_array;
}
function process_col_best_performing(tbl_col, target) {
var col_data = col_to_array (tbl_col, target);
var opacity_array = generate_opacities (col_data, 50);
var row_count = col_data.length;
for (var i = 1; i <= row_count; i++) {
$ ('#' + target + ' tr:nth-child(' + (get_pos_of_max (col_data) + 1) + ') td:nth-child(' + tbl_col + ')').css ('background', 'rgba(0,0,255,' + opacity_array[0] + ')');
col_data[get_pos_of_max (col_data)] = null;
for (const spliceElement of opacity_array.splice (0, 1)) {
}
}
}
<script src='https://cdn.bootcdn.net/ajax/libs/jquery/2.1.3/jquery.js'></script>
<table class='table' id='js-datatable' cellspacing="0.9" cellpadding="8" border="1">
<tr>
<th align=center style="white-space: nowrap;" bgcolor=grey>product</th>
<th align=center style="white-space: nowrap;" bgcolor=grey>Jan</th>
<th align=center style="white-space: nowrap;" bgcolor=grey>Feb</th>
<th align=center style="white-space: nowrap;" bgcolor=grey>Mar</th>
<th align=center style="white-space: nowrap;" bgcolor=grey>Apr</th>
<th align=center style="white-space: nowrap;" bgcolor=grey>May</th>
</tr>
<tr class='heatmap-stable'>
<td align=center>K22</td>
<td align=center>655$</td>
<td align=center>365$</td>
<td align=center>265$</td>
<td align=center>125$</td>
<td align=center>36$</td>
</tr>
<tr class='heatmap-stable'>
<td align=center>K52</td>
<td align=center>90</td>
<td align=center>50</td>
<td align=center>120</td>
<td align=center>80</td>
<td align=center>190</td>
</tr>
<tr class='heatmap-stable'>
<td align=center>J42</td>
<td align=center>1267</td>
<td align=center>1567</td>
<td align=center>347</td>
<td align=center>697</td>
<td align=center>70</td>
</tr>
</table>

Related

How to loop table HTML in javascript?

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.

Add columns to a new table row in JQuery

I have the following html:
<table id='myTable'>
<tbody>
<tr>
<td id=col1">12</td>
<td id=col2">55</td>
<td id=col3">142</td>
<td id=col4">7</td>
</tr>
</tbody>
</table>
I would like to use JQuery to append everything after column 3 (col3) to a new row. Ideally I would end up with something like this:
<table id='myTable'>
<tbody>
<tr>
<td id=col1">12</td>
<td id=col2">55</td>
<td id=col3">142</td>
</tr>
<tr>
<td id=col4">7</td>
</tr>
</tbody>
</table>
Any ideas how this could be achieved? I have tried a few things but haven't been able to get it working.
You could define a generic redistribution function, that takes as argument the desired number of columns, and which just fills up the rows with content from top to bottom, using that number of columns.
It could even be a jQuery plugin:
$.fn.redistribute = function(maxNumCols) {
if (maxNumCols < 1) return;
$(this).each(function () {
let cells = Array.from($("td", this));
let $tr = $("tr", this);
let rowCount = Math.ceil(cells.length / maxNumCols);
for (let i = 0; i < rowCount; i++) {
let $row = i >= $tr.length ? $("<tr>").appendTo(this) : $tr.eq(i);
$row.append(cells.splice(0, maxNumCols));
}
});
}
// I/O management
function alignTable() {
let cols = +$("input").val(); // Get desired number of columns
$("#myTable").redistribute(cols); // Apply to table
}
// Refresh whenever input changes
$("input").on("input", alignTable);
// Refresh on page load
alignTable();
table { border-collapse: collapse; border: 2px solid }
td { border: 1px solid; padding: 4px }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Desired number of columns: <input type="number" size="3" value="4" min="1">
<table id='myTable'>
<tbody>
<tr>
<td>12</td>
<td>55</td>
<td>142</td>
<td>7</td>
<td>20</td>
<td>410</td>
<td>99</td>
</tr>
</tbody>
</table>
Here is a version with one extra statement that sets the colspan on the very last td element so it occupies the remaining columns in the last row:
$.fn.redistribute = function(maxNumCols) {
if (maxNumCols < 1) return;
$(this).each(function () {
let cells = Array.from($("td", this));
let $tr = $("tr", this);
let rowCount = Math.ceil(cells.length / maxNumCols);
for (let i = 0; i < rowCount; i++) {
let $row = i >= $tr.length ? $("<tr>").appendTo(this) : $tr.eq(i);
$row.append(cells.splice(0, maxNumCols));
}
$("td", this).last().attr("colspan", rowCount * maxNumCols - cells.length + 1);
});
}
// I/O management
function alignTable() {
let cols = +$("input").val(); // Get desired number of columns
$("#myTable").redistribute(cols); // Apply to table
}
// Refresh whenever input changes
$("input").on("input", alignTable);
// Refresh on page load
alignTable();
table { border-collapse: collapse; }
td { border: 1px solid; padding: 4px }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Desired number of columns: <input type="number" size="3" value="4" min="1">
<table id='myTable'>
<tbody>
<tr>
<td>12</td>
<td>55</td>
<td>142</td>
<td>7</td>
<td>20</td>
<td>410</td>
<td>99</td>
</tr>
</tbody>
</table>
It sounds like you're still new to jQuery. To give you an idea how to solve your described problem, I have written a solution here. I hope it helps you.
// parameters for splitting
var splitIndex = 3,
splitClass = '.split-columns';
// start the splitting
splitColumnsIntoRows();
function splitColumnsIntoRows() {
var $tables = $(splitClass),
numberTables = $tables.length;
if (numberTables == 0) {
return;
}
for (var i = 0; i < numberTables; i++) {
iterateSplittingRows($($tables[i]).find('tr'));
}
}
function iterateSplittingRows($currentRows) {
var $currentRow,
numberRows = $currentRows.length;
if (numberRows == 0) {
return;
}
for (var i = 0; i < numberRows; i++) {
$currentRow = $($currentRows[i]);
iterateSplittingFields($currentRow, $currentRow.find('th, td'));
}
}
function iterateSplittingFields($currentRow, $currentFields) {
var $newRow,
newRows = [],
childrenLength,
numberFields = $currentFields.length;
if (numberFields == 0) {
return;
}
for (var i = 0; i < numberFields; i++) {
if (i < splitIndex) {
continue;
}
if (i % splitIndex == 0) {
$newRow = $('<tr></tr>');
}
$newRow.append($currentFields[i]);
if (i == numberFields - 1) {
childrenLength = $newRow.children().length;
// fill the row with empty fields if the length does not fit the splitIndex
for (var j = splitIndex; j > childrenLength; j--) {
$newRow.append($('<td></td>'));
}
}
if (
(i >= splitIndex && i % splitIndex == splitIndex - 1)
||
i == numberFields - 1
){
newRows.push($newRow);
}
}
$currentRow.after(newRows);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="myTable" class="split-columns">
<tbody>
<tr>
<td class="col_01">01</td>
<td class="col_02">02</td>
<td class="col_03">03</td>
<td class="col_04">04</td>
<td class="col_05">05</td>
<td class="col_06">06</td>
<td class="col_07">07</td>
<td class="col_08">08</td>
<td class="col_09">09</td>
</tr>
<tr>
<td class="col_10">10</td>
<td class="col_11">11</td>
<td class="col_12">12</td>
<td class="col_13">13</td>
<td class="col_14">14</td>
<td class="col_15">15</td>
<td class="col_16">16</td>
<td class="col_17">17</td>
</tr>
<tr>
<td class="col_19">19</td>
<td class="col_20">20</td>
<td class="col_21">21</td>
<td class="col_22">22</td>
<td class="col_23">23</td>
<td class="col_24">24</td>
<td class="col_25">25</td>
</tr>
</tbody>
</table>

Can't make div block move on arrow button

I want to make a div block move on arrow buttons. But it doesn't work. I put the buttons in a table.
document.getElementById("upbutton").onclick = function up() {
var block = document.getElementById("block");
var dos = "30px";
var h = "630px";
block.style.position = "relative";
while (block.style.top > h) {
block.style.top = "300px" + dos + "px";
dos += "30px";
}
};
<div id="space">
<div id="block"></div>
<div id="arrows">
<table>
<tr>
<th class="arrow"></th>
<th class="arrow"><button id="upbutton"><img src="up.png"></button></th>
<th class="arrow"></th>
</tr>
<tr>
<td class="arrow"><button id="leftbutton"><img src="left.png"></button></td>
<td class="arrow"><button id="resetbutton"><img src="reset.jpg"></button></td>
<td class="arrow"><button id="rightbutton"><img src="right.png"></button></td>
</tr>
<tr>
<td class="arrow"></td>
<td class="arrow"><button id="downbutton"><img src="down.png"></button></td>
<td class="arrow"></td>
</tr>
</table>
</div>
</div>
There are lot of things wrong with your code
You cannot add string to an integer it will result to string
concatenation. If you add "300px"+ 10 it will result to
300px10 not 310px
I can't understand your logic what you are trying to do but
while (block.style.top > h) { will never pass as style of block will be in string again 0px at start and h is 630.
you have use parseInt(block.style.top) in while loop to compare.
Your div block has no width and height or color you can't see anything.
Here is my implementation of moving a div using arrows.
Store your position to a object pos var pos = {top:0,left:0};
then add events to your buttons
UP:
Update the pos.top+=dos value and apply it to the block.style.top = pos.top+'px';
document.getElementById("upbutton").onclick = function up() {
//Update if top is not equal to zero not allowed to go out of window.
if(pos.top!=0) {pos.top-=dos; block.style.top = pos.top+'px';}
};
Down:
Update the pos.top-=dos value and apply it to the block.style.top = pos.top+'px';
document.getElementById("downbutton").onclick = function down() {
if(pos.top<h) {pos.top+=dos; block.style.top = pos.top+'px';}
};
Left:
Update the pos.left-=dos value and apply it to the block.style.left = pos.left+'px';
document.getElementById("leftbutton").onclick = function left() {
if(pos.left!=0) {pos.left-=dos; block.style.left = pos.left+'px';}
};
Right:
Update the pos.left+=dos value and apply it to the block.style.left = pos.left+'px';
document.getElementById("rightbutton").onclick = function right() {
if(pos.top<h) {pos.left+=dos; block.style.left = pos.left+'px';}
};
SNIPPET
var dos = 30;
var h = 630;
var block = document.getElementById("block");
var pos = {top:0,left:0};
document.getElementById("upbutton").onclick = function up() {
if(pos.top!=0) {pos.top-=dos; block.style.top = pos.top+'px';}
};
document.getElementById("downbutton").onclick = function up() {
if(pos.top<h) {pos.top+=dos; block.style.top = pos.top+'px';}
};
document.getElementById("leftbutton").onclick = function up() {
if(pos.left!=0) {pos.left-=dos; block.style.left = pos.left+'px';}
};
document.getElementById("rightbutton").onclick = function up() {
if(pos.top<h) {pos.left+=dos; block.style.left = pos.left+'px';}
};
#block{
width:100px;
height:100px;
position:relative;
background-color:red;
}
#arrows{
position:relative;
z-index:10;
}
<div id="space">
<div id="block" style="top:0px"></div>
<div id="arrows">
<table>
<tr>
<th class="arrow"></th>
<th class="arrow"><button id="upbutton"><img src="up.png"></button></th>
<th class="arrow"></th>
</tr>
<tr>
<td class="arrow"><button id="leftbutton"><img src="left.png"></button></td>
<td class="arrow"><button id="resetbutton"><img src="reset.jpg"></button></td>
<td class="arrow"><button id="rightbutton"><img src="right.png"></button></td>
</tr>
<tr>
<td class="arrow"></td>
<td class="arrow"><button id="downbutton"><img src="down.png"></button></td>
<td class="arrow"></td>
</tr>
</table>
</div>
</div>
This is how I'd go about this:
var block = document.getElementById("block");
function adjustPos(dX, dY) {
block.style.left = parseInt(block.style.left) + dX + 'px';
block.style.top = parseInt(block.style.top) + dY + 'px';
}
document.getElementById("upbutton").onclick = () => adjustPos(0, -10);
document.getElementById("leftbutton").onclick = () => adjustPos(-10, 0);
document.getElementById("rightbutton").onclick = () => adjustPos(10, 0);
document.getElementById("downbutton").onclick = () => adjustPos(0, 10);
#block {
width: 10px;
height: 20px;
background-color: blue;
position: fixed;
}
<div id="space">
<div id="block" style="top: 100px; left: 100px;"></div>
<div id="arrows">
<table>
<tr>
<th class="arrow"></th>
<th class="arrow">
<button id="upbutton">⇑</button>
</th>
<th class="arrow"></th>
</tr>
<tr>
<td class="arrow">
<button id="leftbutton">⇐</button>
</td>
<td class="arrow">
<button id="resetbutton">ⓧ</button>
</td>
<td class="arrow">
<button id="rightbutton">⇒</button>
</td>
</tr>
<tr>
<td class="arrow"></td>
<td class="arrow">
<button id="downbutton">⇓</button>
</td>
<td class="arrow"></td>
</tr>
</table>
</div>
</div>
The key insight is that you need to parse the string as an int (this removes the trailing 'px'. Then you can add it back.
Also, your block needs to use position: fixed to be positioned wherever on the page.
This could be an start point.
var block = document.getElementById("block");
document.getElementById("upbutton").onclick = function up() {
adjustPos(0, -10);
};
document.getElementById("leftbutton").onclick = function up() {
adjustPos(-10, 0);
};
document.getElementById("rightbutton").onclick = function up() {
adjustPos(10, 0);
};
document.getElementById("downbutton").onclick = function up() {
adjustPos(0, 10);
};
document.getElementById("resetbutton").onclick = function up() {
block.style.left = 50 + 'px';
block.style.top = 50 + 'px';
};
function adjustPos(dX, dY) {
block.style.left = parseInt(block.style.left) + dX + 'px';
block.style.top = parseInt(block.style.top) + dY + 'px';
}
<div id="space" style="width:100px;height:100px">
<div id="block" style="background-color: black;position: relative;width: 10px;height: 10px; top:50px; left:50px"></div>
</div>
<div id="arrows">
<table>
<tr>
<th class="arrow"></th>
<th class="arrow"><button id="upbutton"><img src="up.png"></img></button></th>
<th class="arrow"></th>
</tr>
<tr>
<td class="arrow"><button id="leftbutton"><img src="left.png"></img></button></td>
<td class="arrow"><button id="resetbutton"><img src="reset.jpg"></img></button></td>
<td class="arrow"><button id="rightbutton"><img src="right.png"></img></button></td>
</tr>
<tr>
<td class="arrow"></td>
<td class="arrow"><button id="downbutton"><img src="down.png"></img></button></td>
<td class="arrow"></td>
</tr>
</table>
</div>

Creating a sum of values in a table using javascript

Looking to replace all the "?" in the table below with the expected values.
Should I just add classes to the <th> that has a value in them and add them?
<table id="repair-invoice">
<tr>
<th>Item</th>
<th>Parts</th>
<th>Labor</th>
<th>Total</th>
</tr>
<tr>
<td>Automatic Transmission Replacement</td>
<td>$1,809.99</td>
<td>$830.00</td>
<td>?</td>
</tr>
<tr>
<td>Exhaust system replace</td>
<td>$279.99</td>
<td>$225.00</td>
<td>?</td>
</tr>
<tr>
<td>Replace air filter</td>
<td>$9.99</td>
<td>$0.00</td>
<td>?</td>
</tr>
<tr>
<td colspan="3">Total</td>
<td>?</td>
</tr>
</table>
You can iterate over the row/column combination and sum of the values like
var sum = 0;
$('#repair-invoice tr').slice(1, -1).each(function() {
var $tr = $(this),
total = 0;
$tr.find('td').slice(1, -1).each(function() {
total += +$(this).text().replace(/\$|,/g, '') || 0;
});
$tr.find('td:last-child').text(total);
sum += total;
});
$('#repair-invoice tr:last-child td:last-child').text(sum.toFixed(2)); //will have to format and display the value
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="repair-invoice">
<tr>
<th>Item</th>
<th>Parts</th>
<th>Labor</th>
<th>Total</th>
</tr>
<tr>
<td>Automatic Transmission Replacement</td>
<td>$1,809.99</td>
<td>$830.00</td>
<td>?</td>
</tr>
<tr>
<td>Exhaust system replace</td>
<td>$279.99</td>
<td>$225.00</td>
<td>?</td>
</tr>
<tr>
<td>Replace air filter</td>
<td>$9.99</td>
<td>$0.00</td>
<td>?</td>
</tr>
<tr>
<td colspan="3">Total</td>
<td>?</td>
</tr>
</table>
In case you want to follow D.R.Y :
function removeDollar(num) {
return num.substring(1, num.length);
}
function parseCurrency(num) {
return parseFloat(removeDollar(num).replace(/,/g, ''));
}
function addNumbers(num1, num2) {
return parseFloat(num1) + parseFloat(num2);
}
$(document).ready(function () {
var parts = [];
var labor = [];
for (var i = 0; i < 3; i++) {
parts[i] = $("#repair-invoice > tbody > tr:nth-child("+(2+i)+") > td:nth-child(2)").text();
labor[i] = $("#repair-invoice > tbody > tr:nth-child("+(2+i)+") > td:nth-child(3)").text();
$("#repair-invoice > tbody > tr:nth-child(" + (2 + i) + ") > td:nth-child(4)").html('$'+addNumbers(parseCurrency(parts[i]) , parseCurrency(labor[i])));
}
var Total = 0;
for (var i = 0; i <3; i++) {
var rowTotal = parseCurrency($("#repair-invoice > tbody > tr:nth-child(" + (2 + i) + ") > td:nth-child(4)").text());
Total = addNumbers(Total, rowTotal);
}
$("#repair-invoice > tbody > tr:nth-child(5) > td:nth-child(2)").html('$' + Total.toFixed(2));
});

Calling multiple functions with onchange

All this is a little bit over my experience but I have looked everywhere I could, and researched this stuff for 6 hours so far today and am just running into brick walls.
I have a table, where a user enters two variables and from those two variables 12 different numbers are spit out.
The problem those numbers are spit out as plain text strings into readonly text fields, and I need them to be displayed as (US) currency.
All of the input fields in the table are using onchange to run the first function which does the calculations, but the second and third functions which I found online I can not get to run.
HTML:
<form name="form" >
<table width="550" border="0">
<tr>
<td width="265" height="30"><div align="right">Number of Business Customers</div></td>
</tr>
<TR>
<td width="265" height="30"><div align="right">Number of Business Clients:</div></td>
<td width="142" div align="center"><input style="font-size:12px;text-align:center;" name="sum1" onChange="updatesum();CurrencyFormatted();CommaFormatted90;" /></td>
<td width="129" div align="center"> </td>
</tr>
<TR>
<td height="30"><div align="right">Average Number of Employees:</td>
<TD div align="center"><input style="font-size:12px;text-align:center;" name="sum2" onChange="updatesum();CurrencyFormatted();CommaFormatted();" /></TD>
<TD div align="center"> </TD>
<TR>
<td height="30"><div align="right">Anticipated Employee Tax Reduction:</div></td>
<TD div align="center"><input style="font-size:12px;text-align:center;border:none;" name="sum16" readonly "></TD>
<TD div align="center"><input style="font-size:12px;text-align:center;border:none" name="sum26" readonly><BR /></TD>
</TR>
<TR>
<td height="30"><div align="right">Potential Payroll Tax Reduction (annually):</div></td>
<TD div align="center"><input style="font-size:12px;text-align:center;border:none" name="sum17" readonly ></TD>
<TD div align="center"><input style="font-size:12px;text-align:center;border:none" name="sum27" readonly ></TD>
</TR>
<TR>
<td height="30"><div align="right">Potential Payroll Tax Reduction (monthly):</td>
<TD div align="center"><input type="text" style="font-size:12px;text-align:center;border:none" name="sum18" readonly ></td>
<TD div align="center"><input style="font-size:12px;text-align:center;border:none" name="sum28" readonly ></td>
</TR>
<TR>
<td height="30"><div align="right">Pearl Logic Billing (50% of savings, for 12 months):</td>
<TD div align="center"><input style="font-size:12px;text-align:center;border:none" name="sum19" readonly ></td>
<TD div align="center"><input style="font-size:12px;text-align:center;border:none" name="sum29" readonly ></td>
</TR>
<TR>
<td height="30"><div align="right">Sales Agent Monthly Comp (8%):</td>
<TD div align="center"><input style="font-size:12px;text-align:center;border:none" name="sum14" readonly ></td>
<TD div align="center"><input style="font-size:12px;text-align:center;border:none" name="sum24" readonly ></td>
</TR>
<TR>
<td height="30"><div align="right">Sales Agent Total Comp (8%):</td>
<TD div align="center"><input style="font-size:12px;text-align:center;border:none" name="sum15" readonly ></td>
<TD div align="center"><input style="font-size:12px;text-align:center;border:none" name="sum25" readonly ></td>
</TR>
</table>
</form>
Javascript:
function updatesum() {
document.form.sum14.value = ((((((document.form.sum1.value -0)*(document.form.sum2.value -0)*300))/12)/2)*.08);
document.form.sum24.value = ((((((document.form.sum1.value -0)*(document.form.sum2.value -0)*400))/12)/2)*.08);
document.form.sum15.value = (((((((document.form.sum1.value -0)*(document.form.sum2.value -0)*300))/12)/2)*.08)*12);
document.form.sum25.value = (((((((document.form.sum1.value -0)*(document.form.sum2.value -0)*400))/12)/2)*.08)*12);
document.form.sum16.value = 300;
document.form.sum26.value = 400;
document.form.sum17.value = ((document.form.sum1.value -0)*(document.form.sum2.value -0)*300);
document.form.sum27.value = ((document.form.sum1.value -0)*(document.form.sum2.value -0)*400);
document.form.sum18.value = (((document.form.sum1.value -0)*(document.form.sum2.value -0)*300)/12);
document.form.sum28.value = (((document.form.sum1.value -0)*(document.form.sum2.value -0)*400)/12);
document.form.sum19.value = ((((document.form.sum1.value -0)*(document.form.sum2.value -0)*300)/12)/2);
document.form.sum29.value = ((((document.form.sum1.value -0)*(document.form.sum2.value -0)*400)/12)/2);
}
//--></script>
<script type="text/javascript"><!--
function CurrencyFormatted()
{
var i = parseFloat(amount);
if(isNaN(i)) { i = 0.00; }
var minus = '';
if(i < 0) { minus = '-'; }
i = Math.abs(i);
i = parseInt((i + .005) * 100);
i = i / 100;
s = new String(i);
if(s.indexOf('.') < 0) { s += '.00'; }
if(s.indexOf('.') == (s.length - 2)) { s += '0'; }
s = minus + s;
return s;
}
//--></script>
<script type="text/javascript"><!--
function CommaFormatted()
{
var delimiter = ","; // replace comma if desired
var a = amount.split('.',2)
var d = a[1];
var i = parseInt(a[0]);
if(isNaN(i)) { return ''; }
var minus = '';
if(i < 0) { minus = '-'; }
i = Math.abs(i);
var n = new String(i);
var a = [];
while(n.length > 3)
{
var nn = n.substr(n.length-3);
a.unshift(nn);
n = n.substr(0,n.length-3);
}
if(n.length > 0) { a.unshift(n); }
n = a.join(delimiter);
if(d.length < 1) { amount = n; }
else { amount = n + '.' + d; }
amount = minus + amount;
return amount;
}
//--></script>
Your functions have an undefined amount variable. Presumably they just crash with an error.
First you need to remove those function calls from the onChange listener.
Second, change the functions to take an unformatted value and return a formatted one
function CurrencyFormatted(amount) { //<-- notice the method parameter
var i = parseFloat(amount);
if(isNaN(i)) { i = 0.00; }
var minus = '';
if(i < 0) { minus = '-'; }
i = Math.abs(i);
i = parseInt((i + .005) * 100);
i = i / 100;
s = new String(i);
if(s.indexOf('.') < 0) { s += '.00'; }
if(s.indexOf('.') == (s.length - 2)) { s += '0'; }
s = minus + s;
return s;
}
Now change each of your set calls in your updatesum to first format the value
var sum14 = ((((((document.form.sum1.value -0)*(document.form.sum2.value -0)*300))/12)/2)*.08);
var formattedSum14 = CommaFormatted(CurrencyFormatted(sum14));
document.form.sum14.value = sum14;

Categories