How do I dynamically change the ID to do calculations? - javascript

I have the same form duplicated and triplicated, and depending on clicks on a button, they appear. What I want to do is to be able to make calculations, for example, of the cell Quantity and Unit_Price a multiplication and that the result is reflected in Total Price.
I need the Quantity and Unit_Price IDs to change dynamically so that the result is displayed per cell in their respective Total Price. I already wrote a piece of code that takes the number of each cell, the problem is that I don't know how to put it with the ID so that it is dynamic (the number should change depending on the cell it is in)
This is where I don't know how the code should be:
function multiplicar() {
let quantity = parseInt(document.getElementById('id__form-1-quantity').value);
let unit_price = document.getElementById('id__form-1-unit_price').value;
let total_price = document.getElementById('id__form-1-total_price');
total_price.value = quantity * unit_price;
}
function updateEmptyFormIDs(element, totalForms) {
var thisInput = element
var currentName = element.attr('name')
var newName = currentName.replace(/__prefix__/g, totalForms)
thisInput.attr('name', newName)
thisInput.attr('id', "id__" + newName)
var newFormRow = element.closest(".part-form");
var newRowId = "row_id_" + newName
newFormRow.attr("id", newRowId)
newFormRow.addClass("new-parent-row")
var parentDiv = element.parent();
parentDiv.attr("id", "parent_id_" + newName)
var inputLabel = parentDiv.find("label")
inputLabel.attr("for", "id_" + newName)
return newFormRow
}
function addForm() {
//$('.add-new-form').click(function(e){
var formId = "id_form-TOTAL_FORMS"
var emptyRow = $("#empty-row").clone();
emptyRow.attr("id", null);
var totalForms = parseInt($('#' + formId).val());
var newFormRow;
emptyRow.find("input,select,textarea").each(function() {
newFormRow = updateEmptyFormIDs($(this), totalForms)
})
$(".part-form:last").after(newFormRow)
$('#' + formId).val(totalForms + 1);
}
<table>
<tr>
<td id="parent_id_form-1-quantity">
<input type="number" name="form-1-quantity" class="form-control" id="id__form-1-quantity">
</td>
<td id="parent_id_form-1-unit_price">
<input type="number" name="form-1-unit_price" class="form-control" onchange="multiplicar()" id="id__form-1-unit_price">
</td>
<td id="parent_id_form-1-total_price">
<input type="number" name="form-1-total_price" class="form-control" id="id__form-1-total_price">
</td>
</tr>
</table>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

Related

Make a Button Visible Conditionally Using Javascript

I am putting a javascript button on a form. The script works, but can I make that button visible only if the DESCRIPTION field starts with a number?
The button gets added to the form and code I could gather is below. That button then calls the function that opens the external url.
<push al="center" btnnm="OnBase" col="45" det="DT0" height="1" id="hidden57" keynbr="function=ShowOnBaseInvoiceDocument()" nbr="_f292r0" nm="" par="DT0" row="1" sz="8" tooltip="" tp="Hidden"/>
function ShowOnBaseInvoiceDocument0()
{
var onBaseServer = "someserver";
var appName = "Dev";
var screenID = "90";
var accField = "InvoiceNum";
var venField = "VendorID";
var company = Form.getDataValue("TO-COMPANY");
var RefNums = Form.getDataValue("REFERENCE", 0);
var RefNum = RefNums.trim();
var sVenNumbers = Form.getDataValue("DESCRIPTION", 0);
var sVenNumber = sVenNumbers.substring(0,9);
if (RefNums == "")
{
portalWnd.cmnDlg.messageBox("Not a valid invoice.","ok","info",window,false)
return true;
}
var s = "http://" + encodeURIComponent(onBaseServer)
+ "/OnBaseLinkScanWeb/AccLogin.aspx?DBID=" + encodeURIComponent(appName)
+ "&ScreenID=" + encodeURIComponent(screenID)
+ "&Company=" + encodeURIComponent(company)
+ "&RefNum=" + encodeURIComponent(RefNum)
+ "&" + encodeURIComponent(venField) + "=" + encodeURIComponent(portalWnd.strTrim(sVenNumber));
//portalWnd.cmnDlg.messageBox(s,"ok","info",window,false)
window.open(s, "My Invoice");
console.log(s);
return true;
}
Rows Data
Button
205121GMAC CASHIERS OF
Button
Di Closed Bank 0000
No Button
Close Bank 0073-0000 Al
No Button
You can simply loop over all the rows and then check if the first column starts with a Number and if it does not you can simply hide the button.
document.querySelectorAll("tr").forEach(row => {
const firstCol = row.children[0];
const secondCol = row.children[1];
if (!"0123456789".includes(firstCol.innerText[0])) {
secondCol.style.visibility = "hidden";
}
});
<table>
<tr>
<td>1234567</td>
<td><button>Click</button></td>
</tr>
<tr>
<td>HelloWorld</td>
<td><button>Click</button></td>
</tr>
<tr>
<td>245Bye</td>
<td><button>Click</button></td>
</tr>
<tr>
<td>Upvote</td>
<td><button>Click</button></td>
</tr>
</table>

