Solved

Looop through JQuery by concatenating variables

Posted on 2013-12-12
18
249 Views
Last Modified: 2013-12-13
I'm using JQuery to automatically add up fields as the user inputs numbers.  It works fine with a set number of fields.  But the application will get the fields from a database, so the number of fields will vary each time.

It's very rough, but here's the page...
http://buildmomentum.org/register/lc/group_payment.php?id_church=ORG101

The fields are created by looping through the database.

You'll see that the first 4 fields work, but the remaining don't.

I'm trying to convert some JQuery code so that it loops to create the variables.

I've managed to insert the variable 'x' into the parseFloat statement so I can get that to change each loop -   parseFloat($('#id_amount'+x)

But how do I get - var firstValue - to change?  I've tried every way I can think of...

var first + x
var first[x]
var first$x
etc.

Any ideas or should I apply a different logic to the problem?
<code>
<script>
$(document).ready(function(){
$('input').keyup(function(){ // run anytime the value changes
x=1

for (var x = 0, limit = 2; x < limit; x++) {
console.log( "Currently at " + x );

var firstValue = parseFloat($('#id_amount'+x).val()) || 0; // get value of field

<!--these are hardcoded for now, but need to be in the loop-->
var secondValue = parseFloat($('#id_amount2').val()) || 0; // convert it to a float
var thirdValue = parseFloat($('#id_amount3').val()) || 0;
var fourthValue = parseFloat($('#id_amount4').val()) || 0;
    
<!--this needs to loop as well since the number of records will vary-->
var total = firstValue + secondValue + thirdValue + fourthValue; // add them together

$('#added').html(total); // output it
}
});
});
</script>
</code>

Open in new window

0
Comment
Question by:stkoontz
  • 7
  • 6
  • 4
  • +1
18 Comments
 
LVL 38

Expert Comment

by:Tom Beck
ID: 39713929
My understanding is that you are trying to get the values entered in a series of inputs and add them together. Something like this perhaps?

var total = 0;
$("input[name^='amount_entered']").each(function(i) {
     total += parseFloat($(this).val());
});

Or this:

var total = 0;
$("input[id^='id_amount']").each(function(i) {
     total += parseFloat($(this).val());
});
0
 
LVL 2

Author Comment

by:stkoontz
ID: 39713939
Thanks for jumping it to help.  I appreciate it.

I'm new to jquery and haven't done much in Javascript either.  Would you let me know how this code would fit with my code?  What would it replace?

Thanks,

Steve
0
 
LVL 38

Expert Comment

by:Tom Beck
ID: 39713948
$(document).ready(function(){
$('input').keyup(function(){ // run anytime the value changes

    var total = 0;
    $("input[id^='id_amount']").each(function(i) {
          total += parseFloat($(this).val());
    });

    $('#added').html(total); // output it
});
});

Open in new window

0
 
LVL 38

Expert Comment

by:Tom Beck
ID: 39713974
Of course, you would probably want to test for empty inputs and non-numerical inputs before attempting to add the values.

var total = 0;
    $("input[id^='id_amount']").each(function(i) {
            if ($(this).val() !== "" && !(isNaN($(this).val()))) {
                      total += parseFloat($(this).val());
            }
    });
0
 
LVL 52

Expert Comment

by:Scott Fell, EE MVE
ID: 39713982
Just change your input's to a class.  No need for id's in this case.  Instead, just target a class which can be the same name.  See this simplified sample.
http://jsbin.com/OLiGEcA/1/edit?html,js,output
var total=0;
$('input.amount').each(function(){
  var amt=0;
  if ($(this).val()>0){
   amt=$(this).val();
  }
   total=total+parseInt(amt,10);
});
$('td.total').text(total);

Open in new window


<!DOCTYPE html>
<html>
<head>
<script src="http://code.jquery.com/jquery-latest.js"></script>
<meta charset=utf-8 />
<title>JS Bin</title>
</head>
<body>
<table>
  <tr><td><input class="amount" ></td><td>abc</td></tr>
  <tr><td><input class="amount"></td><td>123</td></tr>
  <tr><td><input class="amount" ></td><td>xyz</td></tr>
  <tr><td class="total"></td><td>total</td></tr>
  </table>  
</body>
</html>

Open in new window

0
 
LVL 52

Expert Comment

by:Scott Fell, EE MVE
ID: 39713986
For jquery,  use either 1.1x or 2.x.  The 1.1x will support older IE where the 2.x does not and is lighter weight.  If you are not sure, use the 1.1x.
0
 
LVL 2

Author Comment

by:stkoontz
ID: 39715214
Thanks for both of you trying to help, but neither solution worked.

