Getting NaN values when multiplying a number by document.getElementById('myid') - javascript

I'm learning JavaScript. I want to make subtotal for each product and I don't know why I keep getting NaN? Here is my code. I couldn't find the problem for this. Maybe there's something wrong with the value or something?
var value;
var price = document.getElementById("price");
function priceTotal() {
var total = value * price;
document.getElementById("subtotal").innerText = total;
}
$('.increment-btn').click(function(e) {
e.preventDefault();
var incre_value = $(this).parents('.quantity').find('#qty-input').val();
var value = parseInt(incre_value, 10);
value = isNaN(value) ? 0 : value;
if (value < 100) {
value++;
$(this).parents('.quantity').find('#qty-input').val(value);
}
priceTotal();
});
$('.decrement-btn').click(function(e) {
e.preventDefault();
var decre_value = $(this).parents('.quantity').find('#qty-input').val();
var value = parseInt(decre_value, 10);
value = isNaN(value) ? 0 : value;
if (value > 1) {
value--;
$(this).parents('.quantity').find('#qty-input').val(value);
}
priceTotal();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<td class="text-center" id="price">Rp. {{ number_format($cartlist->product->productprice)}}</td>
<td class="cart-product-quantity text-center" width="132px">
<div class="input-group quantity">
<div class="input-group-prepend decrement-btn changeQuantity" style="cursor: pointer">
<span class="input-group-text">-</span>
</div>
<input type="text" class="qty-input form-control text-center" maxlength="2" value="1" id="qty-input">
<div class="input-group-append increment-btn changeQuantity" style="cursor: pointer">
<span class="input-group-text">+</span>
</div>
</div>
</td>
<!-- <input style="text-align:center; width: 70px;" type="text" name="subtotal" id="subtotal" value="{{$cartlist->product->productprice}}" > -->
<td class="text-center">
<span id="subtotal">Rp. {{ number_format($cartlist->product->productprice)}}</span>
</td>

Two problems:
1 -- You need to pass value from the onClick() handler to the priceTotal() function. I recommend you take a quick glance at MDN Web Docs: Encapsulation, specifically:
Encapsulation is the packing of data and functions into one component (for example, a class) and then controlling access to that component to make a "blackbox" out of the object.
2 -- You are setting price to var price = document.getElementById("price"); and then using it in multiplication. You cannot do that, you must use a number in multiplication, not an HTML element. In addition, the price element is not even an input, so you can't use its val() function either. I set this statically to just 1 to prove my point.
var value;
var price = 1; // you can't use an element as an integer
function priceTotal(value) {
var total = value * price;
document.getElementById("subtotal").innerText = total;
}
$('.increment-btn').click(function(e) {
e.preventDefault();
var incre_value = $(this).parents('.quantity').find('#qty-input').val();
var value = parseInt(incre_value, 10);
value = isNaN(value) ? 0 : value;
if (value < 100) {
value++;
$(this).parents('.quantity').find('#qty-input').val(value);
}
priceTotal(value);
});
$('.decrement-btn').click(function(e) {
e.preventDefault();
var decre_value = $(this).parents('.quantity').find('#qty-input').val();
var value = parseInt(decre_value, 10);
value = isNaN(value) ? 0 : value;
if (value > 1) {
value--;
$(this).parents('.quantity').find('#qty-input').val(value);
}
priceTotal(value);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<td class="text-center" id="price">Rp. {{ number_format($cartlist->product->productprice)}}</td>
<td class="cart-product-quantity text-center" width="132px">
<div class="input-group quantity">
<div class="input-group-prepend decrement-btn changeQuantity" style="cursor: pointer">
<span class="input-group-text">-</span>
</div>
<input type="text" class="qty-input form-control text-center" maxlength="2" value="1" id="qty-input">
<div class="input-group-append increment-btn changeQuantity" style="cursor: pointer">
<span class="input-group-text">+</span>
</div>
</div>
</td>
<!-- <input style="text-align:center; width: 70px;" type="text" name="subtotal" id="subtotal" value="{{$cartlist->product->productprice}}" > -->
<td class="text-center">
<span id="subtotal">Rp. {{ number_format($cartlist->product->productprice)}}</span>
</td>

Related

How can I increment and decrement value with unique id?

I have this loop, The id is unique. When I try to increment it is working for only one input field. How can I increment and decrement using unique id?
#forelse($allproduct as $key=>$data)
<tr>
<td data-label="#lang('Date')">
<div class="quantity col-md-8" style="display:flex; ">
<input type="text" value="" class="form-control req amnt display-inline" id="qtyid[{{$data->product_id}}]" min="0">
<div class="quantity-nav">
<div class="quantity-button quantity-up qty" onclick="incrementValue()">+</div>
<div class="quantity-button quantity-down qty" onclick="decrementValue()">-</div>
</div>
</div>
</td>
</tr>
#endforelse
Javascript
function incrementValue()
{
var value = parseInt(document.getElementById("qtyid").value, 10);
value = isNaN(value) ? 0 : value;
value++;
document.getElementById('qtyid').value = value;
}
function decrementValue()
{
var value = parseInt(document.getElementById('qtyid').value, 10);
value = isNaN(value) ? 0 : value;
value--;
if(value == -1) {
value = 0;
}
document.getElementById('qtyid').value = value;
}
I suggest you use an approach that doesn't need IDs.
function incrementValue(e)
{
// use the quantity field's DOM position relative to the button that was clicked
const qty = e.target.parentNode.parentNode.querySelector("input.req.amnt");
var value = parseInt(qty.value, 10);
value = isNaN(value) ? 0 : value;
value++;
qty.value = value;
}
function decrementValue(e)
{
const qty = e.target.parentNode.parentNode.querySelector("input.req.amnt");
var value = parseInt(qty.value, 10);
value = isNaN(value) ? 0 : value;
value--;
if(value == -1) {
value = 0;
}
qty.value = value;
}
#forelse($allproduct as $key=>$data)
<tr>
<td data-label="#lang('Date')">
<div class="quantity col-md-8" style="display:flex; ">
<input type="text" value="" class="form-control req amnt display-inline" min="0">
<div class="quantity-nav">
<div class="quantity-button quantity-up qty" onclick="incrementValue(event)">+</div>
<div class="quantity-button quantity-down qty" onclick="decrementValue(event)">-</div>
</div>
</div>
</td>
</tr>
#endforelse

Assign value of number input to value of radio Button

I have a radio button that when selected reveals a touchspin, anytime the touchspin increase or decrease button is being clicked i want the value of the radio button to be set to the value of the touch spin’s number input. I tried putting ('input.custom-vote:radio').val(value) at the bottom of the increaseValue and decreaseValue function but it still doesn't work. I will greatly appreciate any help to solve this problem.
<!--Touch-spin increase Value-->
function increaseValue() {
var value = parseInt(document.getElementById('number').value, 10);
value = isNaN(value) ? 0 : value;
value++;
document.getElementById('number').value = value;
}
<!--Touch-spin decrease Value-->
function decreaseValue() {
var value = parseInt(document.getElementById('number').value, 10);
value = isNaN(value) ? 0 : value;
value < 1 ? value = 1 : '';
value--;
document.getElementById('number').value = value;
}
<div class="custom-control custom-radio mb-3">
<input name="votes" value="0" class="form-check-input custom-control-input custom-vote" id="custom" type="radio">
<label class="custom-control-label form-check-label" for="custom">Custom Vote</label>
</div>
<div class="input-group custom-vote">
<button id="decrease" onclick="decreaseValue()" value="Decrease Value" type="button"></button>
<input type="number" maxlength="6" size="5" class="touchspin form-control custom-count" id="number" value="150">
<button id="increase" onclick="increaseValue()" value="Increase Value" type="button"></button>
</div>
This might work:
document.getElementById("custom").value = document.getElementById('number').value

Javascript - Adjust price when changing quantity

I have a form to add product to basket where the user need to select quantity. I'm trying to adjust the price when quantity is modified. Here's my code:
<script>
function increaseValue() {
var value = parseInt(document.getElementById('quantity').value, 10);
value = isNaN(value) ? 0 : value;
value++;
document.getElementById('quantity').value = value;
}
function decreaseValue() {
var value = parseInt(document.getElementById('quantity').value, 10);
value = isNaN(value) ? 0 : value;
value < 1 ? value = 1 : '';
value--;
document.getElementById('quantity').value = value;
}
</script>
<div class="quantity-container">
<span>1</span>
<div class="value-button" id="decrease" onclick="decreaseValue()" value="Decrease Value">-</div>
<input type="number" id="quantity" name="quantity" value="1" />
<div class="value-button" id="increase" onclick="increaseValue()" value="Increase Value">+</div>
</div>
I need to adjust the price for the following scenarios:
If quantity is increased using the 'increase' button
If quantity is decreased (but prevent zero quantity with $0.00 price)
If quantity is updated using the quantity text field
The problem is that the price is displayed using html between the numbers so i'm confused how to update the price. I assume I will have to use RegEx? I can't just hardcode the base price ($15.49 in this example) because the price is never the same (the prices come from SQL DB)
<div id="product-price">
$15<sup>.49</sup>
</div>
Use ES6's Template literals (``). Try the following:
For more: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals
function increaseValue() {
var value = parseInt(document.getElementById('quantity').value, 10);
value = isNaN(value) ? 0 : value;
value++;
document.getElementById('quantity').value = value;
price = '$'+`<span>${p * value}</span>`;
document.getElementById('product-price').innerHTML=price;
}
function decreaseValue() {
var value = parseInt(document.getElementById('quantity').value, 10);
value = isNaN(value) ? 0 : value;
value < 1 ? value = 1 : '';
value--;
document.getElementById('quantity').value = value;
price = '$'+`<span>${p * value}</span>`;
document.getElementById('product-price').innerHTML=price;
}
var p='15.49';
var price = '$'+`<span>${p}</span>`;
document.getElementById('product-price').innerHTML=price;
<div id="myDiv">
<div class="quantity-container">
<span>1</span>
<div class="value-button" id="decrease" onclick="decreaseValue()" value="Decrease Value">-</div>
<input type="number" id="quantity" name="quantity" value="1" />
<div class="value-button" id="increase" onclick="increaseValue()" value="Increase Value">+</div>
</div>
<div id="product-price">
</div>

If total is invalid, set the field text and border to red

I'm trying to make a validation condition for the field Total. Total project costs is invalid: The maximum sum for Total project costs is 9,999,999,999,999.99. Once it is more than this value, the border of the text and the text would be red. Would appreciate any help.
<tr style="height:35px">
<td> </td>
<td align="center"><strong>TOTAL</strong></td>
<td align="center">
<input class="numeral form-control text-font-md" disabled="disabled" style="width:auto; height:30px" value="" type="text" data-bind="attr: {'title': totalRequestfromNEHToolTip}, value: tRequestfromNEH">
</td>
<td align="center">
<input class="numeral form-control text-font-md" disabled="disabled" style="width:auto; height:30px" disabled="" type="text" data-bind="attr: {'title': totalRequestfromNEHToolTip}, value: tnonFedThirdPartyGifts">
</td>
</td>
<td align="center">
<input class="numeral form-control text-font-md" disabled="disabled" style="width:auto; height:30px" value="" type="text" data-bind=" attr: {'title': totalCostShareToolTip}, value: tcostShare">
</td>
<!-- <td align="center"><input class="numeral form-control text-font-md" disabled="disabled" style="width:auto; height:30px" value="" type="text"></td> -->
var TOTAL = ko.computed(function() {
var total = 0;
var hasUserInput = false;
if (tRequestfromNEH() != '' && tRequestfromNEH() != undefined) {
hasUserInput = true;
total = total + Number(String(tRequestfromNEH()).replace(/\,/g, ''));
}
if (tnonFedThirdPartyGifts() != '' && tnonFedThirdPartyGifts() != undefined) {
hasUserInput = true;
total = total + Number(String(tnonFedThirdPartyGifts()).replace(/\,/g, ''));
}
if (tcostShare() != '' && tcostShare() != undefined) {
hasUserInput = true;
total = total + Number(String(tcostShare()).replace(/\,/g, ''));
}
if (total == 0) {
if (!hasUserInput)
return '';
else
return formatNumber('0');
} else {
if (loading == false) {
sendCommand('SAVE');
}
return formatNumber(total);
}
});
use the knockout css binding. here is one where the text and background go red when the total exceeds 10. https://jsfiddle.net/0o89pmju/57/
html
<form>
<div class="form-group">
<label for="number1">number 1</label>
<input type="number" class="form-control" id="number1" data-bind="textInput: number1">
</div>
<div class="form-group">
<label for="number1">number 2</label>
<input type="number" class="form-control" id="number2" data-bind="textInput: number2">
</div>
<div class="form-group" data-bind="css: {'has-error': total() > 10 }">
<label class="control-label">Total:</label>
<p class="form-control-static" data-bind="text: total, css: {'bg-danger': total() > 10 }"></p>
</div>
</form>
js
function viewModel() {
var self = this;
this.number1 = ko.observable('');
this.number2 = ko.observable('');
this.total = ko.pureComputed(function(){
return parseInt(self.number1()||0) + parseInt(self.number2()||0)
},this);
}
var vm = new viewModel();
(function($) {
ko.applyBindings(vm); //bind the knockout model
})(jQuery);

Looping through and storing each table row td element value as array of objects

I have a table that dynamically calculates and create new row. Here is a snippet of the:
<table>
<tr class="purchase_schedule_table">
<td><input type="text" name="purchase_place" class="purchase_place_info" style="width: 90%;" ></td>
<td><input type="text" name="main_products_purch" style="width: 90%;" class="main_products_purch_info" ></td>
<td><input type="number" name="frequency" style="width: 90%;" class="frequency" ></td>
<td><input type="number" name="low" style="width: 90%;" class="product_low" ></td>
<td><input type="number" name="high" style="width: 90%;" class="product_high" ></td>
<td><input type="number" name="average" style="width: 90%;" class="product_average" disabled ></td>
<td>
<div class = "input-group" id="addrow">
<input type="number" name="product_total" style="width: 90%;" class="product_total" disabled>
<span class = "input-group-addon" style="width:1%; background-color:#786bae;border-color:#786bae;">
<a href="#">
<span style="color:#FFFFFF;font-size:9px;line-height: 1.5;border-radius:0 !important;" class="glyphicon glyphicon-plus addrow" aria-hidden="true"></span>
</a>
</span>
</div>
</td>
</tr>
</table>
Here is a snippet of jquery code to calculate the values:
//calculate purchase schedule monthly total
function calculatePurchaseScheduleMonthlyTotal(){
var total_sum = 0;
$('.product_total').each(function () {
var value = $(this).val();
total_sum = parseInt(total_sum) + parseInt(value);
});
$('.total_sum').val(total_sum);
};
//calculate purchase schedule
function calculatePurchaseSchedule(ObjRow) {
var low = 0;
var high = 0;
var average = 0;
var frequency = 0;
var total = 0;
var total_sum = 0;
frequency = ($(ObjRow).find('.frequency').val() == "") ? 0 : $(ObjRow).find('.frequency').val();
high = ($(ObjRow).find('.product_high').val() == "") ? 0 : $(ObjRow).find('.product_high').val();
low = ($(ObjRow).find('.product_low').val() == "") ? 0 : $(ObjRow).find('.product_low').val();
average = (parseInt(high) + parseInt(low)) / 2;
total = average * frequency;
$(ObjRow).find('.product_total').val(total);
$(ObjRow).find('.product_average').val(average);
calculatePurchaseScheduleMonthlyTotal();
};
Here is also a snippet of the code that is use to trigger the calculation:
$(document).on('focusout','input[type=number]',function () {
calculatePurchaseSchedule($(this).closest('tr'));
saveData();
});
Here is the code for adding a table row dynamically:
$('#addrow').click(function (e) {
e.preventDefault();
var purchase_schedule_row = '<tr class="purchase_schedule_table"><td> <input type="text" name="purchase_place" class="purchase_place" style="width: 90%;"></td><td><input type="text" name="main_products_purch" style="width: 90%;" class="main_products_purch"></td><td><input type="number" name="frequency" style="width: 90%;" class="frequency"></td><td><input type="number" name="low" style="width: 90%;" class="product_low"></td> <td><input type="number" name="high" style="width: 90%;" class="product_high"></td> <td><input type="number" name="average" style="width: 90%;" class="product_average" disabled></td><td> <div class = "input-group" id="addrow"> <input type="number" name="total" style="width: 90%;" class="product_total" disabled><span class = "input-group-addon" style="width:1%; background-color:#ec6d65;border-color:#ec6d65;"> <span style="color:#FFFFFF;font-size:9px;line-height: 1.5;border-radius:0 !important;" class="glyphicon glyphicon-minus deleterow" aria-hidden="true"></span></span></div></td></tr>';
$('#purchaseScheduleTable').append(purchase_schedule_row);
});
What I want to do is to store each table row td element value as a array of objects. I have tried doing so in the following code:
var purchase_place;
var main_products_purch;
var frequency;
var product_low;
var product_high;
var product_average;
var product_total;
var product_total_sum;
var purchase_schedule_table = [];
var purchase_schedule_data = {};
var count = 1;
$('.purchase_schedule_table').each(function(){
$(this).find('.product_total').each(function () {
product_total = $(this).find('.product_total').val();
console.log(product_total);
purchase_schedule_data.product_total = product_total;
});
purchase_schedule_table.push(purchase_schedule_data);
});
console.log(purchase_schedule_table);
For example, the end result should be like this:
[
{purchase_place: 'purchase_place', main_products_purch : 'main_products_purch', frequency:'frequency', product_average: 'product_averager'}
{purchase_place: 'purchase_place', main_products_purch : 'main_products_purch', frequency:'frequency', product_average: 'product_averager'}
]
What am I doing wrong? Thanks in advance.
Iterate through each tr with class purchase_schedule_table and then each td in it, make an object and push it in a an array like following.
var arr = [];
$('.purchase_schedule_table').each(function () {
var obj = {};
$(this).find('td').each(function () {
var input = $(this).find('input')[0];
obj[input.name] = input.value;
});
arr.push(obj);
})
console.log(arr)

Categories