Make a dynamic table with updated number values

I am trying to make a dynamic table with only html and js. So far I've created it to the point that when a name and number is entered, the table creates a new row with the inputed name and number. However, I'd like to make it so that if the same name but different number is entered, the row values change.
For example, if I enter 'Bob' and 10, the table will create a new row outputting 'Bob' and 10.
But if if enter 'Bob' and 20, the table row values will update to 'Bob' and 30 (10 + 20). I would also like the row to delete itself if the number value reaches 0, for example if I enter 'Bob' and -10, the values would be 'Bob' and 0 and the row would delete itself.
function createRows() {
var inputName = document.getElementById("name").value;
var inputStock = document.getElementById("stock").value;
var tableRef = document.getElementById('myTable').getElementsByTagName('tbody')[0];
var newRow = tableRef.insertRow();
var newCell = newRow.insertCell(0);
var newCell2 = newRow.insertCell(1);
var newText = document.createTextNode(inputName);
var newText2 = document.createTextNode(inputStock);
newCell.appendChild(newText);
newCell2.appendChild(newText2);
}
<label for="name">Name</label>
<input type="text" placeholder="Type name..." id="name">
<label for="stock">Stock</label>
<input type="number" placeholder="Type number..." id="stock">
<button type="button" onclick="createRows();">Get Value</button>
<table id="myTable">
<thead>
<tr>
<th colspan="1">Name</th>
<th colspan="1">Stock</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
When createRows is called you'll have to go through all the rows to see if there is already an entry with that name and if it is, edit/delete it, if there isn't one, create a new entry.
Here is an example:
function createRows() {
var inputName = document.getElementById("name").value;
var inputStock = document.getElementById("stock").value;
var table = document.getElementById('myTable');
var existingRow = Array.from(table.rows).find(row => row.cells[0].textContent === inputName);
if (existingRow) {
var newValue = parseInt(existingRow.cells[1].textContent) + parseInt(inputStock);
if (newValue === 0) {
existingRow.remove();
} else {
existingRow.cells[1].textContent = newValue;
}
} else {
var tableRef = document.getElementById('myTable').getElementsByTagName('tbody')[0];
var newRow = tableRef.insertRow();
var newCell = newRow.insertCell(0);
var newCell2 = newRow.insertCell(1);
var newText = document.createTextNode(inputName);
var newText2 = document.createTextNode(inputStock);
newCell.appendChild(newText);
newCell2.appendChild(newText2);
}
}
<label for="name">Name</label>
<input type="text" placeholder="Type name..." id="name">
<label for="stock">Stock</label>
<input type="number" placeholder="Type number..." id="stock">
<button type="button" onclick="createRows();">Get Value</button>
<table id="myTable">
<thead>
<tr>
<th colspan="1">Name</th>
<th colspan="1">Stock</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
Use a dictionary to store key-value pairs where the key will be a string and the value will be an integer/float.
var dict = { key1 : value1 ,
key2 : value2 ,
....
};
for each new key use:
dict[new_key] = new_value;
if the key is already present, then:
dict.key = dict[key] + new_value;
Then to show all key-value pairs in the table, Iterate over the dictionary.
for(var key in dict) {
console.log(key + " : " + dict[key]);
}

Trigger One Jquery Function With Another Jquery Function

