sum string with number onclick - javascript

I have a global variable :
var a;
I put my onclick function into my html div in concatenation PHP :
$number =' <div onclick="select(this,'."'250000'".');" > ';
$number .= ...etc... //php function
$number .='</div>';
to insert string into div value onclick (button) :
function select (price){
if ($(id).attr('class') == "table2") { //unselect button
$(id).attr('class', 'table1');
var price2=document.getElementById("price").value.split(",");
var removePrice = price;;
var price3 = jQuery.grep(price2, function (value) { return value != removePrice;});
document.getElementById("price").value = price3;
if (n.length == 0) i = 0;
} else {
$(id).attr('class', 'table2'); //select button
if (i == 0) {
document.getElementById("price").value = price;
a = Number(document.getElementById("price").value); //assign the value into a
i = 1;
} else {
$(id).attr('class','table3');
}
}
From there, I have checkbox HTML :
<div id="CourseMenu"><input type="checkbox" value="50000" />&nbsp Ekstra Bed <input type="checkbox" value="50000" />&nbsp Breakfast</div>
After that I have another function to sum 2 div value (checkbox) :
$(function($) {
var sum = 0;
$('#CourseMenu :checkbox').click(function() { sum = 0;
$('#CourseMenu :checkbox:checked').each(function(idx, elm) {
sum += parseInt(elm.value, 10);
});
var b = parseInt(a||0, 10) + parseInt(sum||0, 10);
$('#sum').html(b); //<--resulted NaN when sum with button
document.getElementById("price").value=b; //<-- assign b as div value
});
});
The purpose is to sum the total price (button & checkbox) into div value
<input type="hidden" id="price" name="price" value="" />
it works fine when the function sum only the checkbox, but when I try to show the sum with the button (global variable) it resulted in NaN
I think I already convert the string into number there, is there something wrong with my code?

I think you have a problem in passing the arguments in onclick event:
onclick="select(this,'250000');" => passing this as first argument try changing to onclick="select('250000')";
but your select function is expecting string as the first argument:
function select(price){ //<-- simplified
document.getElementById("price").value=price;
a = Number(document.getElementById("price").value);
}

Here is an actual solution for your X/Y problem.
The code will initialise the field and clicking buttons or checking checkboxes work independently.
function calc() {
var sum = parseInt($("#price").text(), 10);
$('#CourseMenu :checkbox:checked').each(function() {
sum += parseInt(this.value, 10);
});
$('#sum').val(sum);
}
$(function() {
$("#CourseMenu .btn").on("click", function() {
$("#price").text($(this).data("price")); // using the data attribute
calc();
});
$('#CourseMenu input:checkbox').on("click",function() {
calc(); //
});
calc(); // initialise in case the page is reloaded.
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<form id="CourseMenu">
<button type="button" class="btn" data-price="25000">25000</button>
<button type="button" class="btn" data-price="35000">35000</button>
<div id="price">0</div>
<br/>
<label>
<input type="checkbox" value="200" />200</label>
<label>
<input type="checkbox" value="300" />300</label>
<label>
<input type="checkbox" value="400" />400</label>
<br/>
<input type="text" id="sum" value="" />
</form>
PS: If you do nothing else on click of checkboxes, you can write
$('#CourseMenu input:checkbox').on("click",calc);

Related

Increment and update value in the total number after insert new rows dynamically

EDIT: I have updated the code with the answers.
I have a increment function that is working fine. However:
1. I would like to set some limits based on the total number available in one of the span. For example, 10. So the incrementing can't be more than 10. #DONE
Another issue is that I am planning to have multiple rows and before I save I want to make sure if we count the increments in every row it should not be more than 10 as well. If it decrease the total number (span) dynamically would be nice.
I'm adding rows dynamically with the ADD button, how can I add news rows that actually work with the current functions? Mine rows just clone the first one and the increment function is disabled.
document.addEventListener('DOMContentLoaded', async function() {
document.querySelector('#addlocationdest').addEventListener('click', add);
});
function add() {
var x = 1;
var container = document.getElementById('destination');
var detail = document.getElementById('row');
var clone = detail.cloneNode(true);
clone.id = "destination" + x;
x++;
container.appendChild(clone);
}
window.addEventListener("load", () => {
let elTotalQuantity = document.querySelector("#totalqty");
let totalQuantity = parseInt(elTotalQuantity.innerHTML);
function getSumOfRows() {
let sum = 0;
for (let input of document.querySelectorAll("form .row > input.quantity"))
sum += parseInt(input.value);
return sum;
}
for (let row of document.querySelectorAll("form .row")) {
let input = row.querySelector("input");
row.querySelector(".increment").addEventListener("click", () => {
if (getSumOfRows() >= totalQuantity) return;
input.value++;
elTotalQuantity.innerHTML = totalQuantity - getSumOfRows();
});
row.querySelector(".decrement").addEventListener("click", () => {
if (input.value <= 0) return;
input.value--;
elTotalQuantity.innerHTML = totalQuantity - getSumOfRows();
});
}
});
<div id="location" class="hide">
<div class="title">Transfer details</div><br>
<div class="line padded-s">Total Quantity: <span>10</span></div>
<br>
<form>
<label>New Total Quantity at this location: <span id="totalqty">10</span></label>
<br>
<div id="destination">
<div id="row" class="row">
<button type="button" class="decrement">-</button>
<input type="text" class="quantity" value="0" readonly/>
<button type="button" class="increment">+</button>
<a>Location: </a>
<input type="text" class="location" value="0" readonly/>
</div>
</div>
</form>
<label>Total being transfer: <p id="total-sum"></p></label>
<br>
<button type="button" id="addlocationdest">ADD</button>
<button type="button" id="removelocationdest">REMOVE</button>
</div>
Prologue
As long as the total quantity is fixed at the beginning of the script-execution, this works. Otherwise, it would be best to save the actual allowed total quantity as an attribute, and observe it using a MutationObserver. That way you can update your max. value in your code dynamically, when the total quantity-attribute changes. You can define custom attributes by naming them "data-*" where "*" is a custom name.
Solution for your problem
You are using the same ID on multiple elements. What you meant were classes, so change id="increment" to class="increment", and the same for decrement.
Since we don't want to input something with the buttons, but add listener to them, I'd say it is better to actually use <button>. In forms, buttons act as type="submit", which we don't want, so we need to change it to type="button".
Since the rows and the total quantity actually belong together, it is wiser to place them together into one <form>-element. However, you can still group the buttons and inputs as a row together using <div>.
Now regarding the in-/decrementing of the row's values and the total quantity:
Save the allowed total quantity in a variable
Add event-listener to the corresponding buttons
If action is valid, change row's value
Update total quantity number to totalQuantity - getSumOfRows()
To add new rows dynamically, we create and setup such an element, and append it to the form. See the appendNewRow()-function below.
Sidenote
I have added the readonly attribute to the input-fields so that you cannot enter numbers via keyboard.
window.addEventListener("load", () => {
let elTotalQuantity = document.querySelector("#totalqty");
let totalQuantity = parseInt(elTotalQuantity.innerHTML);
function getSumOfRows() {
let sum = 0;
for (let input of document.querySelectorAll("form .row > input.quantity"))
sum += parseInt(input.value);
return sum;
}
function updateTotalQuantity() {
elTotalQuantity.innerHTML = totalQuantity - getSumOfRows();
}
function appendNewRow() {
let row = document.createElement("div");
row.classList.add("row");
let child;
// input.quantity
let input = document.createElement("input");
input.classList.add("quantity");
input.value = "0";
input.setAttribute("readonly", "");
input.setAttribute("type", "text");
row.append(input);
// button.increment
child = document.createElement("button");
child.classList.add("increment");
child.innerHTML = "+";
child.setAttribute("type", "button");
child.addEventListener("click", () => {
if (getSumOfRows() >= totalQuantity) return;
input.value++;
updateTotalQuantity();
});
row.append(child);
// button.increment
child = document.createElement("button");
child.classList.add("decrement");
child.innerHTML = "-";
child.setAttribute("type", "button");
child.addEventListener("click", () => {
if (input.value <= 0) return;
input.value--;
updateTotalQuantity();
});
row.append(child);
// button.remove-row
child = document.createElement("button");
child.classList.add("remove-row");
child.innerHTML = "Remove";
child.setAttribute("type", "button");
child.addEventListener("click", () => {
row.remove();
updateTotalQuantity();
});
row.append(child);
document.querySelector("form .rows").append(row);
}
document.querySelector("form .add-row").addEventListener("click", () => appendNewRow());
appendNewRow();
});
<form>
<label>Total Quantity: <span id="totalqty">10</span></label>
<br>
<div class="rows">
</div>
<button type="button" class="add-row">Add new row</button>
</form>
QuerySelector only selects the first occurrence so you haven't really added a listener to the second "row". You should use querySelectorAll but, instead of unique ids, use classes.
<input class="increment" type="button" value="+" />
Now you can use document.querySelectorAll(".increment") to get all elements in an array.
You can traverse in the DOM by using parentElement. By knowing which button you clicked, you can traverse up to the form element and then select the first child - which is an input. A more dynamic way would be to use querySelector to select the input, in case the HTML change in the future. Anyway, that's how you can know which input to manipulate based on where the buttons are in the DOM.
I added two global variables, totalSum and maxSum. maxSum is fetched from your span element (which I assigned an unique id to). totalSum makes sure that all inputs combined doesn't exceed maxSum.
You had some duplicate code, so I refactored it into a new method: changeValue.
In all, I think the code speaks for itself.
Oh, this code doesn't take into account that the user can change the value inside the input. I will leave that for you to figure out with an "oninput" listener on each text input.
var totalSum = 0; // 3
var maxSum = 0
var totalSumElement = null;
document.addEventListener('DOMContentLoaded', async function() {
totalSumElement = document.getElementById('total-sum');
maxSum = document.getElementById('max-sum').innerText;
var incrementElements = document.querySelectorAll('.increment'); // 1
var decrementElements = document.querySelectorAll('.decrement');
addListener('click', incrementElements, incrementValue);
addListener('click', decrementElements, decrementValue);
});
function addListener(type, elementArr, func) {
for (element of elementArr) {
element.addEventListener(type, func);
}
}
function withinRange(newValue) {
var maxReached = newValue > maxSum; // 3
var zeroReached = newValue < 0;
return !maxReached && !zeroReached;
}
function changeValue(event, change) { // 4
if (withinRange(totalSum + change)) {
let parent = event.currentTarget.parentElement; // 2
let input = parent.children[0];
let value = parseInt(input.value) || 0;
if (withinRange(value + change)) {
input.value = value + change;
totalSum = totalSum + change;
}
}
totalSumElement.textContent = `Total: ${totalSum}`;
}
function incrementValue(event) {
changeValue(event, 1);
}
function decrementValue(event) {
changeValue(event, -1);
}
#totalqty {
padding-bottom: 1rem;
}
<div id="totalqty" class="line padded-s">Total Quantity: <span id="max-sum">10</span></div>
<form>
<input type="text" value="0" />
<input class="increment" type="button" value="+" />
<input class="decrement" type="button" value="-" />
</form>
<form>
<input type="text" value="0" />
<input class="increment" type="button" value="+" />
<input class="decrement" type="button" value="-" />
</form>
<p id="total-sum"></p>

I want to update my text value when I check checkbox

I have a form, it has a checkbox , value(how many item do you want) , item(ex: pen,eraser).
My value set 0,I hope when I checked, value will turn 0 -> 1
This is my code:
<div class="container">
<table>
<thead>
<tr><th>checkbox</th><th>value</th><th>item</th></tr>
</thead>
<tbody id="myTable">
<%
String sql = "select * from send";
pstmt = conn.prepareStatement(sql);
ResultSet rs = pstmt.executeQuery();
pstmt.setQueryTimeout(60);
while(rs.next()){
String name = rs.getString("name");
String c_id = rs.getString("c_id");
out.print("<tr><td>"+"<input type=checkbox name='a'id='a' value="+c_id+" onclick='testfun( this,"+c_id+")'>"+"</td>"
+ "<td><input type=text id='"+c_id+"' value=0 SIZE=5></td><td>"+name+"</td></tr> ");
}
rs.close();
%>
</tbody>
</table>
</form>
</div>
<script type="text/javascript">
unction testfun(element, c_id) {
var x = document.getElementById('c_id');
//if check-box is checked
if (element.checked) {
x.value ="1";
} else {
x.value ="0";
}
}
</script>
how can I do ?I dont know why I can not change value?
thank.
Assign c_id to your input-box and pass same to your function i.e: testfun() with current checkbox clicked using this .Like below :
Jsp code :
out.print("<tr><td>"+"<input type='checkbox' name='a' value="+c_id+" onclick='testfun( this ,'"+c_id+"')'>"+"</td>" + "<td><input type='text' id='"+c_id+"' name='count' value=0 SIZE=5></td><td>"+name+"</td></tr> ");
Js code :
function testfun(element, cName) {
var x = document.getElementById(cName);
//if check-box is checked
if (element.checked) {
//assign required value
x.value = 1;
} else {
x.value = 0;
}
}
Demo code :
function testfun(element, cName) {
var x = document.getElementById(cName);
//if check-box is checked
if (element.checked) {
//assign required value
x.value = 1;
} else {
x.value = 0;
} }
<input type="checkbox" name="abc" value="ddnd" onclick="testfun(this,'a')" />1
<input type="checkbox" name="abc" value="ddnd" onclick="testfun(this,'b')" />2
<input type="text" id="a" />
<input type="text" id="b" />
You have getElementById but are giving it the value from the element's "name" attribute. Add id='a' to your checkbox input and it should work.

How to get the selected radio buttons value?

i am trying to get the value of selected radio buttons so i can submit my form using Ajax i searched here for some help but i couldn't find any useful solution
<input type="radio" id="answer" name="answer<?php echo $function::escape_string($question_row->question_id); ?>"
value="<?php echo $function::escape_string($answer_row>answer_id); ?>"/>
-HTML Output
<input type="radio" id="answer" name="answer16" value="107"/>
<input type="radio" id="answer" name="answer17" value="109"/>
<input type="radio" id="answer" name="answer15" value="104"/>
i found this function here
function findSelection(field) {
var test = document.getElementsByName(field);
var sizes = test.length;
alert("Size is " + sizes);
for (i=0; i < sizes; i++) {
if (test[i].checked==true) {
alert(test[i].value + ' you got a value');
return test[i].value;
}
}
}
var radioinputs = findSelection("answer");
But I do not know what to change so I can make it work with me properly
You can structure like this:
function findSelection(field) {
var test = document.getElementsByClassName(field);
var sizes = test.length;
//alert("Size is " + sizes);
result = [];
// result[16]=107;
// result[17]=109;
// result[15]=104;
for (i=0; i < sizes; i++) {
var index = test[i].dataset.index;
if(test[i].checked == true){
result[index] = test[i].value;
}else{
result[index] = undefined; // for a answer doesn't have a value
}
}
return result;
}
function checkfunction(){
var radioinputs = findSelection("radioanswer");
console.log(radioinputs);
console.log(radioinputs[15]);
};
<form id="form1">
<input type="radio" class="radioanswer" name="answer16" data-index="16" value="107"/>
<input type="radio" class="radioanswer" name="answer17" data-index="17" value="109"/>
<input type="radio" class="radioanswer" name="answer15" data-index="15" value="104"/>
<button type="button" onclick="checkfunction();"> Check </button>
</form>
A class can has multiple instances, but id has only one! And you can see document about data attributes here: https://developer.mozilla.org/en-US/docs/Learn/HTML/Howto/Use_data_attributes
From the looks of it you have a dynamic name field, i.e. name="answer2", name="answer3", etc. Because of that your query document.getElementByName(field) will not find a field matching "answer".
To remedy this either get rid of the dynamic name or if you really need it then I would say add a class to all those radio buttons and use document.getElemenetsByClassName.

applying onkeyup function simultaneously on multiple textboxes

Suppose I have a column of 1+7 text box. Name of the first box is mm1 and the other boxes are respectively dd1, dd2, ...., dd7. I want to write a javascript function so that all the values in the textboxes dd1, dd2,...,dd7 are multiplied by N if I put N in the first textbox namely mm1. I can write the javascript function , but how to make its effect in all boxes simultaneously? I have tried the following code. But it can effect only one box depending on the value of $i. If we can create a loop for $i taking values 1 to 7, then perhaps the problem will be solved. Any clue please.
<?php $i=3?>
<input type="text" size="1" id="mm1" name="mm1"
maxlength="2" onfocus="this.select()"
onkeyup="gft('dd<?php echo $i?>', 'mm1')"
>
Try this, use class to logically group elements...
$('.mult').each(function(i,v){
var tt = parseFloat($(this).val());
$(this).attr('data-val',$(this).val());
});
$('.myVal').on('keyup',function(e){
var t = $(this).val();
if(!t) t = 0;
$('.mult').each(function(i,v){
if(t>0){
var tt = parseFloat($(this).attr('data-val')) * t;
$(this).val(tt);
}
});
});
Find working fiddle here
function gft(x){
n = 5;
c = x * n;
textInputs[0].value = c;
textInputs[1].value = c;
textInputs[2].value = c;
}
var textInputs = document.querySelectorAll('input[type=text]');
//this eventlistener is made to listen for key movement on all text fields that are of type text
for(i=0;i<textInputs.length;i++){
textInputs[i].addEventListener('keyup',function(){
//gft will execute an equation whenever one of these fields change
//also, it will change all the values inside the textfield simultaneously
gft(this.value);
},false);
}
I made a JSFiddle using only JavaScript (no jQuery):
HTML
<input type="number" onkeyup="multiply(this)"/>
<input type="number" value="1" class="multiply-this"/>
<input type="number" value="2" class="multiply-this"/>
<input type="number" value="3" class="multiply-this"/>
<input type="number" value="4" class="multiply-this"/>
<input type="number" value="5" class="multiply-this"/>
<input type="number" value="6" class="multiply-this"/>
<input type="number" value="7" class="multiply-this"/>
JavaScript
function multiply(first){
var value = +first.value;
var textboxes = document.getElementsByClassName("multiply-this");
for(var i = 0; i < textboxes.length; i++){
var textbox = textboxes[i];
if(textbox.attributes.initialValue){
textbox.value = textbox.attributes.initialValue.value;
} else {
textbox.setAttribute("initialValue", textbox.value);
}
textbox.value = +textbox.value * value;
}
}
window.onload = function(){
var textboxes = document.getElementsByClassName("multiply-this");
for(var i = 0; i < textboxes.length; i++){
var textbox = textboxes[i];
textbox.onkeyup = function(){
this.setAttribute("initialValue", this.value);
}
}
}
I added functionality to remember what value the textboxes had at first. But you can still change it if you specifically change one of the 7 textboxes that gets multiplied.
EDIT
You can also add this if you want it to multiply after changing one of the values:
textbox.onblur = function(){
multiply(document.getElementById("multiplyer"));
}
JSFiddle

Run function on input change and checkbox change

I have a Bootstrap modal with multiple forms in it. All the forms have an input field and checkbox. I try to run a function update_amounts_modal every time a change event takes place. This working when I change the input value but doesn't work when I check/uncheck the checkbox.
UPDATE I'VE CREATED A FIDDLE HERE
The function:
function update_amounts_modal(){
var sum = 0.0;
$('form').each(function() {
var qty = $(this).find('.qty input').val();
var price = $(this).find('.price input').val();
qty= parseInt(qty) || 0;
price= parseFloat(price) || 0;
var amount = (qty*price)
sum+=amount;
});
$('.total-modal').text('€'+sum.toFixed(2));
}
The change function:
update_amounts_modal();
$('form .qty').change(function(){
update_amounts_modal();
$('.total-modal').change();
});
HTML:
<form method="post" data-target="#modal" data-async="" action="action_url">
<div class="qty cell">
<input type="text" class="qty" value="1" name="quantity">
</div>
<div class="price cell">
<span class="euro">€</span><input type="text" disabled="" class="price" value="0.60">
</div>
<div class="checkbox cell">
<input type="checkbox" checked="" value="12933006" name="product[]" class="idRow">
</div>
</form>
//And more forms exactly like this but with different input values!
<div class="total-modal">€0.00</div>
What actually needs to happen is that by checking/unchecking the value needs to be recalculated with the function. So if you have set qty to 10 and you uncheck the checkbox then this amount (10x eg. €0.25) must be deducted from the total.
I thought something like this should work but that isn't:
$(".idRow").change(function(){
if($(this).attr("checked")){
update_amounts_modal();
}
else{
update_amounts_modal();
}
I don't get an error there's just nothing happening. Is there a better way to accomplish this?
I'm not sure figure out your question correctly or not but i think you are looking for something like this:
function update_amounts_modal() {
var sum = 0.0;
$('form').each(function () {
var qty = $(this).find('.qty').val();
var price = $(this).find('.price').val();
var isChecked = $(this).find('.idRow').prop("checked");
if (isChecked){
qty = parseInt(qty, 10) || 0;
price = parseFloat(price) || 0;
var amount = (qty * price);
sum += amount;
}
});
$('.total-modal').text('€' + sum.toFixed(2));
}
$().ready(function () {
update_amounts_modal();
$('form .qty, form .idRow').change(function () {
update_amounts_modal();
});
});
Check JSFiddle Demo
Update:
If in some forms you don't have a CheckBox (in other words some prices aren't optional) so you have to check that CheckBox exist or not and if exist, so check that is checked or not.
in order to do that, modify the update function like this:
function update_amounts_modal() {
var sum = 0.0;
$('form').each(function () {
var qty = $(this).find('.qty').val();
var price = $(this).find('.price').val();
var checkbox = $(this).find('.idRow');
if (checkbox.prop("checked") || checkbox.length == 0){
qty = parseInt(qty, 10) || 0;
price = parseFloat(price) || 0;
var amount = (qty * price);
sum += amount;
}
});
$('.total-modal').text('€' + sum.toFixed(2));
}
in this line: if (checkbox.prop("checked") || checkbox.length == 0){ we say that sum the value if checkbox is checked (checkbox.prop("checked")) or there is no CheckBox (checkbox.length == 0).
Check JSFiddle Demo
Try this : Instead of attr use prop
$(".idRow").change(function(){
if($(this).prop("checked")){
update_amounts_modal();
}
else{
update_amounts_modal();
}
});
u can do
<div class="checkbox cell">
<input type="checkbox"/>
</div>
jQuery("div.checkbox > input:checkbox").on('click',function(){
alert('asdasd');
});
http://jsfiddle.net/1r7rk21w/
If you expect the values to update based on the checked property, then your sum function needs to actually use that check box right?
JS:
$('form').each(function () {
if ($(this).find(".idRow").prop("checked") === true){
//
// The normal computations you had before...
//
}
});

Categories

Resources