If I can put a variable that increments in place of [variable] below, I could get it to work.

var Value[variable] = parseFloat($('#id_amount'+i).val()) || 0;

Is that possible?

Steve
0
 
LVL 38

Expert Comment

by:Tom Beck
ID: 39715332
When you say neither solution worked, can you elaborate? Can you post your latest code that attempts to implement the solutions provided?

If the inputs are being dynamically generated with incrementing ids, then it has to work.
0
 
LVL 52

Expert Comment

by:Scott Fell, EE MVE
ID: 39715351
I realized my code will not work as is.   It needs to be wrapped in a blur or click function of some sort.  

But I am confused looking at your sample.  http://buildmomentum.org/register/lc/group_payment.php?id_church=ORG101

Do you mean for the amounts to be input fields or do you want to add up the leftmost td's?
0
Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

 
LVL 42

Expert Comment

by:Chris Stanyon
ID: 39715438
You are trying to load jQuery version 1.1 from the Google CDN - the oldest version they have is 1.2.3, so you're getting a 404 error and jQuery is never loaded. Change your code to include a newer library:

<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>

Open in new window

0
 
LVL 38

Expert Comment

by:Tom Beck
ID: 39715593
This question has gotten messy. The code I provided in post ID: 39713948 was a working solution except that there was no test for blank inputs or non-numerical inputs. I added that in post ID: 39713974. But I see now from the link that the onkeyup wrapper in the 39713948 code got lost somehow. That plus loading the wrong jQuery library are the reasons the page does not work.

When I answered the question originally, I copied the entire view source from the link and created a local copy. I still have it. It included this jQuery library: <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.0/jquery.min.js"></script>. How it went from 1.7.0 to 1.1.0 is a mystery to me, but that prompted Chris's input. I never suggested a change to the library version. I also did not suggest a change in the markup from using ids to using classes. That was @padas.

So please @stkoontz, how would you like to proceed here? Do you want to:
1.) change your markup to include classes in the inputs instead of ids?
2.) add the onkeyup wrapper back in and keep the ids and my code suggestion?
3.) continue to insist on trying to concatenate id_amount with a variable?
0
 
LVL 38

Accepted Solution

by:
Tom Beck earned 400 total points
ID: 39715612
This is your original posted page. I did not change anything except the script at the end. That part works.
<!DOCTYPE html>
<html lang="en" class="no-js">
<head>

<meta charset=utf-8>
<title>Momentum Lead Contacts</title>
<link rel="stylesheet" href="styles.css" media="all">

<script type="text/javascript" src="http://ajax.googleapis.com/
ajax/libs/jquery/1.7.0/jquery.min.js"></script>
<script type="text/javascript" src="script.js"></script>

</head>

<body>
  <!--<label for="turnover">Turnover</label>
<input type="text" id="id_turnover"/>

<label for="invoiced">Invoiced</label>
<input type="text" id="id_invoiced"/>

<label for="collected">Collected</label>
<input type="text" id="id_collected"/>
-->

<div id="container">Total <span style="clear:both;" id="added"></span><br></div>

<!--<div id="container2">Total + random field<span style="clear:both;" id="added2"></span><br></div>-->
Group payment form.
<form action="group_payment_submit.php" method="post" id="submit">
	<table>
    <tr>
        <td>Last Name</td>
        <td>First Name</td>
        <td>Registrant ID</td>
        <td>Balance</td>
        <td>Today's Payment Amount</td>
    </tr>
        <tr>
      <td>400.00</td>
      <td><input type="text" name="amount_entered[asdf31848]" id="id_amount1"></td>
      <td><input type="text" name="fname" value="asdf" /></td>
      <td></td>
      <td></td>
       
        </td>
        

        </tr>
                <tr>
      <td>375.00</td>
      <td><input type="text" name="amount_entered[asdf63700]" id="id_amount2"></td>
      <td><input type="text" name="fname" value="asdf" /></td>
      <td></td>
      <td></td>
       
        </td>
        

        </tr>
                <tr>
      <td>200.00</td>
      <td><input type="text" name="amount_entered[asdf9892]" id="id_amount3"></td>
      <td><input type="text" name="fname" value="asdf" /></td>
      <td></td>
      <td></td>
       
        </td>
        

        </tr>
                <tr>
      <td>0.00</td>
      <td><input type="text" name="amount_entered[koontz456456]" id="id_amount4"></td>
      <td><input type="text" name="fname" value="steve" /></td>
      <td></td>
      <td></td>
       
        </td>
        

        </tr>
                <tr>
      <td>0.00</td>
      <td><input type="text" name="amount_entered[Koontzie10493]" id="id_amount5"></td>
      <td><input type="text" name="fname" value="steve" /></td>
      <td></td>
      <td></td>
       
        </td>
        

        </tr>
                <tr>
      <td>325.00</td>
      <td><input type="text" name="amount_entered[Koontzie10781]" id="id_amount6"></td>
      <td><input type="text" name="fname" value="steve" /></td>
      <td></td>
      <td></td>
       
        </td>
        

        </tr>
                <tr>
      <td>400.00</td>
      <td><input type="text" name="amount_entered[Koontzie75661]" id="id_amount7"></td>
      <td><input type="text" name="fname" value="steve" /></td>
      <td></td>
      <td></td>
       
        </td>
        

        </tr>
                <tr>
      <td>300.00</td>
      <td><input type="text" name="amount_entered[Koontzie21716]" id="id_amount8"></td>
      <td><input type="text" name="fname" value="steve" /></td>
      <td></td>
      <td></td>
       
        </td>
        

        </tr>
                <tr>
      <td>435.00</td>
      <td><input type="text" name="amount_entered[Koontzie79317]" id="id_amount9"></td>
      <td><input type="text" name="fname" value="steve" /></td>
      <td></td>
      <td></td>
       
        </td>
        

        </tr>
                <tr>
      <td>350.00</td>
      <td><input type="text" name="amount_entered[rank456456]" id="id_amount10"></td>
      <td><input type="text" name="fname" value="Dave" /></td>
      <td></td>
      <td></td>
       
        </td>
        

        </tr>
        <br />
