Calculating TOTAL in added input fields - javascript

I have this small problem. I have been checking out the net to find an answer, but it is mostly for input fields which aren't generated / added.
<script>
$(document).ready(function(){
/* --- ADD FIELD --- */
$('.TotalMultiField').each(function() {
var $wrapper = $('.multiFields', this);
$(".addField", $(this)).click(function(e) {
$('.multiField:first-child', $wrapper).clone(true).appendTo($wrapper).find('input').val('').focus();
});
/* --- REMOVE FIELD --- */
$('.multiField .removeField', $wrapper).click(function() {
if ($('.multiField', $wrapper).length > 1)
$(this).parent('.multiField').remove();
});
});
</script>
Above is the Jquery script to add and remove fields. And below is the HTML code. As you see, in the "insert a number" field, the total should appear in the span id="added".
<form role="form" action=""" method="">
<div class="TotalMultiField">
<div class="multiFields">
<div class="multiField">
<input type="date">
<input type="number" class="number" placeholder="Insert a number">
<button type="button" class="removeField">Remove</button>
</div>
</div>
<button type="button" class="addField">Add field</button>
</div>
Total:<span id="added"></span>
</form>

Just noticed you updated that you do indeed want a sum, here is a fiddle with the total calculated on blur and when you remove a row, bind additional events as required (some tidy up is required, but this should get you started):
http://jsfiddle.net/1ggaco1d/4/
The below code does the totaling:
function total() {
var total = 0;
$(".number").each(function (idx, el) {
var value = $(el).val();
if (value !== "") {
total = total + parseFloat($(el).val());
}
});
$("#added").text(total);
}

Please check the below fiddle
https://jsfiddle.net/srsu4rne/
You should be able to just count the classes in the div
var multiField = $('.multiField').length
$('#added').html(multiField);

Related

Change only one element after clicking other

I have the following problem:
I would like to change the value of an input field, which is next to an another element, which will be clicked.
HTML:
<div>
<a id="{$sArticle.articleID}" class="minus"><i class="icon-minus-wide"></i></a>
<input class="quantityNum--input quantity{$sArticle.articleID}" name="sQuantity"
type="text" value="{$sArticle.minpurchase}">
<a id="{$sArticle.articleID}" class="plus"><i class="icon-plus-wide"></i></a>
</div>
JS:
$(document).on('click', ".plus", function (event) {
let currentTarget = event.currentTarget;
let idOfClickedElement = $(currentTarget).attr('id');
let currentQuantity = Number($('.quantity' + idOfClickedElement).val());
$(this).parent().find(".quantity" + idOfClickedElement).val(currentQuantity + 1)
});
There are other input fields which are the same like in the example. Those value changes also, but I want only one.
As each input with +/- is inside a div wrapper, you can use
$(this).closest("div").find(".quantityNum--input")
to get the related input.
There's no need for the numeric IDs when using relative DOM traversal.
Combining the + and - into a single event gives:
$(document).on('click', ".minus,.plus", function() {
var delta = $(this).is(".plus") ? 1 : -1;
$(this).closest("div").find(".quantityNum--input").val((i, val) => {
console.log(val);
return (val * 1) + delta;
});
});
.minus,
.plus {
cursor: pointer
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
<a class="minus">[-]<i class="icon-minus-wide"></i></a>
<input class="quantityNum--input" name="sQuantity" type="text" value="100">
<a class="plus">[+]<i class="icon-plus-wide"></i></a>
</div>
<div>
<a class="minus">[-]<i class="icon-minus-wide"></i></a>
<input class="quantityNum--input" name="sQuantity" type="text" value="500">
<a class="plus">[+]<i class="icon-plus-wide"></i></a>
</div>
I thik you are looking for .next and .prev.
note: I like sharing information usingdata-attributes so I've used that. you can use anything else id/class to differentiate. that's upto you
Just created a demo script for you
$('.number-action-button').on('click', function(){
const direction = $(this).data('direction');
if(direction === 'decrement'){
const $input = $(this).next('input[type="number"]');
$input.val($input.val() - 1);
}
if(direction === 'increment'){
const $input = $(this).prev('input[type="number"]');
$input.val(parseInt($input.val()) + 1);
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button class="number-action-button" data-direction="decrement">-</button>
<input type="number" value="0" />
<button class="number-action-button" data-direction="increment" >+</button>
simple solution: bundle the 3 elemts into 1 container, so your parent selector can easily catch the input, the way you already do it.
<div>
<a id="{$sArticle.articleID}" class="minus"><i class="icon-minus-wide"></i></a>
<input class="quantityNum--input quantity{$sArticle.articleID}" name="sQuantity"
type="text" value="{$sArticle.minpurchase}">
<a id="{$sArticle.articleID}" class="plus"><i class="icon-plus-wide"></i></a>
</div>
if you cant(or dont want) change the html use $(this).next() (or $(this).prev() for the plus button) in order to fint the input.
btw: maybe you'll try that funktion (havn't tested it, but at least it should give you an idea how to)
$(document).on('click', ".plus,.minus", function (event) {
let input_quantity=false;
if($(this).hasClass('plus'){
input_quantity=$(this).prev();
input_quantity.val(parseInt(input_quantity.val())+1);
}else{
input_quantity=$(this).next();
input_quantity.val(parseInt(input_quantity.val())-1);
}
});

how to display the array of values for the single field using jquery?

Here I need to get all the values entered in the input field. But it echoes only the first value.
ie. When I press the + and give some values, I need to get that value too.
$(document).ready(function() {
$(document).on("click", ".add", function() {
var clone = '<div class="add1"><input type="text" name="selprice" /><input type = "submit" value = "+" class = "add" ><input type = "submit" value = "-" class = "remove" ></div>';
$(this).closest('.add1').after(clone);
});
$(document).on("click", ".remove", function() {
$(this).parent(".add1").remove();
});
});
$('#package').change(function() {
var arr = [];
$("input.packageclass").each(function() {
arr.push($(this).val());
alert(arr);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<div class="add1">
<h6>Sales Package </h6>
<div>
<input type="text" name="package" placeholder="Ex:34" id="package" class="packageclass">
<input type="submit" value="+" class="add"></div>
</div>
$('.package').change(function() {
You are using an ID in your input type="text". IDs are only used once. If you want to add the listener to all of your textfields use classes.
In addition to that the .change(function() is only once called, when the dom is ready. That will be a problem too. So the change listener is not added to the generated textfields. Maybe you use something like...
$('.package').on('change', 'input', function() {
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<div class="add1">
<h6>Sales Package </h6>
<div>
<input type="text" name="package" placeholder="Ex:34" id="package" class="packageclass">
<input type="submit" value="+" class="add">
</div>
</div>
<script type="text/javascript">
var addInput = function(e) {
var arr = [];
$("input.packageclass").each(function() {
arr.push($(this).val());
});
alert(arr);
};
$(document).ready(function() {
$(document).on("click", ".add", function() {
var clone = '<div class="add1"><input class="packageclass" type="text" name="selprice" /><input type = "submit" value = "+" class = "add" ><input type = "submit" value = "-" class = "remove" ></div>';
$(this).closest('.add1').after(clone);
$('.packageclass').unbind().bind('change', addInput);
});
$(document).on("click", ".remove", function() {
$(this).parent(".add1").remove();
});
});
$('.packageclass').unbind().bind('change', addInput);
</script>
Just using loop you can get the particular value from loop.
for (var i = arr.length - 1; i >= 0; i--) {
arr[i];
//work with arr[]
}
I have used event delegation to capture the events and take appropriate action.
In this, you can add a event listener to your parent element i.e., click to the .body in my case. When I click on the .add button, the event propagates and .body click handler gets invoked. By checking for event.target we can find out the origin of event and add or remove the divs.
Similary we can listen for the change event of the input boxes and take appropriate actions.
$('#body').click(function(e) {
if(e.target.className === 'add') {
$('#body').append(`
<div class="add1">
<input type="text" name="package" placeholder="Ex:34" id="package" class="packageclass">
<button class="add">+</button>
<button class="remove">-</button>
</div>
`);
}
if(e.target.className === 'remove') {
$(e.target).parent().empty();
}
});
$('#body').change(function(e) {
console.log(e.target.value);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<div id="body">
<h6>Sales Package </h6>
<div class="add1">
<input type="text" name="package" placeholder="Ex:34" id="package" class="packageclass">
<button class="add">+</button>
</div>
</div>
Just add class="packageclass" to the input when creating your clone variable.
https://jsfiddle.net/289xvmu7/
var clone = '<div class="add1"><input type="text" name="selprice" class="packageclass"/> <input type = "submit" value = "+" class = "add" ><input type = "submit" value = "-" class = "remove" ></div>';

Polymer update datalist

I'm making a polymer element with some requirements. I've a list (ul) and two input fields. I need that one of the inputs update my list (there's no problem here). The other input should be able to define some default values for the first input, here I'm using a datalist.
I wrapped all in a polymer element. That's when I started having problems. I'm trying to update the datalist inside the polymer element, the datalist is updated but the input doesn't show the new hints.
Also, I've noticed that if I have more than one of these elements all the input binds with the datalist of the first element. I don't understand this behaviour. Each element must bind to the list inside her scope.
One more thing that I need to figure out is how can I delete some of default values added.
Here is my code:
<dom-module id="test-input" attributes="edit list type">
<template>
<!-- Here I have the first input that creates a list and I need to be binded with a datalist-->
<div id="container">
<div id="display" on-click="_openEdit">
<div id="textDescription" class="textDescription">{{description}}</div>
<ul id="list" class="list"></ul>
<form id="addContainer" class="addContainer" action="#" method="post">
<label for="newitem">{{label}}</label>
<!--<input type="text" name="newitem" id="newitem" placeholder="{{placeholder}}" required>-->
<input list="defaultValues" name="newitem" id="newitem" placeholder="{{placeholder}}" required>
<!-- I've added this options so we can see that it's working but when the datalist is updated it doesn't show-->
<datalist id="defaultValues">
<option value="option added on html"></option>
<option value="option added on html 2"></option>
</datalist>
<input type="submit" id="addToList" value={{buttonText}}>
</form>
</div>
<!-- Here I have the second input that updates the datalist default values-->
<div id="edit">
<div id="extendedList">
<div>Enter the default values</div>
<form id="extendedAddContainer" class="addContainer" action="#" method="post">
<label for="extendedNewitem">{{label}}</label>
<input type="text" name="extendedNewitem" id="extendedNewitem"
placeholder="enter default values" required>
<input type="submit" id="extendedAddToList" value={{buttonText}}>
</form>
</div>
</div>
</div>
</template>
<script>
defaultValueCounter = 0;
function isEmpty(str) {
return !str.replace(/^\s+/g, '').length; // boolean (`true` if field is empty)
}
Polymer({
is: "test-input",
properties: {
buttonText: {
type: String,
value: "Add"
}
},
ready: function () {
/* Start: add input to list */
var list = this.$.list,
field = this.$.newitem,
form = this.$.addContainer;
form.addEventListener('submit', function (ev) {
if (field.validity.valid && !isEmpty(field.value)) {
list.innerHTML += '<li class="style-scope list-input">' + field.value + '</li>';
field.value = '';
field.focus();
ev.preventDefault();
}
}, false);
list.addEventListener('click', function (ev) {
var t = ev.target;
if (t.tagName === 'LI') {
t.parentNode.removeChild(t);
}
ev.preventDefault();
}, false);
/* End: add input to list */
/* Start: Add default values */
var extendedList = this.$.defaultValues,
extendedField = this.$.extendedNewitem,
extendedForm = this.$.extendedAddContainer,
container = this.$.extendedList,
defaultList = this.$.defaultList;
extendedForm.addEventListener('submit', function (ev) {
ev.preventDefault();
/* Here I add things to the datalist */
if (extendedField.validity.valid && !isEmpty(extendedField.value)) {
aux = document.createElement("option");
aux.value = extendedField.value;
extendedList.appendChild(aux);
extendedField.value = '';
extendedField.focus();
}
}, false);
}
/* End: Add default values */
});
</script>
</dom-module>
Thanks in advance!

How do I add up values of buttons in jquery

I'm trying to sum up values of buttons if the buttons are clicked on. For example, there is "Button1". If this button is clicked, it should add its value to a sum which will be displayed at the bottom of the page. If "Button1" is clicked a second time it should substract its value from the sum.
Here is my attempt to do this but it's not doing anything at all:
var value_Buttons = 0;
var total = 0;
$("button[name=Button1],[name=Button2],[name=Button3],[name=Button4],[name=Button5],[name=Button6]").click(function() {
if($(this).hasClass('active') == false) {
value_Buttons += parseInt($(this).val());
} else if($(this).hasClass('active') == true) {
value_Buttons -= parseInt($(this).val());
}
total += value_Buttons;
alert(total);
});
total = value_Buttons + value_Optional_Button;
$("input[name=value_sum]").val(total);
Additionally, here is the code for an examplary button (Like "Button1"):
<div class="form-group col-md-2">
<button type="button" class="form-control btn btn-primary" name="Button1" value="300" title="300 €" data-toggle="button" aria-pressed="false" autocomplete="off">Button 1</button>
</div>
There will be more buttons, but they will only differ in their name and value.
Also, the box which will display the sum of the button-values currently looks like this:
<div>
<label class="control-label">Sum</label>
<div class="input-group">
<input class="form-control" name="value_sum" style="text-align:right" id="costs" value="" type="text" readonly>
<span class="input-group-addon">€</span>
</div>
</div>
I've searched all over Stackoverflow, as well as via Google, etc. yet I can't find anything or anyone with a similar problem
Blocking JS logic error is here :
$("input[name=value_sum]").val(total);
this line should be in the above code block. Added corrections for substraction :
var total = 0;
$("button[name]").on("click", function() {
if(!$(this).hasClass('active')) {
total += Number($(this).val());
$(this).addClass('active').html("remove " + $(this).attr("title"));
} else {
total -= Number($(this).val());
$(this).removeClass('active').html("add " + $(this).attr("title"));
}
$("input[name=value_sum]").val(total);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="form-group col-md-2">
<button type="button" class="form-control btn btn-primary" name="Button300" value="300" title="300 €" data-toggle="button" aria-pressed="false" autocomplete="off">add 300 €</button>
<button type="button" class="form-control btn btn-primary" name="Button600" value="600" title="600 €" data-toggle="button" aria-pressed="false" autocomplete="off">add 600 €</button>
</div>
<div>
<label class="control-label">Sum</label>
<div class="input-group">
<input class="form-control" name="value_sum" style="text-align:right" id="costs" value="0" type="text" readonly>
<span class="input-group-addon">€</span>
</div>
</div>
Lines 14 and 15 need to be placed within the click event of the button to update the value_sum input on every click. Also your selection for the value attribute it a little bit off. The way to return the value attribute of a button using jQuery is:
$(this).attr('value');
So after these two points, stripping your code of the if and else check, and also selecting the buttons with a cleaner method, you should have something like this:
var total = 0;
$("button[name=Button1], button[name=Button2], button[name=Button3], button[name=Button4], button[name=Button5], button[name=Button6]").click(function() {
total += $(this).attr('value');
$("input[name=value_sum]").val(total);
});
To display the total, that is 0, in the input element on page load, you could use:
<input class="form-control" name="value_sum" style="text-align:right" id="costs" value="0" type="text" readonly>
start off by create a listener for a class that will be applied to all of your buttons.
$(.btn).click(function() {
//get value
var value = parseint($(this).attr("value"));
//check if already clicked
if($(this).hasClass('active') {
//set value of total
total = total - value;
//remove class active
$(this).removeClass('active');
}else {
//set value of total
total = total + value;
//addclass active
$(this).addClass('active');
}
)};
Is this what you need?
Working Demo
Here have added a classname 'add' for all buttons , on click its toggle class add, sub in you case you using active,inactive class
var total = 0;
$("button[name=button1],[name=button2],[name=button3]").on('click', function () {
var self = $(this);
var gValue = Number(self.val());
if (self.hasClass("add")) {
total += gValue;
self.removeClass("add").addClass("sub");
} else {
total -= gValue;
self.removeClass("sub").addClass("add");
}
$("#costs").val(total);
});
Check this fiddle.
Add as many buttons as you like, the only thing is that you'll have to add a data-value to them to figure out how much to add or substract. I would also do the search for buttons using a class instead of "button" but that's up to you.
var buttons = {};
$("button").each(function (index, item) {
buttons[index] = 0;
$(item).click(function () {
var value = +($(item).data("value")),
val = +($("#costs").val());
val += (!buttons[index]) ? value : -value;
buttons[index] = (!buttons[index]) ? 1: 0;
$("#costs").val(val);
});
});
Hope it helps.

jQuery add ID increment to .html() appending on input onchange and refresh onchange value

I apologize for the wordy title but I haven't found a solution to my problem yet. I am a newbie with jQuery and web development so any guidance would be appreciated.
I have a <input> that allows user to enter a value (number) of how many rows of a set of input fields they want populated. Here's my example:
<div id="form">
<input id="num" name="num" type="text" />
</div>
<p> </p>
<div id="form2">
<form action="" method="post" class="form_main">
<div class="data">
<div class="item">
<input id="name" name="name[]" type="text" placeholder="name" /><br/>
<input id="age" name="age[]" type="text" placeholder="age" /><br/>
<input id="city" name="city[]" type="text" placeholder="city" /><br/>
<hr />
</div>
</div>
<button type="submit" name="submit">Submit</button>
</form>
My jQuery:
<script>
var itemNum = 1;
$("#num").on("change", function() {
var count = this.value;
var item = $(".item").parent().html();
//item.attr('id', 'item' + itemNum);
for(var i = 2; i <= count; i++) {
itemNum++;
$(".data").append(item);
}
})
</script>
I'm having problems adding an ID item+itemNum increment to <div class="item">... item.attr() didn't work. It doesn't append once I added that line of code.
Also, how can I get it so that once a user enters a number that populates rows of input fields, that if they change that number it will populate that exact number instead of adding to the already populated rows? Sorry if this doesn't make any sense. Please help!
Here is a DEMO
var itemNum = 1;
$("#num").on("change", function() {
$('.data div').slice(1).remove(); //code for removing previously populated elements.
var count = this.value;
console.log(count);
var item;
//item.attr('id', 'item' + itemNum);
var i;
for(i = 1; i <= count; i++) {
console.log(i);
item = $("#item0").clone().attr('id','item'+itemNum);
//prevent duplicated ID's
item.children('input[name="name[]"]').attr('id','name'+itemNum);
item.children('input[name="age[]"]').attr('id','age'+itemNum);
item.children('input[name="city[]"]').attr('id','city'+itemNum);
itemNum++;
$(".data").append(item);
}
})
Use clone() instead of html()
Try
var itemNum = 1,
item = $(".data .item").parent().html();;
$("#num").on("change", function () {
var count = +this.value;
if (itemNum < count) {
while (itemNum < count) {
itemNum++;
$(item).attr('id', 'item' + itemNum).appendTo('.data')
}
} else {
itemNum = count < 1 ? 1 : count;
$('.data .item').slice(itemNum).remove();
}
})
Demo: Fiddle

Categories