I have a form, where a user can select between different options inside a few dropdown fields. Depending on the user selection, the values will be displayed inside a span field next to the dropdown field.
Now I would like to count all those values inside the span fields, so that I can display a total amount at the end of the form before it will be submitted.
Here is a part of my form:
<form name='formname_form' action='./index.php' method='post' class='formname-form' id='formname-form'>
<div class="row" id='save_prices'>
<div class="col-lg-8 offset-lg-2 col-md-10 offset-md-1 col-sm-12">
<div class="form-inline">
<label class="form-icon">
<figure>
<img src="../assets/images/symbol-1.png" alt="/">
</figure>
</label>
<div class="form-group">
<select name="field_a" id="field_a" onchange="CalcDiscount()">
<option value="0,00">Option A?</option>
<option value="6,17">Yes</option>
<option value="0,00">No</option>
</select>
</div>
<div class="amount-wrap-3">
<span>€ <span id='field_a_price' class='prices'></span></span>
</div>
</div>
<div class="form-inline">
<label class="form-icon">
<figure>
<img src="../assets/images/symbol-2.png" alt="/">
</figure>
</label>
<div class="form-group">
<select name="field_b" id="field_b" onchange="CalcDiscount()">
<option value="0,00">Option B</option>
<option value="17,50">Yes</option>
<option value="0,00">No</option>
</select>
</div>
<div class="amount-wrap-3">
<span>€ <span id='field_b_price' class='prices'></span></span>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-lg-8 offset-lg-2 col-md-10 offset-md-1 col-sm-12">
<div class="total-amount">
Total Price
<div class='price'><span id='total_price' class="total_price"></span> €</div>
</div>
</div>
</div>
<div class="row">
<div class="col-lg-6 col-xs-12">
<div class="form-inline">
<input name='submit' type='submit' id='submit' value='Save' class='btn btn-form-indiv'/>
</div>
</div>
</div>
</form>
And here is my javascript part:
<script>
// Get references to the objects you need (<select> and <span>)
var field_a = document.getElementById('field_a');
var field_a_price = document.getElementById('field_a_price');
var field_b = document.getElementById('field_b');
var field_b_price = document.getElementById('field_b_price');
// When the list value changes, set the innerHTML of the <span>
field_a.onchange = function() {
field_a_price.innerHTML = this.value;
};
field_b.onchange = function() {
field_b_price.innerHTML = this.value;
};
var priceList = $('#save_prices').find('.prices');
var totalPrice = 0;
$.each(priceList, function(i, price){
totalPrice += parseInt($(price).text())
});
$('.total_price').text(totalPrice);
</script>
Does anyone have an idea what I am doing wrong? The value inside my span with the class total_price stays always 0. I assume that is has something to do with my onChange methods that I am using?
Problem
The total from the 2 select boxes are not appearing in the Total Price area.
Solution
Create a function and call it to fire off on the onchange event when a new value is selected in the selection boxes.
Example
// Get references to the objects you need (<select> and <span>)
var field_a = document.getElementById('field_a');
var field_a_price = document.getElementById('field_a_price');
var field_b = document.getElementById('field_b');
var field_b_price = document.getElementById('field_b_price');
// When the list value changes, set the innerHTML of the <span>
field_a.onchange = function() {
field_a_price.innerHTML = this.value;
// Calling new function
updateTotal();
};
field_b.onchange = function() {
field_b_price.innerHTML = this.value;
// Calling new function
updateTotal();
};
// New function
function updateTotal() {
var p = $('.prices').map(function () { return $(this).text(); }).get();
var totalPrice = 0;
$.each(p, function( index, value ) {
totalPrice = totalPrice + value;
$('.total_price').text(totalPrice);
});
}
Summary
I am not sure what you are attempting to do with the values considering they have commas.
To directly address your question, when your code is ran the reason the values are always empty is because all the code only runs on page load. When you change the selection box values only the code in the onchange was being ran. By adding a function that is called each time a selection is made we can populate the array from the class list returned with JQuery.
Related
I'm currently able to append HTML and remove the right appended HTML, but when I add more of that HTML it is appended with the same id so the functionality if I want to show or hide a certain div element, is not working.
This is the code that i append and remove:
$(".adRowOutdoor").click(function(){
var newTxt = $('<div class="add-row-outdoor row width-100 padding-left-15"> <div class="form-group col-md-4"> <label for="state" class="control-label">Type</label> <div class="sg-select-container"> <select id="choose-outdoor"> <option disabled="">Choose type</option> <option value="Undercover walkway">Undercover walkway</option> <option value="Oval">Oval</option> <option value="Swimming Pool">Swimming Pool</option> <option value="Outdoor Basketing Court">Outdoor Basketing Court</option> <option value="other">Other</option> </select> </div> </div><!-- end col --> <div id="choose-outdoor-is-hidden" class="form-group col-md-4" style="display: none;"> <label for="other-textfield" class="control-label">Other</label> <input type="text" class="form-control form-input-field" name="other-textfield" value="" required="" placeholder=""> <span class="help-block"></span> </div> <div class="col-md-2 remove-btn-audit form-space-top-35"> <button class="btn btn-add-waste removeOutdoor"><i class="fa fa-minus-circle o-btn-add" aria-hidden="true"></i>Remove</button> </div> </div><!-- row audit -->');
$(".row-outdoor-container").append(newTxt);
});
$("body").on('click' , '.removeOutdoor' , function(){
var curRow = $(this).parents('div.add-row-outdoor');
curRow.remove();
});
An image how it looks is:
What I want now is to hide and show a div element with a text field on the selection of the certain div with a unique id that I want to generate.
I'm able to show that text field only for the first element, but not for other appended HTML.
$('#choose-outdoor').change(function (e) {
var val = $("option:selected", this).val()
if (val == 'other') {
$('#choose-outdoor-is-hidden').show();
}
// Hide complete sub type div
else {
$('#choose-outdoor-is-hidden').hide();
}
});
JsFiddle of my code is here
Change id to classes so basically make choose-outdoor and choose-outdoor-is-hidden as your classes on the same elements.
Then use event delegation as the elements are dynamically created:
$('.row-outdoor-container').on("change", '.choose-outdoor', function (e) {
var val = $(this).val();
$el = $(this).closest(".add-row-outdoor").find('.choose-outdoor-is-hidden');
if (val == 'other') {
$el.show();
}
else {
$el.hide();
}
});
Updated fiddle
Given that I have 5 input fields that are linked to their own price, I want to be able to grab the value of the input multiplied by its specific price and return that value to the dom.
This is what's being rendered, there are 5 with a unique price.
I'm not sure how to link each input to its specific price, add the prices of all 5 inputs (if there are any) and post them on the dom.
I'm trying to get the data-price of the .class p tag, loop through them, link it to their input add the sum and post the sum to the dom
<section data-itemid="${menuObj.id}">
<div class="amount">
<input type="number" placeholder="Quantity" min="0" name="${menuObj.id}">
</div>
<div class="item">
<h1>${menuObj.name}</h1>
<p class="food">${menuObj.description}</p>
<p class="price" data-price="${menuObj.price}">${menuObj.price}</p>
</div>
</section>
I have it working for one, but not sure how to get them working for all
$(function() {
$('input').on('keyup', function() {
var input = $('.amount input').val();
var price = $('.price').data('price');
var final = $('.finalprice p');
var total = input * price;
final.text(total);
});
})
For dynamic content use event delegation to bind events.
$(document).on('input', '.menu-class div[class="amount"] input[type="number"]', function() {...}
Use input event to cover every change on your input Quantity.
Apply a class to the section. i.e: .menu-class
Approach
Basically, loop over the section and collect the amount.
var total = 0;
$('.menu-class').each(function() {
var $section = $(this);
var input = $section.find('div.amount [type="number"]').val();
var price = $section.find('.price').data('price');
total += (input * price);
});
$finalPrice.text(total);
Snippet
$(function() {
var $finalPrice = $('.finalprice p');
$finalPrice.on('calculate', function() {
var total = 0;
$('.menu-class').each(function() {
var $section = $(this);
var input = $section.find('div.amount [type="number"]').val();
var price = $section.find('.price').data('price');
total += (input * price);
});
$finalPrice.text(total);
});
$(document).on('input', '.menu-class div[class="amount"] input[type="number"]', function() {
$finalPrice.trigger('calculate');
});
});
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<section class='col-md-6 col-xs-6'>
<section class='menu-class' data-itemid="111">
<div class="amount">
<input type="number" placeholder="Quantity" min="0" name="quant_111">
</div>
<div class="item">
<h1>My Meat :-)</h1>
<p class="food">Meat</p>
<p class="price" data-price="1000.0">1,000.00</p>
</div>
</section>
<hr>
<section class='menu-class' data-itemid="112">
<div class="amount">
<input type="number" placeholder="Quantity" min="0" name="quant_112">
</div>
<div class="item">
<h1>My bread :-)</h1>
<p class="food">Bread</p>
<p class="price" data-price="2000.0">2,000.00</p>
</div>
</section>
</section>
<section class='col-md-6 col-xs-6'>
<section class='finalprice'>
<h1>Final price</h1>
<p>
</p>
</section>
</section>
$('.amount input') returns an array-like object of all dom elements that match the selector. I believe $('.amount input').val(); will return value from the first item in the array
You may want to localize finding inputs, like below:
$(function() {
$('input').on('keyup', function() {
var $section = $(this).closest('section');
var input = $section.find('.amount input').val();
var price = $section.find('.price').data('price');
var final = $section.find('.finalprice p');
var total = input * price;
final.text(total);
});
});
I've created cash denomination calculator in jquery, and it's working fine once you add entry but suppose if you try to change those entries then it's not calculating values as i expected.
Just fill those values and you'll get total of all, but if try to change the value of input box inside div with '.mul_by' class[i.e. the small input box before '=' sign] then it's not calculating the total properly.
And here's the jsFiddle for the same.
$('.mul_by').each(function (i) {
var _this = $(this),
//set default input value to zero inside .mul-by div
setZero = _this.find('.form-control').val(0),
//set default input value to zero inside .mul-val div
setDenominationVal = _this.siblings('.mul_val').find('.form-control').val(0),
//set default input value to zero inside .total div
setTotalVal = $('.total').val(0);
setZero.on('change', function () {
//watch and store input val. inside .mul_by
var getUpdatedVal = _this.find('.form-control').val(),
//get label text
getDenominationVal = parseInt(_this.siblings('label').text()),
//update mul_by div after multiplication
updateDenominationVal = _this.siblings('.mul_val').find('.form-control');
if (getUpdatedVal > 0) {
var vals = updateDenominationVal.val(getUpdatedVal * getDenominationVal);
total = parseInt(setTotalVal.val()) + parseInt(vals.val());
setTotalVal.val(total);
} else {
updateDenominationVal.val(0);
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form class="form-horizontal">
<div class="form-group">
<label class="control-label col-md-2 col-xs-2" for="batch">2000</label>
<div class="col-md-1 col-xs-4 mul_by">
<span>x </span> <input type="text" class="form-control">
</div>
<div class="col-md-3 col-xs-5 mul_val">
<span style="font-size: 18px;">= </span> <input type="text" class="form-control">
</div>
</div>
<div class="form-group">
<label class="control-label col-md-2 col-xs-2" for="batch">500</label>
<div class="col-md-1 col-xs-4 mul_by">
<span>x </span> <input type="text" class="form-control">
</div>
<div class="col-md-3 col-xs-5 mul_val">
<span style="font-size: 18px;">= </span> <input type="text" class="form-control">
</div>
</div>
<div class="form-group">
<label class="control-label col-md-2 col-xs-2" for="batch">100</label>
<div class="col-md-1 col-xs-4 mul_by">
<span>x </span> <input type="text" class="form-control">
</div>
<div class="col-md-3 col-xs-5 mul_val">
<span style="font-size: 18px;">= </span> <input type="text" class="form-control">
</div>
</div>
<div class="form-group">
<hr>
<label class="control-label col-md-2 col-xs-2" for="batch">total:</label>
<div class="col-md-3 col-xs-5 mul_val">
<span style="font-size: 18px;">= </span> <input type="text" class="form-control total">
</div>
</div>
</form>
How do i update total after making changes?
Hope you understand it. Thanks in advance for your help.
Please check this code i get proper result I had made lot of changes at end hope you will get desired result:-
$(document).ready(function () {
$('.mul_by').each(function (i) {
var _this = $(this),
//set default input value to zero inside .mul-by div
setZero = _this.find('.form-control').val(0),
//set default input value to zero inside .mul-val div
setDenominationVal = _this.siblings('.mul_val').find('.form-control').val(0);
//set default input value to zero inside .total div
setTotalVal = $('.total').val(0);
setZero.on('change', function () {
var getcurrentval = $(this).val();
console.log('getcurrentval',getcurrentval)
//watch and store input val. inside .mul_by
var getUpdatedVal = _this.find('.form-control').val(),
//get label text
getDenominationVal = parseInt(_this.siblings('label').text()),
//update mul_by div after multiplication
updateDenominationVal = _this.siblings('.mul_val').find('.form-control');
console.log(getUpdatedVal,getDenominationVal)
var vals = 0,total=0;
if(getUpdatedVal > 0){
if(updateDenominationVal.val()>0){
vals = updateDenominationVal.val(getUpdatedVal * getDenominationVal - updateDenominationVal.val());
total = parseInt(setTotalVal.val()) + parseInt(vals.val()) ;
updateDenominationVal.val(getUpdatedVal * getDenominationVal);
console.log('total',total,'setTotal',setTotalVal.val(),vals.val());
}
else{
vals = updateDenominationVal.val(getUpdatedVal * getDenominationVal);
updateDenominationVal.val(getUpdatedVal * getDenominationVal);
total = parseInt(setTotalVal.val()) + parseInt(vals.val());
}
console.log(vals.val());
setTotalVal.val(total);
} else{
updateDenominationVal.val(0);
}
});
});
});
I am having some difficulties with selecting a value from an array in the same function that I populate the select using ng-options. I am trying to dynamically load a select list full of options and at the same time there is a default value from the last time the user chose something that I want to already be selected. when console.logging I can see that this works and is added to machineProfile.input but the select does not reflect what the ng-model has as a current value. I did confirm that they are both the same. I have some code below.
$scope.getMachineProfile = function(object) {
var count = 0;
var keepGoing = true;
$scope.machineProfile.machineName = object.Name;
$scope.machineInputs = object.Hardware;
/*angular.forEach(object.Hardware, function(inputs, key) {
console.log($scope.machineInputs);
});*/
//var foundMachine = 0;
angular.forEach($scope.machineProfiles, function(machine, key) {
if (keepGoing) {
if (machine.remoteAddr === object.Address) {
keepGoing = false;
/*$timeout(function(){
}, 500);*/
/*console.log($scope.machineProfiles[count].input);
console.log($scope.machineProfile.input);*/
$scope.machineProfile.input = $scope.machineProfiles[count].input;
$scope.machineProfile.workType = $scope.machineProfiles[count].workType;
$scope.machineProfile.workPeriod = $scope.machineProfiles[count].workPeriod;
$scope.machineProfile.counterRate = $scope.machineProfiles[count].counterRate;
$scope.machineProfile.timerRate = $scope.machineProfiles[count].timerRate;
console.log($scope.machineProfile);
//console.log('Awesome select: ' + count);
//console.log($scope.machineProfiles[count].input);
}
++count;
}
});
HTML
<ul class="nav sidebar-menu">
<li ng-repeat="machine in machineObj" class="">
<a ng-click="getMachineProfile(machine)">
<span class="fa fa-cogs"></span>
<span class="sidebar-title">{{machine.Name}}</span>
</a>
</li>
</ul>
Below is once a item is selected from the code above:
<div class="col-sm-4">
<div class="form-group">
<label for="chooseInput" class="control-label">Choose Input</label>
<!-- <select name="chooseInput" class="form-control" ng-model="machineProfile.input">
<option ng-selected="machine.input === machineProfile.input" ng-repeat="machine in machineInputs" value="machine.input">
{{machine.input === machineProfile.input}}
</option>
</select> -->
<select name="chooseInput" class="form-control" ng-model="input" ng-change="awesome(machineProfile.input)" ng-options="machine.input for machine in machineInputs track by machine.input"></select>
<!-- <input disabled="true" name="machineName" type="text" class="form-control" placeholder="Machine Name"> -->
</div>
</div>
Any help is appreciated as this is driving me nuts. The $scope object machineProfile.input is updated but nothing appears on screen.
Looks like your ng-model is not correct. Try this.
<select name="chooseInput" class="form-control" ng-model="machineProfile.input" ng-change="awesome(machineProfile.input)" ng-options="machine.input for machine in machineInputs track by machine.input"></select>
I am trying to implement automatically HTML using form value.
When user enter the information in the form, the JS will create the correspond HTML for him.
For example.
<div class="row" id="1">
<div class="form-group col-lg-2">
<select class="form-control" name="tag">
<option value="p" selected>p</option>
<option value="br">br</option>
</select>
</div>
<div class="form-group col-lg-2">
<select class="form-control" name="class">
<option value="Day" selected>Day</option>
<option value="BlockTime">BlockTime</option>
<option value="BlockTitle">BlockTitle</option>
<option value="Session">Session</option>
<option value="Person">Person</option>
<option value="Firm">Firm</option>
</select>
</div>
<div class="form-group col-lg-7">
<textarea class="form-control" rows="3" name="content"></textarea>
</div>
<div class="form-group col-lg-1">
<input type="button" class="btn btn-default" onclick="addLine()" value="Add">
</div>
</div>
The user selected P, Day, Test message, and the press "Add" button, the button will call function addLine(). The main part is below, I didn't make it right.
var currentTag = currentLine.find("select[name='tag'] option:selected").text();
var currentClass = currentLine.find("select[name='class'] option:selected").text();
var currentText = currentLine.find("textarea").val();
var new_content = $("<currentTag></currentTag>").addClass(currentClass).html(currentText);
Now the currentTag will get the value "p", currentClass will get "Day", currentText do get "Test message", this has been done.
This is what I want, the jQuery creates HTML code like this:
<p class="Day">Test message</p>
And I want to store the HTML code to a variable called new_content. ...
If you have a container for these elements, you could just append them to it:
First you want to set your new line as a variable:
var newElements = [];
var i = 0; //Make an index counter so you can use it later if you want to. This is optional
/* Do your selection script */
var htmlElement = "<" + currentTag + " class='" + currentClass + "'>" + currentText + "</" + currentTag + ">";
newElement.push(htmlElement, i);
$('.container').append(htmlElement);
i++; //increment your i to create an index
/* Make sure all of this is inside your selection script. */