I've got an order form, to which I can append fields by clicking a button. I've got some back end javascript running which totals up the order price, but the grand total script is eluding me.
My problem is that I need the script to seach the entire DOM and find how many have an ID which matches the following pattern.
totprice01
totprice02
totprice03
totprice(n)
I've been playing with this regex, but with not a lot of luck i'm afraid:
matchStr = new RegExp("\\btotprice\\d{2}\\b", "gi");
Once i've got an array of all the HTML IDs I need to pass them into a function which so far looks like this - notice it's all hard coded, not in the least dynamic:
document.getElementById('totpricetot').value = Math.round((parseFloat(document.getElementById('totprice1').value)+parseFloat(document.getElementById('totprice2').value)+parseFloat(document.getElementById('totprice3').value)+parseFloat(document.getElementById('totprice4').value)+parseFloat(document.getElementById('totprice5').value)+parseFloat(document.getElementById('totprice6').value)+parseFloat(document.getElementById('totprice7').value)+parseFloat(document.getElementById('totprice8').value)+parseFloat(document.getElementById('totprice9').value)+parseFloat(document.getElementById('totprice10').value))*100)/100;
Is anyone able to help me put this into expression + function to return the sum of all the values into ?
Thanks a lot!
EDIT
OK I decided to ditch just using plain ol' javascript - JQuery it is! I've put together this code using some of the examples below, but can someone help me debug it I keep get "not defined" errors from the debugger - it appears this function is unavailable to the rest of the DOM?
<input id="totprice08" onChange="totChange()" class="total_field" />
<input id="totprice09" onChange="totChange()" class="total_field" />
<input id="totprice10" onChange="totChange()" class="total_field" />
etc...
<input id="totpricetot" value="0.00" name="totpricetot" />
jQuery(function($) {
function totChange() {
var sum=0;
$('.total_field').each(function() {
sum += $( this ).val () * 1;
} );
$('#totpricetot').val(sum);
}
});
I love it how every javascript question on SO is answered by, "use jQuery"...
Anyways...you can do it with just plain ol' javascript too:
var inputs = document.getElementsByTagName("input");
var priceInputs = [];
for (var i=0, len=inputs.length; i<len; i++) {
if (inputs[i].tagName.indexOf("totprice") > -1) {
priceInputs[priceInputs.length] = parseInt(inputs[i].value);
}
}
calcTotal(priceInputs);
Then just create a function to loop through the array and sum up (:
There are lots of solutions. Besides giving all the elements in question the same class name and use jQuery (or something similar), you could also simply remember the total number of the elements in some JavaScript variable. Would it be possible? I know - it’s kind of an old school solution. You have not indicated that you are using jQuery or any other JavaScript library, so it may be more suitable for you.
Edit: Just to be more explicit:
// your variable, updated every time you add/remove a new field
var fieldsCount;
// whenever you need to do anything with all the fields:
for (var i = 0; i < fieldsCount; i++)
{
var field = document.getElementById("totprice" + i);
// ...
}
Using jQuery, you could select and sum the elements like this:
var sum = 0;
$('[id^=totprice-]').each(function()
{
sum += $(this).val();
});
Give the inputs you need to sum up a class and then get those inputs by that class name (jQuery or some other framework would come in handy here).
if you would use jQuery you could do something like this:
function calculateSum () {
var sum = 0;
$( '.YourClass' ).each ( function () {
sum += $( this ).val () * 1;
} );
return sum;
}
You could give all your total price elements the same CSS class and then get all elements of this class (nice and easy with JQuery).
Give each element a class and use jQuery.
Related
I'm trying to clone a div after a user puts in the amount of divs to be cloned. User will put in a number (say 3) and the function will create three group-container divs. The prompt works, but nothing happens after that. Seems pretty simple but it's evading me. Is my logic incorrect? Obviously my programming skills are very new.
I create a function that has the input (groupInput)
Create a for loop to reiterate the following instruction
The for loop will clone group-container as many times as i<groupInput
function addGroup() {
var groupInput = prompt("How many groups? 1-100");
for(i=0; i<groupInput; i++){
var group = document.getElementById("group-container");
var clone = group.cloneNode(true);
group.parentNode.appendChild(clone);
}
}
Any suggestions would be much appreciated.
Updated
Thanks for the suggestions, I get I should use class for this now.
I did get it to work with the ID in jsfiddle (not sure why it's not in my html), but now with the class it's not: https://jsfiddle.net/waynebunch/c5sw5dxu/. getElementsByClassName is valid right?
You should put the group declaration outside of the for loop so the clone remains the same throughout the loop.
Fiddle
function addGroup() {
var groupInput = prompt("How many groups? 1-100");
var group = document.getElementById("group-container");
for(i=0; i<groupInput; i++){
var clone = group.cloneNode(true);
group.parentNode.appendChild(clone);
}
}
The prompt() method probably returns the correct number, but with type set to String. Instead try
parseInt(groupInput)
To convert the value to a number, which should allow the for loop to execute properly.
Something like the below might work once you get your quantity in from a prompt or text input.
var doc = document;
var input = prompt("Please enter your qty", "0");
if (input != null) {
for (i = 0; i < input; i++) {
var elem = doc.createElement('div');
elem.className = 'group-container';
}
}
I'm currently parsing the first string already and everything works fine:
var links = document.getElementsByTagName("a");
var element;
function search() {
for (var i = 0; i < links.length; i++) {
element = links[i];
var price = parseInt(element);
if (element.href.indexOf("http://www.myurl.com") == 0) {
//program goes here
}
}
}
However, each of the hyperlinks (products) has another string with the price on it (in the same div element). This would look like this:
<span class="price_table_value">
Pricetag:<br>
<span style="color:white">239,--€ </span>
</span>
I would love to somehow parse that too and use parseInt() to make an Integer out of it.
I've thinking about this for a hour and cant find a good solution (im still beginning to learn JS). Any help/ideas?
You can try this one...
function search() {
for (var i = 0; i < links.length; i++) {
element = links[i];
var price =parseInt($(".price_table_value").value);
}
}
Just other example without jQuery:
var priceHolder = Array.prototype.slice.call(document.querySelectorAll(".price_table_value span"));
priceHolder.forEach(function(item) {
var price = /([0-9]+[.0-9]?)/.test(item.innerHTML) ? parseFloat(RegExp.$1) : 0;
console.log(price);
});
Here is working jsfiddle:
http://jsfiddle.net/zono/9gL1vw0e/9/
Try to go with something like in this fiddle?
Basically, this should go in you loop body, but replace the [0] with i, and add the logic you need:
var rawPrice = $(element).children('.price_table_value').children('span').text();
var price = parseFloat(rawPrice);
Of course only do it if you're 100% certain the price format will start with the price value (parseFloat will trim anything trailing the number, just as King Kong noticed). Also, you may want to wrap it around a try/catch block (and best always do it when parsing).
Please note that generally, you probably should be getting such values from some sort of API, not just getting these from DOM elements like this, so please make sure that's what you want to do.
I am trying to teach myself javascript through simple programming ideas. I tasked myself to make a way to calculate two numbers and provide a total of the results by option of using any of the four available operators. It's sort of a very simple calculator, to get to the point. I don't think I need to copy my html code - so I just posted my javascript.
Since I am new to programming in general and javascript, I looked around the web and found some code pointers.
<script>
function add() {
var entry1 = document.getElementById("entry1").value;
var entry2 = document.getElementById("entry2").value;
var sum = Number(entry1)+Number(entry2);
document.getElementById("results").value=sum
}
function sub() {
var entry1 = document.form.entry1.value;
var entry2 = document.form.entry2.value;
var sum = Number(entry1)-Number(entry2);
document.form.results.value=sum
}
function multi() {
var entry1 = document.form.entry1.value;
var entry2 = document.form.entry2.value;
var sum = Number(entry1)*Number(entry2);
document.getElementById("results").value=sum
}
function div() {
var entry1 = document.form.entry1.value;
var entry2 = document.form.entry2.value;
var sum = Number(entry1)/Number(entry2);
document.getElementById("results").value=sum
}
</script>
I think this gives you insight into what I am playing around with. I thought it was interesting I found a way to get around using document.getElementByID, but I guess what I am trying to understand is how you can using both ways...the document.form... and document.getElementById.
Using "document.getElementById" will search the whole DOM looking for "entry1." "Form" in "document.form" refers to the form that encapsulates the whole contents in the <body> tag. As a theory, I did a <div name="blah"> tag in front of <form name="form"> to see if it would use "blah" if I changed document.form to document.blah...it broke. Same thing happened when I tried document.blah.form.entry1....). I think you can see what I am getting at.
I am just curious as to why document.form.entry1.value; works like document.getElementById("entry1").value;?
As others have mentioned,document.getElementById is to be used to select a specific element regardless of what it is. document.forms is to be used to specifically target forms and their elements.
I think document.form points the specific form named or id'ed as the identifier "form" like <form name="form" id="form">.
Please check the syntax document.forms instead of document.<an_identifier> carefully.
document.<an_identifier> may be a dialect of IE.
it's just a kind of syntactic sugar as for me.
Where have you found that "funny" sample? Let me refactor it a bit. hope it will help you better understand to main idea.
<script>
function add(a,b) {
return Number(a) + Number(b);
}
function sub(a,b) {
return Number(a) - Number(b);
}
function multi(a,b) {
return Number(a) * Number(b);
}
function div(a,b) {
return Number(a) / Number(b);
}
function main () { //as an entry point;
var entry1 = document.getElementById('entry1').value,
entry2 = document.getElementById('entry2').value;
$results = document.getElementById("results");
$results.value = add (entry1, entry2);
//$results.value = sub (entry1, entry2);
//$results.value = multi (entry1, entry2);
//$results.value = div (entry1, entry2);
}
</script>
btw: even functions are redundant, but OK I left them as is.
enjoy to JS world
drafting up a quick listing tool to list local kids baseball teams. Takes a couple of inputs and writes to a text field. There's some validation and whatnot too, but that's out of scope and doesn't seem to be impacting things.
Problem is, I'm having trouble figuring out how to "capture" the existing text, add the new inputs and sort the whole lot, before writing the new result to the paragraph element (effectively replacing it).
So far I have:
var LeagueTeams = [];
var IndividualTeam = '';
LeagueTeams.push(document.forms[0].TeamName.value);
LeagueTeams.push(document.getElementById('TeamList')
LeagueTeams = LeagueTeams.sort();
for (j = 0; j < LeagueTeams.length; j++) {
IndividualTeam = LeagueTeams.pop();
IndividualTeam = IndividualTeam + '' + \n;
document.forms[0].TeamName.value += IndividualTeam;
}
What I end up getting is my input, and then an array of my input PLUS the previous contents, with a couple of line breaks. Setting the operator to = instead of =+ stops it from printing to the array at all.
i.e.
Enter: a
Text area: a
Then enter: b
Text area: a ab
(etc)
OK, now that we have a better idea of what you're trying to do, here's some code that will do that:
HTML:
<label>Enter Team Name: <input id="newTeam" type="text"></label>
<button id="add">Add</button><br>
All Teams:<br>
<textarea id="allTeams" rows="40" cols="40"></textarea>
Javascript (plain javascript, no framework, called after page is loaded):
var teamList = ["Dodgers", "Mets", "Giants"];
document.getElementById("add").onclick = function() {
var input = document.getElementById("newTeam");
if (input.value) {
teamList.push(input.value);
}
updateTeamList();
input.value = "";
}
function updateTeamList() {
teamList.sort();
var o = document.getElementById("allTeams");
o.value = teamList.join("\n");
}
updateTeamList();
And, you can see it working here: http://jsfiddle.net/jfriend00/HkhsL/
Comments on your existing code:
I'm not sure I understand what you're trying to do overall, but do you realize that this loop is going to have problems:
for (j = 0; j < LeagueTeams.length; j++) {
IndividualTeam = LeagueTeams.pop();
IndividualTeam = IndividualTeam + '' + \n;
document.forms[0].TeamName.value += IndividualTeam;
}
Each time you do LeagueTeams.pop() you are reducing the length of the array and you're continually comparing to LeagueTeams.length in the for loop. This will only get half way through the array because each time through the loop, you increment j and decrement LeagueTeams.length which means you'll only get half way through the array.
If you intend to iterate all the way through the array in your for loop, you should use this version that gets the length once initially and simplifies the code in the loop:
for (j = 0, len = LeagueTeams.length; j < len; j++) {
document.forms[0].TeamName.value += LeagueTeams.pop() + '\n';
}
or perhaps even better, this version that doesn't even use j:
while (LeagueTeams.length > 0) {
document.forms[0].TeamName.value += LeagueTeams.pop() + '\n';
}
Then further, I see that you're trying to use LeagueTeams.sort() on an array that has both strings in it and DOM object references. What are you trying to do with that sort because the built-in sort function does a lexigraphical sort (e.g. alpha) which will do something odd with a DOM reference (probably sort by whatever toString() returns which may be object type)?
If you want to sort the input by team name, then you would need to put both team name and the DOM reference into an object, insert that object into the array as one unit and then use a custom sort function that would sort by the name in the object. As your code is written above, you see to be using document.getElementById('TeamList') which is the same for all teams so I'm not sure why you're putting it into the array at all.
If you can show your HTML and a more complete version of your code, we could help further. What you have above is just a non-working piece of code and we don't know what your HTML looks like that it's trying to operate on.
FYI, there are several syntax errors in the code you posted, so this can't be running code:
Missing paren at the end of this: LeagueTeams.push(document.getElementById('TeamList'))
Missing quotes around \n: IndividualTeam = IndividualTeam + '' + '\n';
If you are just trying to make a list of the teams, try something like:
<script type="text/javascript">
function addTeam(form) {
var para = document.getElementById('teamList');
var teams = para.innerHTML.split(/<br\s*[\\]?>/);
teams.push(form.teamName.value);
para.innerHTML = teams.sort().join('<br>');
}
</script>
<form action="">
<input type="text" name="teamName">
<input type="button" value="Add team" onclick="addTeam(this.form)">
</form>
<p id="teamList"></p>
You may be using different elements or layout, but the strategy should be about the same. If you are making a set of options for a select, things are a little easier.
How can I use these JavaScript math functions ?
For example, I want to compute the square of all <input> values in a form, without submiting the form.
Can you give a little example? Thank you.
JQuery doesn't need to support math functions as it is an addon library for Javascript, you can still use Javascript in your JQuery code, so you can still use all the native math functions.
Examples:
Addition
var x = 1;
var y = 2;
var lol = x+y;
alert(lol);
Subtraction
var x = 10;
var y = 1;
var lol = x-y;
alert(lol);
Edit: Now we understand your question a little better...
<input type="text" id="field1" value="16" />
<input type="text" id="field2" value="25" />
<input type="text" id="field3" value="36" />
var field1Value = document.getElementById("field1").value;
var field2Value = document.getElementById("field2").value;
var field3Value = document.getElementById("field3").value;
alert(Math.sqrt(field1Value ));
alert(Math.PI * field2Value);
alert(Math.sin(field3Value));
You can act on each individual input using an each()(docs) loop.
Click here to test a working example. (jsFiddle)
$('a.square').click(function() {
$('#myform :text').each(function() {
this.value *= this.value;
});
});
$('a.square_root').click(function() {
$('#myform :text').each(function() {
this.value = Math.sqrt(this.value);
});
});
When either link is clicked, it finds all the text inputs in myform and iterates over them.
Inside the each function, this refers to the current input element.
JavaScript is the programming language, not jQuery, which is a library for web application programming written in JavaScript. To effectively use jQuery, you need to know JavaScript.
It is, however, possible to use jQuery's functionality to easily work with multiple textboxes at once:
// Set each single-line textbox's value to the square
// of its numeric value, if its value is in fact a number.
$('input:text').each(function() {
var num = +this.value;
if(!isNaN(num)) {
this.value = num * num; // or Math.pow(num, 2)
}
});
It would be quite useful if jQuery had a reduce() function.
When dealing with lists of data, most functional languages, and indeed most traditional languages these days, have methods that perform a repetitive function over the entire list, taking each element in turn and applying a function to it.
The simplest of these is map, which jQuery implements for you. This takes a list and applies a function to each element and returns the list of results, one result per entry in the list. eg. [1,2,3] -> (map x2) -> [2,4,6].
Sometimes you want a total or collective result from a list, rather than a list of individual mappings. This is where the reduce (or fold) operation comes in. Unfortunately jQuery does not have this method available as standard, so below is a plugin for it. A reduce function takes an accumulator value and the value of the current element, and returns the modified accumulator, which will be passed on to the next call. eg. [1,2,3,4] -> (reduce + [initial:0]) -> 10 = ( ( ( (0 + 1) + 2 ) + 3 ) + 4 ) or ([1,2,3,4] -> (reduce * [initial:1]) -> 24 = ( ( ( (1 * 1) * 2 ) * 3 ) * 4 ).
(function($) {
$.reduce = function(arr, callback, initial) {
var accumulator = initial || 0;
$.each(arr, function(index, value) {
accumulator = callback(accumulator, value, index);
});
return accumulator;
}
})(jQuery);
Then you can use it like this to get a sum of squares:
var answer = $.reduce($('input:text'), function(acc, elem) {
var cVal = $(elem).val();
return acc + cVal * cVal;
}, 0);
i was looking for a solution too , and i saw a lot of questions here that doesn't work (even this one) in case someone wondering like me , here is my working solutiuon :
$("#apport").keyup(
function(){
var apport = parseFloat($("#apport").val());
var montant = parseFloat($("#montant-financer").val());
var moinmontant = parseFloat(montant) - parseFloat(apport);
$("#montant-financer").val(moinmontant);
}
);
All the id's selector are input
Use the jquery map function to create an array
$('input:text').map(function() {
return this.value * this.value; // math calculation goes here
}).get();
See a live example
Looking at the initial question that was posted, it clearly states compute the square of all values in a form, without submiting the form.
i think keyup would be the best solution.
$("input").keyup(function () {
var value = $(this).val();
var x=value*value;
$("p").text(x);
}).keyup();
Click here to check the working example.
http://jsfiddle.net/informativejavascript/Sfdsj/3/
For more details visit http://informativejavascript.blogspot.nl/