<br />
</table>
<input name="group" type="submit" value="Next" />
</form>

<script>
$(document).ready(function(){
$('input').keyup(function(){ // run anytime the value changes

    var total = 0;
    $("input[id^='id_amount']").each(function(i) {
		if ($(this).val() !== "" && !(isNaN($(this).val()))) {
          total += parseFloat($(this).val());
		}
    });

    $('#added').html(total); // output it
});
});
</script>

<script src="js/general.js"></script>
</body>
</html>

Open in new window

0
 
LVL 2

Author Comment

by:stkoontz
ID: 39716684
I might be in over my head here until I learn more javascript.  I'll answer padas' question first, then look through the code to try to answer TommyBoy's.

Pada's question..

"Do you mean for the amounts to be input fields or do you want to add up the leftmost id's?"

I want the amounts to be input fields.  Here's a link to a cleaned up page, but still with original code.  (I won't change this page as I test code.)

http://buildmomentum.org/register/lc/group_paymentjquery.php?id_church=ORG101

When the user enters a number in the Amount Paid column, it should add up and be displayed next to "Total Paid."  This works for the first 5 names because it's hard-coded.  I need the loop so it can be used on a varying number of names.

Now I'll take a look at TommyBoy's last uploaded code.

Steve
0
 
LVL 2

Author Comment

by:stkoontz
ID: 39716705
@tommyboy:  I dropped in my PHP code to pull the information from the database, keeping your jquery in tact and it's working great.  I'm going to test it some more so I understand what's going on before I close the question.

Thanks!

Steve
0
 
LVL 2

Author Comment