In the below I have a table row where a calculation happens upon input in .quantity and the result of that calculation is placed in .amount2. This works just fine and works as you see below.
<tr class="manifest-row">
<td width = 17.5% class="productCode" onchange="populateProduct(this)">{{form.ProductCode}}</td>
<td width = 32.5% class="description">{{form.DescriptionOfGoods}}</td>
<td width = 12.5% class="quantity" oninput="calculateUnit(this)">{{form.UnitQty}}</td>
<td width = 12.5% class="unitType">{{form.Type}}</td>
<td width = 10.5% class="price" oninput="calculate(this)">{{form.Price}}</td>
<td width = 12.5% class="amount2">{{form.Amount}}</td>
</tr>
JS
function calculateUnit(el) {
// Find the row containing this cell
var row = el.closest("tr");
// Get the quantity from the `input` in the `.quantity` cell in this row
var unitQty = el.querySelector('.quantity input').value;
// Get the price from the `input` in this cell (could use `e.target` instead)
var price = row.querySelector('.price input').value;
// Do the calculation, assign to the `input` in the `.amount` cell in this row
var lineTotal = unitQty * price;
row.querySelector('.amount2 input').value = lineTotal;
}
The issue is that there can be many rows, and I have a separate function which sums all the values in the inputs where class is .amount2 and places that sum in a field #id_InvoiceTotal. But this function below does not trigger properly on input because it is being filled instead by the function above. So how can I make the function above trigger the function below? I've seen .trigger() in my online searches but I don't understand how to apply it here.
<script>
$(document).on("input", ".amount2", function() {
var total = 0;
var i = 0;
$('#form_set .amount2').each(function() {
total += parseInt($('#id_form-'+(i)+'-Amount').val());
i++;
$('#id_InvoiceTotal').val(total);
})
});
</script>
You can do it in the same function with just two additional statements like this :
function calculateUnit(el) {
let total = 0;
var row = el.closest("tr");
var unitQty = el.querySelector('.quantity input').value;
var price = row.querySelector('.price input').value;
var lineTotal = unitQty * price;
row.querySelector('.amount2 input').value = lineTotal;
document.querySelectorAll(".amount2 input").forEach(function(item){
total += item.value / 1;
});
document.querySelector("#id_InvoiceTotal").value = total;
}

How to get a table data element using the id?

