I have a piece of somewhat-messy jquery in my app to assign values to the tax, shipping, and total fields of a hidden form before checkout. I have it working mostly, but for some reason if you click "Yes, I live in Colorado" (which will assign a $9ish state tax), the total doesn't get added up properly (the tax isn't added in), even though the tax does get shown.
I added a css-lite snippet that does replicate the problem. Just click "Yes I live in CO", then "See Shipping Options" and "Calculate Total".
$(document).ready(function(){
var $subtotal = $("#hfSubtotal").val();
$(".footer").removeClass("top-shadow-inset");
$(".choiceYesCO").click(function(){
$(".choice-box").removeClass("active");
$(".icon-choice").removeClass("ion-ios-checkmark-outline ion-ios-circle-outline")
$(".choice-no-co").addClass("ion-ios-circle-outline")
$(".choice-yes-co").addClass("ion-ios-checkmark-outline")
$(this).addClass("active");
var $tax = parseFloat($subtotal * .0463).toFixed(2);
$("#hfTax").val($tax);
$(".fieldTax").html("Tax: $" + $tax);
});
$(".choiceNoCO").click(function(){
$(".choice-box").removeClass("active");
$(".icon-choice").removeClass("ion-ios-checkmark-outline ion-ios-circle-outline")
$(".choice-no-co").addClass("ion-ios-checkmark-outline")
$(".choice-yes-co").addClass("ion-ios-circle-outline")
$(this).addClass("active");
var $tax = parseFloat(0.00).toFixed(2);
$("#hfTax").val($tax);
$(".fieldTax").html("Tax: $" + $tax);
});
$(".submitTax").click(function(){
$(".stepTax").addClass("hidden");
$(".stepShipping").removeClass("hidden");
$(".fieldTax").removeClass("hidden");
});
var $tax = $("#hfTax").val();
$(".submitShipping").click(function(){
var $shipping = parseFloat(0.00).toFixed(2);
$("#hfShipping").val($shipping);
$(".fieldShipping").html("Shipping: $" + $shipping);
var $total = parseFloat($subtotal).toFixed(2); + parseFloat($tax).toFixed(2); + parseFloat($shipping).toFixed(2);
$("#hfTotal").val($total);
$(".fieldTotal").html("<strong>Total: $" + $total + "</strong>");
$(".stepShipping").addClass("hidden");
$(".stepTotal").removeClass("hidden");
$(".fieldShipping").removeClass("hidden");
$(".fieldTotal").removeClass("hidden");
});
$(".submitTotal").click(function(){
$(".edit_order").submit();
});
});
.btn {
display: block;
background-color: red;
padding: 5px;
cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="stepTax">
<h3>Do you live in Colorado?</h3>
<div class="choiceYesCO choice-box"><h4><i class="icon choice-yes-co icon-choice ion-ios-circle-outline"></i>Yes, I live in Colorado.</h4></div>
<div class="choiceNoCO choice-box"><h4><i class="icon choice-no-co icon-choice ion-ios-circle-outline"></i>No, I don't live in Colorado.</h4></div>
<div class="btn submitTax">See Shipping Options</div>
</div>
<div class="stepShipping hidden">
<h3>Shipping Options Go Here</h3>
<p>For now all shipping is free!</p>
<div class="btn submitShipping">Calculate Total</div>
</div>
<div class="stepTotal hidden">
<h3>You're ready to checkout!</h3>
<div class="btn submitTotal">Checkout</div>
</div>
<form novalidate="novalidate" class="simple_form edit_order" id="edit_order_1" enctype="multipart/form-data" action="/orders/1" accept-charset="UTF-8" method="post"><input name="utf8" type="hidden" value="✓" /><input type="hidden" name="_method" value="patch" /><input type="hidden" name="authenticity_token" value="6P1CzQgCx7JVXAJgVi2puDOHX/fJApgUBeFI24TAh+ZWXZ5MmQfpMqGsxcnJl4Z6vwYp8A0MbOer34CJDnv4UQ==" />
<h4>Subtotal: $200.00</h4>
<input id="hfSubtotal" type="hidden" value="200.0" name="order[subtotal]" />
<h4 class="hidden fieldTax"></h4>
<input id="hfTax" type="hidden" value="9.26" name="order[tax]" />
<h4 class="hidden fieldShipping">Shipping: $</h4>
<input id="hfShipping" type="hidden" value="0.0" name="order[shipping]" />
<h4 class="hidden fieldTotal"><strong>Total: $</strong></h4>
<input id="hfTotal" type="hidden" value="200.0" name="order[total]" />
</form>
Can anyone see where I'm going wrong here?
the problem that you have here is that you are trying to make the sum with ";" after every value, on the first value, it just brake the line and will always give you 200.00
var $total = parseFloat($subtotal).toFixed(2); + parseFloat($tax).toFixed(2); + parseFloat($shipping).toFixed(2);
just remove those ";" and just let the last one, change it like this
var $total = (parseFloat($subtotal) + parseFloat($tax) + parseFloat($shipping)).toFixed(2);
this will solve the problem.
Related
I am creating a lot of numbers inside of a div. Each time someone clicks a number I want to add it to another div. Let me make myself clear with some examples:
When a user clicks on the add class, the value of .addcop should be added to the value of .totalyHide. That means the value should change to 12.
When I click on the .add2 the value should be added on to 12, so the value of .totalyhide becomes 32.80.
and other terms, if I click the first + and click the second +, they should be added together on Yearly Price.
I hope you understand what I am trying to do.
$('.add').click(function() {
$('.addcop').click();
var dp = $(".addcop").val();
var total = $(".totalyHide").val();
var bigTotal = parseFloat(total) + parseFloat(dp);
$(".totaly").val("$" + bigTotal);
});
$('.add2').click(function() {
$('.procurement').click();
var procurement = $(".procurement").val();
var total = $(".totalyHide").val();
var bigTotal = parseFloat(total) + parseFloat(procurement);
$(".totaly").val("$" + bigTotal);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.2/css/all.css" integrity="sha384-fnmOCqbTlWIlj8LyTjo7mOUStjsKC4pOpQbqyi7RrhN7udi9RwhKkMHpvLbHG9Sr" crossorigin="anonymous">
<div class="box box6">
<div class="titlet">work on it
<hr>
</div>
<div class="explain">to help you better</div>
<div class="money">
<p class="me">$12 Yearly</p><i class="add fas fa-plus-square fa-2x"></i></div>
<input type="text" name="content" class="addcop" style="display: none;" value="12">
</div>
<div class="box box5">
<div class="titlet">Procurement
<hr>
</div>
<div class="explain"></div>
<div class="money">
<p class="me">$20.80 Yearly</p><i class="add2 fas fa-plus-square fa-2x"></i></div>
<input type="text" class="procurement" style="display: none;" value="20.80">
</div>
<div class="box box8">
<div class="total">Your First Deposit will be: <input class="total1" type="button" value="$546"></div>
<input type="text" class="totalHide" style="display: none;" value="546">
<div class="total">Yearly Price: <input onchange="myFunction()" class="totaly" type="button" value="$0"></div>
<input type="text" class="totalyHide" style="display: none;" value="0">
<div class="total">On-off Price: <input class="total" type="button" value="$546"></div>
<input type="text" class="total" style="display: none;" value="546">
</div>
There is a minor issue with the JQuery code that you have written. You can add the following changes to get the desired result.
$('.add').click(function() {
$('.addcop').click();
var dp = $(".addcop").val();
var total = $(".totalyHide").val();
var bigTotal = parseFloat(total) + parseFloat(dp);
$(".totalyHide").val(bigTotal); // Add this line here
$(".totaly").val("$" + bigTotal);
});
$('.add2').click(function() {
$('.procurement').click();
var procurement = $(".procurement").val();
var total = $(".totalyHide").val();
var bigTotal = parseFloat(total) + parseFloat(procurement);
$(".totalyHide").val(bigTotal); // Add this line here
$(".totaly").val("$" + bigTotal);
});
The thing to note here is that whenever you are calculating the total,
you'll have to set that total to $(".totalyHide"), so that you can read the updated value upon next click.
I have created an Add / Remove input fields. I want to get total of 'Amount' using Javascript which should not exceed 100%. Means the total of amount should not exceed 10000.
Say for example first field will have 3000, second will have 6000 and third will have 1000. If we enter larger number it should not accept it.
var i = 0;
jQuery(document).ready(function($) {
//fadeout selected item and remove
$(document).on('click', '#remove-allocation-fields', function(event) {
event.preventDefault();
$(this).parent().fadeOut(300, function() {
$(this).parent().empty();
return false;
});
});
var rows = '<div class="fund-fields"><div class="row"><div class="col-md-5"><div class="form-group"><input type="text" class="form-control" name="allocate_items[]" placeholder=""></div></div><div class="col-md-5"><div class="form-group"><input type="text" class="form-control" name="allocate_amount[]" placeholder=""></div></div><div class="col-md-2"><button type="button" class="btn btn-danger" id="remove-allocation-fields"><span class="glyphicon glyphicon-remove" aria-hidden="true"></span> Remove</button></div></div><div class="clear"></div></div>';
//add input
$('#add-allocation-fields').click(function() {
$(rows).fadeIn("slow").appendTo('#fund-allocation-fields');
i++;
return false;
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="panel panel-default">
<div class="panel-heading">
<center><b>Allocation of Funds</b></center>
</div>
<div class="panel-body">
<div class="row">
<div class="col-md-5">
<label>Allocation Items <b style="color:#FF0000;">*</b></label>
</div>
<div class="col-md-5">
<label>Amount <b style="color:#FF0000;">*</b></label>
</div>
<div class="col-md-2"></div>
</div>
<div class="row">
<div class="col-md-5">
<div class="form-group">
<input type="text" class="form-control" name="allocate_items[]" placeholder="">
</div>
</div>
<div class="col-md-5">
<div class="form-group">
<input type="text" class="form-control" name="allocate_amount[]" placeholder="">
</div>
</div>
<div class="col-md-2">
<button type="button" class="btn btn-success" id="add-allocation-fields">
<span class="glyphicon glyphicon-plus" aria-hidden="true"></span>
Add
</button>
</div>
</div>
<div id="fund-allocation-fields"></div>
<p class="help-block"><i>Total amount must be equal to the goal amount.</i></p>
</div>
</div>
Please Help me. Thanks in advance.
If I understand correctly you could do something as simple as:
var val1 = document.getElementById('inputOne').value;
var val2 = document.getElementById('inputTwo').value;
var val3 = document.getElementById('inputThree').value;
if(val1+val2+val3 < 10000){
// Less then 10000 so do your stuff
} else{
// More then 10000 so let the user know they went too far
}
You can also do it in jQuery. Just change document.getElementById('inputOne').value to $('#inputOne').val()
If the elements are built dynamically you could just do something like this:
var inputs = Array.from(document.querySelectorAll('.inputsToAdd'));
var number = 100;
document.getElementById('btn').addEventListener('click', ()=>{
inputs.map(input=>{
number+=parseInt(input.value);
})
if(number<10000)
console.log(true);
else console.log(false)
})
This is a bit of a connundrum since you have the ability to add infinite input fields, in common practice this is a bad UI experience but to resolve your issue.
You want to sum all the values on click and if the values are too high throw an error. You can accomplish this by assigning each inputField a class and then summing the collection of that class.
I made a small sample using jQuery, a conditional and .each() like so:
$('#sum').click(function(){
var nums = 0
$('.valueField').each(function(){
nums += parseInt(this.value)
});
nums > 10000 ? console.log("value too high", nums) : console.log("compute works", nums)
})
See my small demo below:
$('#sum').click(function() {
var nums = 0
$('.valueField').each(function() {
nums += parseInt(this.value)
});
nums > 10000 ? alert("value too high", nums) : alert("compute works", nums)
})
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<input type='number' class='valueField' />
<input type='number' class='valueField' />
<input type='number' class='valueField' />
<button id='sum'>Click</button>
<script src="https://code.jquery.com/jquery-3.1.0.js"></script>
</body>
</html>
<div class="form-inline">
<div class="form-group col-lg-4">
<label>Select Item:</label>
<div id="field1">
<select class="form-control" name="item_1">
<?php if($item !=0){foreach ($item as $list_item){?>
<option value="<?php echo $list_item['item'];?>">
<?php echo $list_item[ 'item'];?>
</option>
<?php }}else {?>
<option value="">No Items Available</option>
<?php }?>
</select>
</div>
</div>
<div class="form-group col-lg-2">
<label>Quantity:</label>
<div id="field2">
<input type="number" min="1" class="form-control input-md" name="quantity_1" />
</div>
</div>
<div class="form-group col-lg-3">
<label>Cost(per piece):</label>
<div id="field3">
<input type="number" min="1" class="form-control input-md" name="cost_1" />
</div>
</div>
<div class="form-group col-lg-3" style="margin-top:25px">
<div id="field4">
<button id="addmore" onclick="add();" class="btn add-more" type="button">+</button>
</div>
</div>
</div>
I have these three fields('item, quantity and cost') and these three fields are added incrementally on clicking + button but i am having removing these buttons on - click.
I simply need these three input fields to be added at one click and remove these fields on one click as well. also these fields name should be incremented.
<script>
function add() {
i++;
var div1 = document.createElement('div');
div1.innerHTML = '<select class="form-control" name="item_' + i + '"> <option value=""></option></select>';
document.getElementById('field1').appendChild(div1);
var div2 = document.createElement('div');
div2.innerHTML = '<input type="number" min="1" class="form-control input-md" name="quantity_' + i + '" />';
document.getElementById('field2').appendChild(div2);
var div3 = document.createElement('div');
div3.innerHTML = '<input type="number" min="1" class="form-control input-md" name="cost_' + i + '" />';
document.getElementById('field3').appendChild(div3);
var div4 = document.createElement('div');
div4.innerHTML = '<button id="remove" onclick="remove_btn(this)" class="btn remove" type="button">-</button>';
document.getElementById('field4').appendChild(div4);
}
</script>
There are several issues:
Avoid putting blobs of HTML in your javascript, put your HTML in the HTML file.
Avoid IDs, particularly when they will certainly be duplicated. Duplicate IDs are illegal. Only the first one can be found with a lookup.
Avoid concatenating together strings of text to generate your HTML. It is a too easy to make a mistake and put an XSS vulnerability in your code that way.
(function($) {
"use strict";
var itemTemplate = $('.example-template').detach(),
editArea = $('.edit-area'),
itemNumber = 1;
$(document).on('click', '.edit-area .add', function(event) {
var item = itemTemplate.clone();
item.find('[name]').attr('name', function() {
return $(this).attr('name') + '_' + itemNumber;
});
++itemNumber;
item.appendTo(editArea);
});
$(document).on('click', '.edit-area .rem', function(event) {
editArea.children('.example-template').last().remove();
});
$(document).on('click', '.edit-area .del', function(event) {
var target = $(event.target),
row = target.closest('.example-template');
row.remove();
});
}(jQuery));
.hidden { display: none; }
.formfield { float: left; }
.example-template { clear: left; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="hidden">
<div class="example-template">
<div class="formfield"><input placeholder="Name" name="name"></div>
<div class="formfield"><input placeholder="Addr" name="addr"></div>
<div class="formfield"><input placeholder="Post" name="post"></div>
<div class="formfield"><button class="del">-</button></div>
</div>
</div>
<div class="edit-area">
<div class="controls">
<button class="add">+</button>
<button class="rem">-</button>
</div>
</div>
This works by first grabbing the row template out of the hidden div element, and storing it in a variable. Each time it needs to make a new row, it clones the template and updates it. It updates it by adjusting the name element as required, appending "_" and a number. Once it has customized this copy of the template, it appends it to the edit area.
You can remove elements with a reference to the parent using similar syntax with the following:
var childElement = document.getElementById("myChildElement");
document.getElementById("myElement").removeChild(childElement);
Similar to what is described here: http://www.w3schools.com/js/js_htmldom_nodes.asp
Also, consider a toggle on the CSS style property: "display: none;"
I would like to detect when a button is clicked in a div which has multiple buttons which act like checkboxes for mobile optimized application.
This is what I have as HTML:
When it was only normal checkboxes instead of button like checkboxes I was able to achieve what I want with this script:
$(document).on('change', 'input:checkbox.modifier', function () {
var totalChecked = $("#modifiersDiv :checkbox:checked").size();
var maximum = parseInt($('#Maximum').val());
if (totalChecked === maximum) {
$("#modifiersDiv :checkbox:not(:checked)").attr("disabled", true);
} else {
$("#modifiersDiv :checkbox:not(:checked)").attr("disabled", false);
}
});
Now I'm trying something like this just to see if the function will be triggered at all but without success:
$(document).on('click', 'input:button.modifier', function () {
});
Bottom line is that I want to detect with jQuery when 5 buttons are selected then I will need to disable the other buttons in the div until the user will not deselect some button.
Update
Code I'm using for the button:
var startDiv = "<div class='btn-group btn-block' data-toggle='buttons'>";
var checkBox = '';
$.each(data.modifierOptions, function(key, item) {
checkBox += "<label class='btn btn-checkbox btn-block' style='margin-bottom:2px;'><input type='checkbox' data-quantity='1' class='modifier' data-itemid='" + itemid + "' data-name='" + item.Name + "' data-price='" + item.Price + "' name='" + item.Name + "' value='" + item.ID + "'/>" + item.Name + " </label><br />";
});
var endDiv = "</div>";
var totalDiv = startDiv + checkBox + endDiv;
$(totalDiv).appendTo('#modifiersDiv');
I read over your question, and you weren't far off in your attempt. I put together a pen to demonstrate how you can do this: http://codepen.io/aecend/pen/mjklu
The checkbox inputs aren't being replaced with button elements, the labels are only styled so that they appear to be buttons. In the jQuery, you would still need to use the checkbox selector and instead of disabling the checkboxes themselves (there's no point, they're hidden), simply add the "disabled" class to the other labels once five options are selected.
Here's the HTML I used, I only added the btn-default class to make the buttons more visible:
<html>
<head>
<meta charset="utf-8">
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<link rel="stylesheet" href="http://netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css">
<link rel="stylesheet" href="http://netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap-theme.min.css">
<script src="http://netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script>
<title>Hamburger Builder v2.0</title>
</head>
<body class="sitecolor">
<div id="modifiersDiv" class="modal-div" style="width: 250px; margin: 0 auto;">
You can select a maximum of 5 option(s)
<br>
<div class="btn-group btn-block" data-toggle="buttons">
<label class="btn btn-default btn-checkbox btn-block" style="margin-bottom: 2px;">
<input class="modifier" type="checkbox" value="67739" name="Bacon" data-price="1" data-name="Bacon" data-itemid="a4007375-e037-46ce-be39-57ca2d1872e0" data-quantity="1">
Bacon
</label>
<br>
<label class="btn btn-default btn-checkbox btn-block" style="margin-bottom: 2px;">
<input class="modifier" type="checkbox" value="67740" name="Lettuce" data-price="1" data-name="Lettuce" data-itemid="a4007375-e037-46ce-be39-57ca2d1872e1" data-quantity="1">
Lettuce
</label>
<br>
<label class="btn btn-default btn-checkbox btn-block" style="margin-bottom: 2px;">
<input class="modifier" type="checkbox" value="67741" name="Tomato" data-price="1" data-name="Tomato" data-itemid="a4007375-e037-46ce-be39-57ca2d1872e2" data-quantity="1">
Tomato
</label>
<br>
<label class="btn btn-default btn-checkbox btn-block" style="margin-bottom: 2px;">
<input class="modifier" type="checkbox" value="67742" name="Cheese" data-price="1" data-name="Cheese" data-itemid="a4007375-e037-46ce-be39-57ca2d1872e3" data-quantity="1">
Cheese
</label>
<br>
<label class="btn btn-default btn-checkbox btn-block" style="margin-bottom: 2px;">
<input class="modifier" type="checkbox" value="67743" name="Onions" data-price="1" data-name="Onions" data-itemid="a4007375-e037-46ce-be39-57ca2d1872e4" data-quantity="1">
Onions
</label>
<br>
<label class="btn btn-default btn-checkbox btn-block" style="margin-bottom: 2px;">
<input class="modifier" type="checkbox" value="67744" name="Pickles" data-price="1" data-name="Pickles" data-itemid="a4007375-e037-46ce-be39-57ca2d1872e5" data-quantity="1">
Pickles
</label>
<br>
</div>
</div>
</body>
and here is the snippet of JavaScript you'll need, it's almost exactly what you had, except Bootstrap-ready now:
$(document).on('change', 'input:checkbox.modifier', function () {
var totalChecked = $("#modifiersDiv :checkbox:checked").size();
var maximum = 5; //parseInt($('#Maximum').val())
if (totalChecked === maximum) {
$(this).parent().siblings(":not(.active)").addClass("disabled");
} else {
$("#modifiersDiv label.disabled").removeClass("disabled");
}
});
Add a class to the selected buttons, and on each click count the number of buttons that are checked at that moment:
$(".button:not(.selected)").click(function(){
$(this).addClass("selected");
if($(".button.select").length>4){
$(".button").addClass("disabled");
}
}
You might want to add something that will also de-select a button once it's clicked twice...
Try this :))))
var count=0;
$("#modifiersDiv").find(".modifier").click(function(){
if($(this).is(":checked")){
count++;
}else{
count--;
}
if(count>=$('#Maximum').val())
$("#modifiersDiv").find(".modifier").not(':checked').attr("disabled", true);
else
$("#modifiersDiv").find(".modifier").not(':checked').attr("disabled", false);
});
I am using this code to generate dynamically ADD More input fields and then plan on using Save button to save their values in database. The challenge is that on Save button, I want to keep displaying the User Generated Input fields. However they are being refreshed on Save button clicked.
javascript:
<script type="text/javascript">
var rowNum = 0;
function addRow(frm) {
rowNum++;
var row = '<p id="rowNum' + rowNum + '">Item quantity: <input type="text" name="qty[]" size="4" value="' + frm.add_qty.value + '"> Item name: <input type="text" name="name[]" value="' + frm.add_name.value + '"> <input type="button" value="Remove" onclick="removeRow(' + rowNum + ');"></p>';
jQuery('#itemRows').append(row);
frm.add_qty.value = '';
frm.add_name.value = '';
}
function removeRow(rnum) {
jQuery('#rowNum' + rnum).remove();
}
</script>
HTML:
<form method="post">
<div id="itemRows">Item quantity:
<input type="text" name="add_qty" size="4" />Item name:
<input type="text" name="add_name" />
<input onclick="addRow(this.form);" type="button" value="Add row" />
</div>
<p>
<button id="_save">Save by grabbing html</button>
<br>
</p>
</form>
One approach is to define a template to add it dynamically via jQuery
Template
<script type="text/html" id="form_tpl">
<div class = "control-group" >
<label class = "control-label"for = 'emp_name' > Employer Name </label>
<div class="controls">
<input type="text" name="work_emp_name[<%= element.i %>]" class="work_emp_name"
value="" />
</div>
</div>
Button click event
$("form").on("click", ".add_employer", function (e) {
e.preventDefault();
var tplData = {
i: counter
};
$("#word_exp_area").append(tpl(tplData));
counter += 1;
});
The main thing is to call e.preventDefault(); to prevent the page from reload.
You might want to check this working example
http://jsfiddle.net/hatemalimam/EpM7W/
along with what Hatem Alimam wrote,
have your form call an upate.php file, targeting an iframe of 1px.