I have a script that works pretty good for calculating a price total from checkboxes with a starting price. I got most of this code from Stackoverflow, but I need to tweak it a little.
I would like to add a comma to separate thousands in the total dollar amount. I've seen a few functions for this but don't know where to add the thousands comma function.
Here is the code:
HTML
<form action="#" method="" name="form">
<fieldset>
<div class="build-option">
<div class="build-title">King-Dome</div>
<label class="build-label"><input type="checkbox" name="nozzle" value="1500"> $1,500</label>
</div>
<div class="build-option">
<div class="build-title">Solar Package</div>
<label class="build-label"><input type="checkbox" name="nozzle" value="1800"> $1,800</label>
</div>
<div class="build-option">
<div class="build-title">Additional Awning</div>
<label class="build-label"><input type="checkbox" name="nozzle" value="900"> $900</label>
</div>
<div class="build-option">
<div class="build-title">Generator Basket</div>
<label class="build-label"><input type="checkbox" name="nozzle" value="250"> $250</label>
</div>
</fieldset>
Javascript
<script type="text/javascript">
window.onload=function() {
document.getElementsByTagName('fieldset')[0].onclick = totalizer;
};
function totalizer(e) {
var e = e? e : window.event;
var target = e.srcElement || e.target;
if(e.type=='click' && target.type=='checkbox') {
var cost = document.getElementById('cost');
var extra = parseFloat(target.value);
cost.firstChild.data = (parseFloat(cost.firstChild.data) + ((target.checked)? extra : -extra)).toFixed(2);
var parts = e.toString().split("."); //add this for comment - didn't work
parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ","); //add this for comment - didn't work
return parts.join("."); //add this for comment - didn't work
}
}
</script>
I also need to find a script to clear form elements by click a "Clear" form button and a script that clears the form checks if the page is refreshed. I could possibly skip the clear button if I could get the script to calculate "already" checked boxes when refreshing the page.
If you check a box now, the total will update. But if you leave the check then refresh the page, the starting total is then changed )it should be $39950. If you uncheck the box that was checked before refreshing, the total is then less than what the starting total should be.
I may need to ask a another question for this second part. Main thing is to fix the comma issue first.
Related
I'm not really sure the best way to go about this but I've laid the framework.
Basically, I would like to add the functionality so that when my #moreItems_add button is clicked and calls the moreItems function, I simply want to add a new Input field below it, and so on. I want to limit this to 10 fields though, so I show that in the function.
The only trick is, I will be submitting all fields via ajax to save to the database, so I need to try and keep track of an ID with each.
What's the best way to continue the javascript here so that I can append an input field on button press and keep track of IDs for each?
<div class="modal-body">
<form id="Items">
<label id="ItemLabel">Item 1:</label>
<input type="text" name="Items[]">
<button id="moreItems_add" onclick="moreItems()" id="moreItems">More Items</button>
</form>
</div>
<div class="modal-footer">
<input type="submit" name="saveItems" value="Save Items">
</div>
<!-- modal JS -->
<script type="text/javascript">
function moreItems(){
var MaxItems = 10;
//If less than 10, add another input field
}
</script>
You can use the jQuery .insertBefore() method to insert elements right before "more items" button. Below is the code representing this:
var maxItems = 1;
function moreItems() {
if (maxItems < 10) {
var label = document.createElement("label");
label.id="ItemLabel"+maxItems;
label.innerHTML = "Item "+(maxItems+1)+": ";
var input = document.createElement("input");
input.type='text';
input.name = 'item'+maxItems;
$('<br/>').insertBefore("#moreItems_add");
$(label).insertBefore("#moreItems_add");
$(input).insertBefore("#moreItems_add");
maxItems++;
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="modal-body">
<form id="Items">
<label id="ItemLabel">Item 1:</label>
<input type="text" name="Items[]">
<button type="button" id="moreItems_add" onclick="moreItems()" id="moreItems">More Items</button>
</form>
</div>
<div class="modal-footer">
<input type="submit" name="saveItems" value="Save Items">
</div>
Something like this should do the trick:
<!-- modal JS -->
<script type="text/javascript">
var MAX_ITEMS = 10,
added = 0;
function moreItems(){
if (added >= MAX_ITEMS) return;
var newField = document.createElement('input');
newField.type = 'text';
// TODO: Any field setup.
document.getElementById('items').appendChild(newField);
added++;
}
</script>
In terms of tracking each field with an ID, that should always be done by the back-end for data integrity and safety reasons.
some years ago I've wrote an article about making a repeated section using jQuery.
The live example is available on jsFiddle.
In the example you can find that both "add" and "remove" button are available, however you can set just the "add" button for your purpose.
The idea to limit to specific number of repeated boxes is to watch the number of repeatable elements just created in the context. The part of code to change in the live example is rows 13-18:
// Cloning the container with events
var clonedSection = $(theContainer).clone(true);
// And appending it just after the current container
$(clonedSection).insertAfter(theContainer);
There you should check if the number of repeated elements is less than <your desired number> then you will allow the item to be created, else you can do something else (like notice the user about limit reached).
Try this:
const maxItens = 10,
let itensCount = 0;
function moreItems() {
if (itensCount++ >= maxItens) {
return false;
}
let newInput = document.createElement('input');
// use the iterator to make an unique id and name (to submit multiples)
newInput.id = `Items[${itensCount}]`;
newInput.name = `Items[${itensCount}]`;
document.getElementById('items').appendChild(newInput);
return false;
}
Add type "button" to stop submiting the page (also, your button have two ID):
<button id="moreItems_add" onclick="moreItems();" type="button">More Items</button>
The submit button must be inside the form to work:
<form>
<div class="modal-body">
<div id="Items">
<label id="ItemLabel">Item 1:</label>
<input type="text" name="Items[]">
</div>
<button id="moreItems_add" onclick="moreItems()" id="moreItems">More Items</button>
</div>
<div class="modal-footer">
<button type="submit">Save Items</button>
</div>
</form>
To append itens in sequence the button must be outside of div "itens".
I have a small quiz application that I am converting into angular. It displays a question, and 4 possible answers that you select through radio buttons. You can move to the next question or back to the original and your selection is noted.
I am having problems reselecting the radio button when I want to go back to the question. The attribute for the button states that I have changed it to true, but it is not indicated. Only when I go back to the first question, and try to go back a second time does it update correctly. I am assuming that since it can't back back any further and can run again that there is some updating to the buttons going on and that is what is doing it.
The extra space appears to be a formatting issue with stack overflow, it isn't in my actual code base. I have since remove it.
Any help would be greatly appreciated. The code is rough right now as I just have everything thrown into the controller. Some structure will come later.
HTML
<div ng-controller="mainController" class="col-md-5 col-md-offset-5">
<div>
{{quizQuestions}}
</div>
<div ng-repeat="answers in quizAnswers">
<label>{{answers}}</label>
<input class="rad" type="radio" name="answer" ng-click="markAnswer($index)">
</div>
<div>
<label>Change the question</label>
<input type="button" ng-click="decrease()" value="Back">
<input type="button" ng-click="increase()" value="Next">
</div>
</div>
Angular
$scope.adder = 0;
$scope.answer = [];
$scope.markAnswer = function(index) {
$scope.answer.splice($scope.adder,1,index);
};
$scope.display = function(number) {
$scope.quizQuestions = allQuestions[number].question;
$scope.quizAnswers = allQuestions[number].choices;
};
$scope.decrease = function() {
if($scope.adder === 0) {
} else {
$scope.adder -= 1;
$scope.display($scope.adder);
}
document.getElementsByClassName('rad') [$scope.answer[$scope.adder]].checked = true;
};
$scope.display($scope.adder);
There is a syntax error in your "rad" class ng-click
<input class="rad" type="radio" name="answer" ng- click="markAnswer($index)">
you need to take out the space between ng- and click
For what your doing, you should look into the ng-model directive. Mind if take a look at your markAnswer() function?
Right now my code is very "hard-coded" and repetitive. I'd like to know if there is a cleaner way to do the following. Ideally, I want to iterate through my forms fields with a loop and calculate the results with one statement, but I'm struggling to figure out how best to do so.
Summary: I have ten form fields, each with a distinct decimal value that a user may or may not supply. When the user hits submit, it should add the value in the input field with a value being displayed on the current HTML page, then insert into the DB.
First, I grab that value from the form input field and convert it into a number with two decimal places. I then grab the current total from the HTML and add the two numbers together. After that I inject that total back into the form input field so that it can be stored in $_POST and inserted into a database.
How can I make my code more DRY (ie, Don't Repeat Yourself)? Below are just two examples but they are exactly the same except for the element calls:
var subtotal = Number($("#housing").val());
subtotal = (subtotal).toFixed(2);
var currentTotal = $('#output-housing').html().replace("$", "");
var total = Number(subtotal) + Number(currentTotal);
$('#housing').val(total);
var subtotal = Number($("#utilities").val());
subtotal = (subtotal).toFixed(2);
var currentTotal = $('#output-utilities').html().replace("$", "");
var total = Number(subtotal) + Number(currentTotal);
$('#utilities').val(total);
I would like to iterate through my input fields like so, but I'm trying to figure out how I could display the logic inside:
var input = $('.form-expenses :input');
input.each(function() {
// Insert switch statement here?? Some other construct??
});
HTML: (Uses Bootstrap 3 classes)
FORM:
<form class="form-expenses form-horizontal" role="form" method="post" action="/profile/update">
<div class="form-group">
<label for="housing" class="control-label col-sm-3">Housing</label>
<div class="input-group input-group-lg col-sm-9">
<span class="input-group-addon">$</span>
<input type="text" class="form-control" name="housing" id="housing" />
</div>
</div>
<div class="form-group">
<label for="utilities" class="control-label col-sm-3">Utilities</label>
<div class="input-group input-group-lg col-sm-9">
<span class="input-group-addon">$</span>
<input type="text" class="form-control" name="utilities" id="utilities" />
</div>
</div>
...
<button class="btn btn-lg btn-primary btn-block" id="update-expenses" type="submit"> Update</button>
</form>
OUTPUT:
<tr>
<td>Housing</td>
<td id="output-housing">$<?php echo $total['housing']?></td>
</tr>
<tr>
<td>Utilities</td>
<td id="output-utilities">$<?php echo $total['utilities']?></td>
</tr>
Something like this should work. Assumes the same prefixing relationship of output/input ID's
$(function() {
$('form.form-expenses').submit(function() {
updateValues();
return false/* prevent submit for demo only*/
})
})
function updateValues(){
$('.form-expenses :input').not('#update-expenses').each(function(){
var $input=$(this), inputId=this.id;
var curr=$('#output-'+inputId).text().replace("$", "");
$input.val(function(i,val){
return (1*(val ||0) + 1*curr).toFixed(2);
})
});
}
DEMO
From a UI perspective, this seems very counter intuitive to change values that user just input.
To create ajax data object instead of updating the display values:
function getAjaxData(){
var ajaxData={}
$('.form-expenses :input').not('#update-expenses').each(function(){
var $input=$(this), inputId=this.id;
var curr=$('#output-'+inputId).text().replace("$", "");
ajaxData[this.name] =(1*(val ||0) + 1*curr).toFixed(2);
});
return ajaxData
}
/* in submit handler*/
$.post('path/to/server', getAjaxData(), function(response){/*do something with reponse*/})
"if I allow a user to add/remove fields, then this could get a bit sticky"
In that case, give your fields a class name. As long as that exists on added fields, they will all be calculated.
<input type="text" class="form-control calculate-me" name="housing" id="housing" />
And iterate though all, using their ids as a reference
$(".calculate-me").each(function(){
var ref=this.id;
var subtotal = Number($("#" + ref).val());
subtotal = (subtotal).toFixed(2);
var currentTotal = $('#output-' + ref).html().replace("$", "");
var total = Number(subtotal) + Number(currentTotal);
$('#' + ref).val(total);
});
I am trying to make a form that generates a value based on weighted inputs. For example, if we had the following in the database
**Item** _|_**Weight**
sink | 1.5
toilet | 2.5
shower | 3
And a form that looked like this, built from the database, using AJAX (Has to be built using AJAX, because the inputs' names and the number of inputs varies depending on a user selection in a previous section of the form)
<form id="calculator">
...There are several field sets here...
<fieldset id="myFields">
<input type="text" class="iteminput" data-weight="1.5" name="sink" id="sink">
<input type="text" class="iteminput" data-weight="2.5" name="toilet" id="toilet">
<input type="text" class="iteminput" data-weight="3" name="shower" id="shower">
</fieldset>
</form>
If the user puts in that they have X sinks, Y toilets, and Z showers, I want to automatically calculate the total "value" of their plumbing system, in this case, X*1.5+Y*2.5+Z*3.
Where I am hung up is on how to get the value of each input. What I want to be able to do is loop through all of the inputs in #myFields, get the value of the field, as well as the value of the data-weight attribute, multiply them together, then add them to a running total. I would like to do all of this in a function attached to the onKeyUp event for each input.
Any help is appreciated, and more information can be provided if necessary.
Javascript only solution would be best, but I am not against using jQuery if it drastically simplifies the answer.
Here is a jQuery example:
You should be able to get the values of the inputs on a blur function. And then update the values by running an each function on the inputs. Something like this...
<ul>
<li>
<label>Number of X</label>
<input type="text" value="" id="x"/>
</li>
<li>
<label>Number of Y</label>
<input type="text" value="" id="y"/>
</li>
<li>
<label>Number of Z</label>
<input type="text" value="" id="z"/>
</li>
</ul>
<p>Total is: <span class="total"></span>
jQuery:
$('input').blur(function () {
var total = 0;
$('input').each(function() {
total += Number($(this).val());
});
$('.total').text(total);
});
DEMO:
http://jsfiddle.net/DYzsR/1/
This is what I ended up doing.
function calcFixtures()
{
var elements = [];
var total = 0;
elements = document.getElementsByClassName('fixtureinput');
for (var i=0; i<elements.length; i++) {
total += elements[i].value * elements[i].getAttribute("data-weight");
}
}
Logic being, get all elements with a certain class, loop through them, and for each element, get the value of the data-weight attribute and multiply it by the current form value for that element. Thanks to #Kris for the idea of doing it as a running total rather than a single calculation. That was really the breakthrough point.
I am making a form field where I would like to do a simple show-hide to display div's on a radio button.
<form id="basic" name="basic">
<label><input name="formelement" type="radio" value="yes" /> Yes </label>
<label><input name="formelement" type="radio" value="no" /> No </label>
<div id="yes" style="display: none;">
This is the div that displays that shows when 'Yes' is selected.
</div>
<div id="no" style="display: none;">
This is the div that displays that shows when 'No' is selected.
</div>
</form>
I have played with some various javascript's I have found online and have achieved not a lot of success as most of them online manage to show-hide one div. Getting the 'yes' to hide when 'no' is selected and vice-versa is the tricky part. If anyone could provide some assistance that would be really appreciated!
Just paste these code between head tags
<script type="text/javascript">
window.onload=function(){
var el1 = document.getElementsByName('formelement')[0];
var el2 = document.getElementsByName('formelement')[1];
el1.onchange=function(){
var show=el1.value;
var hide=el2.value;
document.getElementById(show).style.display='block';
document.getElementById(hide).style.display='none';
}
el2.onchange=function(){
var show=el2.value;
var hide=el1.value;
document.getElementById(show).style.display='block';
document.getElementById(hide).style.display='none';
}
}
</script>
DEMO.
The below is assuming value of radio is same as id of the div..
function getRadioVal(name){
var oRadio = document.forms[0].elements[name];
for(var i = 0; i < oRadio.length; i++)
if(oRadio[i].checked)
return oRadio[i].value;
return '';
}
//hide both divs..
document.getElementById("yes").style.display = "none";
document.getElementById("no").style.display = "none";
//show only one of them..
document.getElementById(getRadioVal("formelement")) = "block";
Dealing with javascript without any libraries is a pain when things get complex, I would recommend libraries such as jQuery
this is what you want
How can I check whether a radio button is selected with JavaScript?
assign onclick event and you are good to go.