I can't seem to grab the inner text of an element. I have tried many approaches to this and still can't fully understand why this is not working.
I have already tried grabbing it by the class, by the id and even by the type of element.
I expected the function to run, but instead it gets caught in the problem areas I marked within the javascript.
function updateCartTotal() {
var cartItemContainer = document.getElementById('cart-table')
var cartRows = cartItemContainer.rows.length
var total = 0
for (var i = 1; i < cartRows; i++) {
var cartRow = cartRows[i]
var priceElement = cartRow.getElementById('item-total')[0] //this is the issue ALSO: i have tried removing "[0]"
var quantityElement = cartRow.getElementsByClassName('form-control')[0] //this is the issue ALSO: i have tried removing "[0]"
var price = parseFloat(priceElement.innerText.replace('$', ''))
var quantity = quantityElement.value
total = total + (price * quantity)
}
total = Math.round(total * 100) / 100
document.getElementsByClassName('cart-total-price')[0].innerText = '$' + total
}
<table class="table table-striped table-border checkout-table" id="cart-table">
<tbody>
<tr>
<td class="hidden-xs">
<img src="images/intro-04.jpg" alt="[Rainbow Six] Complete Edition" />
</td>
<td>
<h5 class="txt25">[Rainbow Six] Complete Edition</h5>
</td>
<td class="txt25" id="item-total">
$45.00
</td>
<td>
<input class="form-control" type="number" name="" value="1" max="50" min="1" />
</td>
<td class="item-total-total txt25">
$45.00
</td>
<td><button class="btn btn-danger" onclick="removeRow(this)" type="button">REMOVE</button></td>
</tr>
</tbody>
</table>
getElementById is only on document, not other nodes
document.getElementById('item-total') will return ONE element and
IDs must be unique.
I changed <td class="txt25" id="item-total"> to <td class="txt25 item-total">
I also suggest you change class="cart-total-price" to id="cart-total-price" since there is likely only one
Try classes and querySelector which is superior to getElementsByClassName:
function updateCartTotal() {
[...document.querySelectorAll('cart-table tbody tr')].forEach((cartRow) => {
var price = cartRow.querySelector('.item-total').innerText.replace(/[$\s]/g,"")
var quantity = cartRow.querySelector('.form-control').value;
total += (+price * +quantity)
});
document.querySelector('.cart-total-price').innerText = '$' + total.toFixed(2)
}
For older browser support you can change first line to
var cartRows = document.querySelectorAll('cart-table tbody tr')
for (var i=0, cartRow;i<cartRows.length; i++) {
cartRow = cartRows[i];

Javascript: could not get the value inside an array using for in loop

I want to display the form with user filled values inside the form to admin. I have displayed all type of values to the respective type of input/select/textarea tags (type: text,email, tel,number... etc) except input type=checkbox.
I am getting problem while fetching the values from array that contain values of group of checkboxes. My code is
var value = data[i][key];
var result = $.isArray(value);
if (result == true) {
var string = key;
var splitstring = string.split("#");
for (var value1 in value) {
console.log(value1);
$("input[type='checkbox'][groupid='" + splitstring[0] + "'][value='" + value1 + "']").attr('checked', true); //cb
}
}
my array(named value) contain values like
[cricket, football, tennis]
would like to make the checkbox property checked that match the condition. but when i console the values fetched one by one it shows me output as
0
1
2
i am not getting what is it???
my html code
<table class="form-group">
<tbody id="tedit">
<tr>
<td>
<div class="checkbox">
<input id="dddddddd#1428735544884535#check_box1" class="form-control" name="14287355448849394#dddddddd[]" groupid="14287355448849394" grid-name="dddddddd" value="Check Box1" type="checkbox" /><label class="jedit"><span class="mouseover">Check Box1</span></label>
</div>
</td>
</tr>
<tr>
<td>
<div class="checkbox">
<input id="dddddddd#14287355448843282#check_box2" class="form-control" groupid="14287355448849394" grid-name="dddddddd" name="14287355448849394#dddddddd[]" value="Check Box2" type="checkbox" /> <label class="jedit"> <span class="mouseover">Check Box2</span></label>
</div>
</td>
</tr>
<tr>
<td>
<div class="checkbox">
<input id="dddddddd#14287355448853367#check_box3" class="form-control" groupid="14287355448849394" grid-name="dddddddd" name="14287355448849394#dddddddd[]" value="Check Box3" type="checkbox" /> <label class="jedit"> <span class="mouseover">Check Box3</span></label>
</div>
</td>
</tr>
</tbody>
</table>
my javascript code is
$.post('<?php echo BASE_URL . 'php/processing/formDashboard/formEntryShowOneByOne.php' ?>', {id: $('#formMetaDataId').val()}, function(data) {
console.log(data);
for (var i = 0, len = data.length; i < len; i++) {
for (var key in data[i]) {
$("input[type='text'][name='" + key + "']").val(data[i][key]); //input tags
$("input[type='text'][name='" + key + "']").prop('disabled', 'true'); //input tags
//........likewise for other type of elements.......///
//.....................for checkbox........................//
var value = data[i][key];
var result = $.isArray(value);
if (result == true) {
var string = key;
var splitstring = string.split("#");
for (var value1 in value) {
console.log(value1);
$("input[type='checkbox'][groupid='" + splitstring[0] + "'][value='" + value1 + "']").attr('checked', true); //cb
}
}
}
}
});
this is simple. The 'cricket' string is retrievable like this:
value[value1]
value1 is just the iterator, in your example 0,1,2
This is your working code:
var value = data[i][key];
var result = $.isArray(value);
if (result == true) {
var string = key;
var splitstring = string.split("#");
for (var value1 in value) {
console.log(value[value1]);
$("input[type='checkbox'][groupid='" + splitstring[0] + "'][value='" + value[value1] + "']").attr('checked', true); //cb
}
}
You should use forEach function
value.forEach(function(val)
{
console.log(val);
//do your thing here
});
That's just how the for ... in loop works for arrays:
var a = ['a','b','c'];
for (var i in a) {
alert(i); // alerts 0,1,2
alert(a[i]); // alerts a,b,c
}
Thus, you just need to index your array with the loop variable:
var value = data[i][key];
var result = $.isArray(value);
if (result == true) {
var string = key;
var splitstring = string.split("#");
for (var valueIndex in value) {
console.log(value[valueIndex]);
$("input[type='checkbox'][groupid='" + splitstring[0] + "'][value='" + value[valueIndex] + "']").attr('checked', true); //cb
}
}

Categories

Resources