by:stkoontz
ID: 39716757
It's working great, but I can't figure this out...

    $("input[id^='id_amount']").each(function(i) {

How is this line converted to id_amount1, id_amount2, etc so that the amounts are associated with the correct name?  Or maybe I'm just not understanding the logic.

Thanks,

Steve
0
 
LVL 52

Assisted Solution

by:Scott Fell, EE MVE
Scott Fell,  EE MVE earned 100 total points
ID: 39716815
First look at this http://jsbin.com/acUQezUD/1/edit?html,js,output  "looping" in js is not like your serverside language.  The .each http://api.jquery.com/jQuery.each/ is doing the looping where it looks for each input.  Or if your form had the class payments like <form class="payments"> you could change   $('input').each(function () { to   $('form.payments input').each(function () {.  It works very close to how you manage css.

On another note, you will have problems if your coding is off.  The fact you had to use br tags in your form should have clued you to a problem.  Please try and find the issue. Remember that every opening tag needs a closing tag in the same order.  You can check your work by pasting your url or code snippet to a validator http://validator.w3.org/.  Invalid code will make your js scripting much harder then it needs to be.

Learning js/jquery is not going to be an hour crash course.  Plan on spending 3 to 4 hours http://www.codecademy.com/learn to get the basics down and keep practicing.  Taking a half day break to learn will save you a lot of time in the long run.

$('input').change(function () {
    var total = 0;
    $('input').each(function () {
        var paid = $(this).val();
        if (paid > 0) {
            total = parseInt(total, 10) + parseInt(paid, 10);
            $('div#total').html('Total: ' + total);

        }
    });
});

Open in new window

<form action="group_payment_submit.php" method="post" id="submit">
	<table>
    <tr>
        <td>Name</td>
        <td>Amount paid</td>
        <td>&nbsp;</td>
        <td>&nbsp;</td>
        <td>&nbsp;</td>
    </tr>
        <tr>
      <td>Name1</td>
      <td><input type="text" name="amount_entered[asdf63700]" id="id_amount1"></td>
      <td><input type="hidden" name="fname" value="asdf" /></td>
      <td></td>
      <td></td>
       
        </td>
        

        </tr>
                <tr>
      <td>Name10</td>
      <td><input type="text" name="amount_entered[Koontzie21716]" id="id_amount2"></td>
      <td><input type="hidden" name="fname" value="steve" /></td>
      <td></td>
      <td></td>
       
        </td>
        

        </tr>
                <tr>
      <td>Name2</td>
      <td><input type="text" name="amount_entered[asdf31848]" id="id_amount3"></td>
      <td><input type="hidden" name="fname" value="asdf" /></td>
      <td></td>
      <td></td>
       
        </td>
        

        </tr>
                <tr>
      <td>Name3</td>
      <td><input type="text" name="amount_entered[asdf9892]" id="id_amount4"></td>
      <td><input type="hidden" name="fname" value="asdf" /></td>
      <td></td>
      <td></td>
       
        </td>
        

        </tr>
                <tr>
      <td>Name4</td>
      <td><input type="text" name="amount_entered[koontz456456]" id="id_amount5"></td>
      <td><input type="hidden" name="fname" value="steve" /></td>
      <td></td>
      <td></td>
       
        </td>
        

        </tr>
                <tr>
      <td>Name5</td>
      <td><input type="text" name="amount_entered[rank456456]" id="id_amount6"></td>
      <td><input type="hidden" name="fname" value="Dave" /></td>
      <td></td>
      <td></td>
       
        </td>
        

        </tr>
                <tr>
      <td>Name6</td>
      <td><input type="text" name="amount_entered[Koontzie79317]" id="id_amount7"></td>
      <td><input type="hidden" name="fname" value="steve" /></td>
      <td></td>
      <td></td>
       
        </td>
        

        </tr>
                <tr>
      <td>Name7</td>
      <td><input type="text" name="amount_entered[Koontzie75661]" id="id_amount8"></td>
      <td><input type="hidden" name="fname" value="steve" /></td>
      <td></td>
      <td></td>
       
        </td>
        

        </tr>
                <tr>
      <td>Name8</td>
      <td><input type="text" name="amount_entered[Koontzie10781]" id="id_amount9"></td>
      <td><input type="hidden" name="fname" value="steve" /></td>
      <td></td>
      <td></td>
       
        </td>
        

        </tr>
                <tr>
      <td>Name9</td>
      <td><input type="text" name="amount_entered[Koontzie10493]" id="id_amount10"></td>
      <td><input type="hidden" name="fname" value="steve" /></td>
      <td></td>
      <td></td>
       
        </td>
         

        </tr>
 
</table>
<input name="group" type="submit" value="Next" />
</form>
<div id="total"></div>

Open in new window

0
 
LVL 2

Author Closing Comment

by:stkoontz
ID: 39717539
@tommyBoy - thanks for solving the problem with the example code.

@padas - thanks for the extended explanation and HTML tips.  I tweaked the code and ran the validator and the code clears now.
0
 
LVL 38

Expert Comment

by:Tom Beck
ID: 39718288
The author asked me for an explanation of this line of code:

$("input[id^='id_amount']").each(function(i) {

I posted an explanation and you removed it. Clear enough?
0

Featured Post

What Should I Do With This Threat Intelligence?

Are you wondering if you actually need threat intelligence? The answer is yes. We explain the basics for creating useful threat intelligence.

Join & Write a Comment

In this article you'll learn how to use Ajax calls within your CodeIgniter application. To explain this, I'll illustrate how to implement a simple contact form to allow visitors to send you an email through your web site.
This article demonstrates how to create a simple responsive confirmation dialog with Ok and Cancel buttons using HTML, CSS, jQuery and Promises
The viewer will learn the basics of jQuery, including how to invoke it on a web page. Reference your jQuery libraries: (CODE) Include your new external js/jQuery file: (CODE) Write your first lines of code to setup your site for jQuery.: (CODE)
The viewer will learn the basics of jQuery including how to code hide show and toggles. Reference your jQuery libraries: (CODE) Include your new external js/jQuery file: (CODE) Write your first lines of code to setup your site for jQuery…

758 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

22 Experts available now in Live!

Get 1:1 Help Now