I'm fairly new to JavaScript and am trying to write some code that lists three price options in a form, as checkboxes. If both of the first two are selected, I want the total price to drop by a certain amount.
My code is based on the code in this question:
Javascript checkboxes incorrect calculating
They reset the base value by a date variable. I assume that if I have a function that sets the base to a negative value if those two boxes are checked, that would achieve what I want. I'd also like the output to have an additional tag of 'save (x) per month' when this happens.
However I'm not sure how to go about relating the variable to the checkboxes.. do I need to use jquery as per how to change the value of a variable based on a select option:selected?
Jquery is never necessary, but it is always a plus. since you are learning javascript, i would recommend not using the framework yet.
First you need a form (it would be better if you showed us what your form looks like):
<form>
<input type="checkbox" id="first" /><label for="first">First Box</label> <br>
<input type="checkbox" id="second" /><label for="second">First Box</label> <br>
<input type="text" id="output" value="5.00"/>
</form>
Now the javascript
<script type="text/javascript">
var first = document.getElementById("first");
var second = document.getElementById("second");
first.onchange = function () {
if (this.checked == true) {
document.getElementById("output").value = "new Value";
}else {
document.getElementById("output").value = "other Value";
}
}
... the same can be done for 'second' ....
</script>
I'm assuming you are modifying your recalculate() function from your earlier question. In that function, after you get your sum, add this to apply the discount:
if ($("#chkBox1,#chkBox2").filter(":checked").length == 2)
{
sum -= discount;
}
To write the message to your output, modify your $("#output").html(sum) code to this:
$("#output").html(sum + " Save $" + discount + " per month");
if (document.getElementById('checkBox1').checked && document.getElementById('checkBox2').checked) {
// Change the price
}
There are many ways to address this issue. As a reminder before I get into it, never do something like 'calculating price' on the client-side. That is, you can calculate the price so show the user, but any real calculations should be done on the server side (as clients can adjust and manipulate form submissions).
I created a simple example that will tally the results of checked checkboxes (and simply displays the result). There are lots of ways you can manipulate this code to fit your purpose. I have used jQuery, but there are other interesting options for this problem (check out KnockoutJS, for instance).
<input type="checkbox" class="adjust one" data-value="1.00" id="so1" /> <label for="so1">$1.00</label> <br/>
<input type="checkbox" class="adjust two" data-value="2.00" id="so2" /> <label for="so2">$2.00</label><br/>
<input type="checkbox" class="adjust one" data-value="3.00" id="so3" /> <label for="so3">$3.00</label>
<p>
Total: <span class="total"></span>
</p>
Then, you want to include the following JavaScript (along with the jQuery library).
var total;
var calculateTotal = function() {
total = 0.0;
$('input[type="checkbox"]:checked').each(function() {
total += parseFloat($(this).data('value'));
});
$('.total').text(total);
};
$(document).ready(function() {
$('input[type="checkbox"]').live('change', function() {
calculateTotal();
});
calculateTotal(); //do it for initial price
});
calculateTotal() will calculate a total based on the checkboxes (inputs of type checkbox) which match the selector "checked". This then pulls the data attribute "value" from each checkbox and calculates a total based on that number. The logic for your problem is likely to differ, but simply adjusting calculateTotal should handle this. Finally, the calculateTotal function gets called whenever a checkbox is 'changed' (and once initially).
Hopefully this should be a big help in getting you up and running. Here is a JSFiddle live demonstration.
Related
I am having what is probably a simple issue with some jQuery code. I have two inputs that form variables to a simple piece of maths. One is a text box, the other a range input. I need to display the result of a very simple calculation in a span element.
Here is the html and js I have:
<input type="text" name="txt_bserves" id="txt_bserves" value="0">
<span id="currsalesval">10%</span>
<input type="range" name="convertslider" id="convertslider" min="0" max="100" value="10">
<span id="currsalesconv">525 serves</span>
function updateValue()
{
var sliderval = $('#convertslider').val();
var bserves = $("#txt_bserves").val();
var cserves = (bserves * (sliderval/100));
$("#currsalesval").text(sliderval.concat("%"));
$("#currsalesconv").text(cserves.concat(" serves"));
}
$('#convertslider').on('change, mousemove', function(){
updateValue();
});
The issue comes on the third line, a simple piece of maths to calculate a percentage of the input box.
The currsalesval span updates fine with the percentage value from the slider. But the currsalesval span is not updated with the cserve value.
I realise this might be a type conversion issue, but having been thrugh a number of different variations of conversions, I thought I'd ask here instead.
Thanks in advance guys.
cserves is not a string , so it doesn't have a concat method. Instead of :
$("#currsalesconv").text(cserves.concat(" serves"));
try
$("#currsalesconv").text(cserves + " serves");
I need to create two text boxes where the user can insert number, and a button that adds them.
I need to use the .val() to bring the data from the html body, that is done.
My issue is that I don't know how to display the result in a text box, and not using the alert option.
Help!
You need to add change listeners to your html elements and you need to run a function on change.
<input type='number' id='firstBox' onChange='calculate()' />
<input type='number' id='secondBox' onChange='calculate()' />
<input type='number' id='answerBox' />
function calculate(){
var first = Number(document.getElementById('firstBox').value)
var second = Number(document.getElementById('secondBox').value)
var answer = document.getElementById('answer')
answer.value = first + second
}
Also, I created a quick fiddle for you here, definitely check it out it will help you get acquainted.
I have this piece of JavaScript that will sum up a totalprice based on radio/checkbox selection
JQUERY
var price = 0;
$('.price-input').click(function () {
if ($(this).is(":checked")) {
price += parseInt($(this).attr("data-price"), 10);
$('.total-price').text(price);
$('.total-price-input').val(price);
} else {
price -= parseInt($(this).attr("data-price"), 10);
$('.total-price').text(price);
$('.total-price-input').val(price);
}
});
The HTML is a collection of 3 radiobuttons and 3 checkboxes, where the radiobutton is one price and the checkboxes can sum up 3 prices with the radiobutton price to give a total price.
<input class="price-input" data-price="2000" id="ChosenLane" name="ChosenLane" type="radio" value="Konference - Spor 1: Lean">
<input class="price-input" data-price="1300" id="ChosenLane" name="ChosenLane" type="radio" value="Konference - Spor 2: Innovation">
<input class="price-input" data-price="1600" id="ChosenLane" name="ChosenLane" type="radio" value="Kage">
<input type="checkbox" name="lanes" value="Aften buffet" data-price="1000" class="price-input">
<input type="checkbox" name="lanes" value="fthrctfyh" data-price="5456" class="price-input">
<input type="checkbox" name="lanes" value="dfhxfhg" data-price="54545" class="price-input">
All in all this works - if I select a radiobutton it will add the radiobutton price to the price, but if I click a radiobutton again it will add the price again to the totalprice. I want the radiobuttons, not to add if one is selected, but instead just use its price.
So if I check a radiobutton it will at 2000 to the price and if I click another radiobutton, it will subtract the 2000 and add 1300 instead.
Please check the following solution:
JQUERY
$(function () {
$('.price-input').change(function () {
var price = 0;
$('.price-input').each(function(){
if ($(this).is(":checked")) {
price += parseInt($(this).attr("data-price"), 10);
}
})
$(".totalPrice").text(price);
});
})
Fiddle: http://jsfiddle.net/kkqqfaqv/
Change your code to change event from click event. As click event is called every time user clicks the radio box, doesn't matter whether selected or not. Change event will be triggered if the state of checkbox changes
I am not entirely clear about your relation betweeen price and total-price-input.
As a general rule for much higher robustness: Don't rely on clean unsetting-setting, i.e. that substracting X and adding Y always match up one on one.
Rather:
always start your callback function with price=0
check which input buttons and radio button are set
add up accordingly
This has also the benefit, that you can trigger such a clean-from-start calback after page DOM load: I.e. if user goes browser-forward, then back, inputs and radio buttons keep being checked (in any modern browser) ➠ having the correct value for that resurrected choice (rather than 0 and a “refresh problem” is good. ➠ Thus put it in a named distinct function, to call upon $.ready() and upon .change().
Also, I'd use .change() rather than .click(): Input can possibly change state by other means than click (like keyboard navigation?), and change is what you are looking for.
I'm working on this eCommerce project where I need to calculate "shipping costs" if a particular checkbox is checked.
Here's the code for the checkbox :-
<div class="alert alert-info">
<p>Shipping Outside Lagos (N2, 000)</p>
<input type="checkbox" name="shipping" id="shipping">
</div>
How can I write the jQuery function, so that when the input is checked..I can get the value in a variable. Suppose the default value is 2000, how would I be able to get $amount=2000 (if checked) and $amount remains 0 if unchecked.
Due to my limited knowledge in jQuery / JavaScript, I'm unable to find a solution for it.
Search didn't help either.
Any suggestions are welcome.
var amount = $('#shipping').is(':checked') ? 2000 : 0;
$('#shipping').on('change', function() {
amount = this.checked ? 2000 : 0;
});
// use amount
You can do:
var shippingAmt = 0;
$("#shipping").change(function() {
shippingAmt = this.checked ? 2000 : 0;
});
I'd suggest using a function to determine the cost of items. You could have an abstract of determining costs which would run through a few or several conditions to calculate 'add ons' so to speak.
So you'd have your initial total of say $500.99, then run that value through something like calculateTotalValue(value)
It would check if any add-ons were checked in the form, and add their values to the initial value.
This would allow you to have any number of extras, like shipping, or even add-ons/upgrades for the product itself, and you'd be able to fetch the total without fail in each case. You could have a generic way of stipulating that a field is an 'add on' so you wouldn't need to maintain a list, like so:
<input type="checkbox" rel="add-on" data-add-on-type="shipping" value="500">
Then in your function,
calculateTotalValue(value) {
$.each($('input[rel="add-on"]'), function(i) {
// You probably want some error checking here
value += this.val();
});
return value;
}
If necessary you could use data-add-on-type to keep track of where costs comes from to output a list for the user, as well.
I've made a form to process user input using PHP, and the first question asks the user to select one of three radio buttons to fill in the "type" parameter - the available options are "book", "journal", and "website", and the code looks like this:
<strong>Type of work:</strong>
<input type="radio" name="type" id="book" value="book" checked="checked" /> <label for="book">Book</label>
<input type="radio" name="type" id="journal" value="journal" /> <label for="journal">Journal</label>
<input type="radio" name="type" id="website" value="website" /> <label for="website">Website</label>
Further down the page, I have three fieldsets (using <fieldset>), each corresponding to one of the types. I'd like to have only one of these display at a time, depending on which radio button is selected, to make the page look cleaner.
Unfortunately, I'm a total JavaScript noob, and my last attempt broke things really badly. The fieldsets already have IDs (boxBook, boxJournal, and boxWebsite), although they currently don't do anything special.
If it affects anything, I'd like the output to be valid HTML5, and to degrade gracefully, displaying all three fieldsets if the user has JS disabled.
Any help would be greatly appreciated ^^
Using jQuery I'd suggest:
// hides the elements using jQuery (so they're visible without JavaScript)
$('#boxBook, #boxJournal, #boxWebsite').hide();
// when the radio inputs whose name is equal to "type" is changed:
$('input:radio[name="type"]').change(function() {
var id = this.id;
// hides all the fieldset elements whose `id` starts with "box":
$('fieldset[id^="box"]').hide();
// looks for the element with the id equal to
// `box` + upper-cased first-letter of this.id +
// the substring from second-letter onwards of this.id
$('#box' + id[0].toUpperCase() + id.substring(1)).show();
});
JS Fiddle demo.
Incidentally, rather than performing string manipulation on the id of the radio input, it'd be easier to either use a data-* attribute to specify the precise id of the targeted element:
<input type="radio" id="book" name="type" data-targets="boxBook" />
And use:
$('#boxBook, #boxJournal, #boxWebsite').hide();
$('input:radio[name="type"]').change(function() {
var id = $(this).attr('data-targets'); // or: $(this).data('targets');
$('fieldset[id^="box"]').hide();
$('#' + id).show();
});
JS Fiddle demo.
Edited the latter code-block to meet the OP's requirements:
$('input:radio[name="type"]').change(function() {
$(this).siblings('input:radio[name="type"]').each(function() {
$('#' + $(this).data('targets')).hide();
});
$('#' + $(this).data('targets')).show();
}).filter(function() {
return !this.checked;
}).each(function() {
$('#' + $(this).data('targets')).hide();
});
JS Fiddle demo.
Though, frankly, I think I've over-complicated it quite a bit. But it does work, and meets the needs specified in the comment:
if one of the radio buttons is checked by default, the fieldset doesn't display. I'd like to have it default to book if possible
You should use a function in a script element in the head, roughly like the following
function chooseFieldset(id) {
document.getElementById('boxBook' ).style.display =
(id == 'book') ?'display':'none';
document.getElementById('boxJournal').style.display =
(id == 'journal')?'display':'none';
document.getElementById('boxWebsite').style.display =
(id == 'website')?'display':'none';
}
Then you can call id every time a radio button is clicked, using the attribute on every radio:
onClick="chooseFieldset(this.id);"