Solved

for loop not incrementing

Posted on 2013-01-21
17
393 Views
Last Modified: 2013-01-21
I have  a table in which I'm having jQuery add a table row each time the 'Add Row' button is pushed.

If my loop looks like "for(x=0; $x<1; ++$x)" the addRow does not work...if my loop looks like "for(x=1; $x < 2; ++$x)", then the program adds a row but does not actually increment x with each row addition.


	case "distributions":

	$poNumber = safeData($_GET['poNum']);
	
	echo '<span class="sectitleblk">Creating Header Distributions for PO # ' . $poNumber . ' for '. ucwords(strtolower(getVendorName($vendorid))) . '</span><br /><br />';
	
	if (isset($Errors)) 
		{
		echo "<div align='center'><span class='errormessagered'><ul class='errors'>";
		foreach ($Errors as $Error) 
			{
			echo "<li>".$Error."</li>";
			}
		echo "</ul></span></div><br />";
		}
	
	?>
	<form id="createDistribution" name="createDistribution" method="POST" enctype="multipart/form-data" action="<?=$_SERVER['PHP_SELF']?>?kdaccount=<?=$vendorid?>&action=poinfo">
		<input type="hidden" name="vendoracct" value = "<?=$vendorid?>">
		<div id="container" class="shadow">
			<div id="row">
				<div id="left">
					<strong>Description:</strong>
				</div>
				<div id="defaultdiv">
					<div id="right">
						<input type="text" class="fieldclasssm" name="linedescr[]" value = "<? if (!empty($_POST['custRef'])) { echo "value='".safeData($_POST['custRef'])."'"; }?>" size="113" />
					</div>
				</div>
			</div>
			<div id="row">
				<div id="left">
					<strong>Distributions:</strong>
				</div>
				<div id="defaultdiv">
					<div id="right">
						<table border="1" class="lineTbl">
							<thead>
							<tr>
								<th>Qty</th>
								<th>nominal #</th>
								<th>depot<font color='red'>*</font></th>
								<th>amount<font color='red'>*</font></th>
								<th><input type="button" value="Add Line" class="add"/></th>
							</tr>
							</thead>
							<tbody class="lineBdy">
							<?php for ($x=0; $x<1; ++$x) { 
							echo "<tr id='line_".$x."' class='lineRow'>";
							?>				
								<td><?php echo $x; ?> &nbsp;<input type="text" class="serial" name="qty[]" size="10" /></td>
								<td><input type="text" class="date start" name="nominal[]" size="10" /></td>
								<td><input type="text" class="date end" name="depot[]" size="10" /></td>
								<td><input type="text" class="credit_amt" name="amount[]" size="10" /></td>
								<!-- <td align="center"><img src="./img/close.png" class="delRow" border="0"></td> -->
							</tr>				
							<?php 

							} ?>
							</tbody>
							<tr>
								<td colspan='5' align='right'>Total: $ <span id="grandtotal"></span><br /><font color='red'>(*)</font> Column names with asterisks are required. </td>
							</tr>
						</table>
					</div>
				</div>
			</div>
		</div>
	</form>
<?php
	break;
	}
?>

<link rel="stylesheet" type="text/css" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.9.2/themes/base/jquery-ui.css" />
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.9.2/jquery-ui.min.js"></script>
<script type="text/javascript">
$(function () { 
    $("#usedefaultbill").click(function () {
        $("#newdivbill").hide();
     });
    $("#usealternatebill").click(function () {
        $("#newdivbill").show();
    });
	
    $("#usedefaultship").click(function () {
        $("#newdivship").hide();
     });
    $("#usealternateship").click(function () {
        $("#newdivship").show();
    });
	
$("#poType").change(function(){

$("#showcustref").hide();

 var chosenValue = $("#poType").val();
if (chosenValue == "5" || chosenValue == "3" ) 
  
  {
    $("#showcustref").show();

}
  
});
	
	$("#compname").autocomplete({
		source: "autocomplete.php",
		minLength: 3,
		select: function(event, ui) {
			event.preventDefault();
			$("#compid").val(ui.item.id);
			$("#compname").val(ui.item.label);
			$(':text[name=shipCompName]').val(ui.item.label);
			$(':text[name=shipAddress]').val(ui.item.address);
			$(':text[name=shipCity]').val(ui.item.town);
			$(':text[name=shipState]').val(ui.item.state);
			$(':text[name=shipZip]').val(ui.item.postcode);
		}
	});
		
$("#compid").change( function () {
  $("#submit").trigger('click');
}); 

					// Add new table rows
					$(function() {
						var lineCnt = 1;
						
						$(".add").click(function(){					
							$("#line_1").clone(false).attr('id', 'line_'+lineCnt+'').appendTo(".lineBdy");
							$('#line_'+lineCnt+'').find('.serial, .credit_amt').val('');
							lineCnt++;
							$(".date").datepicker();
							$(".credit_amt").unbind().formatCurrency({ colorize: true, negativeFormat: '-%s%n', roundToDecimalPlace: 2 });
						});
						
					});

					
});
</script>

Open in new window

0
Comment
Question by:t3chguy
  • 6
  • 4
  • 4
  • +2
17 Comments
 
LVL 9

Expert Comment

by:user_n
ID: 38801856
for(x=0; $x<1; ++$x)
Is executed only one time for x= 0. And i think that it should be
for($x=0; $x<1; ++$x)

for(x=1; $x < 2; ++$x) I suppose that by default the value of $x is 0. You do not give it a value by x= 1, you should write $x = 1. So first time $x is 0 and we have one execution of the loop , then $x is 2 and the $x>2 so the for loop stops its execution
0
 
LVL 34

Expert Comment

by:Paul MacDonald
ID: 38801867
Correct me if I'm wrong, but in both cases the loop condition will only fire once.

That is in for(x=0; $x<1; ++$x) will x will only be less than 1 the first time through.

In for(x=1; $x < 2; ++$x), x will only be less than 2 the first time through.
0
 
LVL 1

Author Comment

by:t3chguy
ID: 38801875
So then, if I wanted one row to show by default, and have the ability to add unlimited number of rows, what would that sequence be?
0
 
LVL 34

Expert Comment

by:gr8gonzo
ID: 38801878
for(x=
should be:
for($x=
0
 
LVL 34

Expert Comment

by:Paul MacDonald
ID: 38801889
I'm not a PHP person so I'm not authoritative, but in the loop syntax you're using you'd need to know how many rows there are.  There may be a different way to loop through until there's no data to show, but I don't know what that is.
0
 
LVL 9

Expert Comment

by:user_n
ID: 38801903
you can use while loop
while(True) this means that the loop will never end
{
if(end condition) the condition that satisfies your ending condition
   break;
}


http://php.net/manual/en/control-structures.break.php
0
 
LVL 1

Author Comment

by:t3chguy
ID: 38801938
I'm not quite sure I know how to implement that in this case.
0
 
LVL 9

Expert Comment

by:user_n
ID: 38801951
the idea is that while loop will never end
it will end only when break is executed
so you make an endless loop
that is doing what you whant
end you should know what is the condition this loop to end
When this condition is reached the break should be executed and it will stop the execution of while statement at this point
0
3 Use Cases for Connected Systems

Our Dev teams are like yours. They’re continually cranking out code for new features/bugs fixes, testing, deploying, testing some more, responding to production monitoring events and more. It’s complex. So, we thought you’d like to see what’s working for us.

 
LVL 9

Expert Comment

by:user_n
ID: 38801973
What exactly is your goal?
0
 
LVL 1

Author Comment

by:t3chguy
ID: 38801989
Essentially what it's doing is running the loop ONE time, and showing all 10 rows by default, then anything more than ten, the row id, or value of x is just one, which isn't what it should be doing.


What I'm trying to accomplish is showing 1 row first, and then adding a row which each time the 'Add Line' button is pressed and having the row id increment all the way up until I would say 10 rows max.



									$counter = 1;
								WHILE ($counter <= 1) 
										{
										for ($x=0; $x<=10; $x++)
										{ 
										echo "<tr id='line_".$x."' class='lineRow'>";
									?>				
										<td><?php echo $x; ?> &nbsp;<input type="text" class="serial" name="qty[]" size="10" /></td>
										<td><input type="text" class="date start" name="nominal[]" size="10" /></td>
										<td><input type="text" class="date end" name="depot[]" size="10" /></td>
										<td><input type="text" class="credit_amt" name="amount[]" size="10" /></td>
										<!-- <td align="center"><img src="./img/close.png" class="delRow" border="0"></td> -->
									</tr>				
									<?php 

									} $counter++;} ?>

Open in new window

0
 
LVL 40

Expert Comment

by:RQuadling
ID: 38801991
Do you know how many times you should execute the loop?

foreach(range(1, $i_Count) as $x) { ... }

Open in new window

for($x = 0; $x < $i_Count; ++$x) { ... }

Open in new window

$x = 0;
while ($x < $i_Count) {
  ++$x;
}

Open in new window


All provide the same sort of functionality.
0
 
LVL 1

Author Comment

by:t3chguy
ID: 38801999
I would think a max of 10 times would be best.
0
 
LVL 40

Expert Comment

by:RQuadling
ID: 38802086
I would also STRONGLY recommend that you put the index in the <input> tags name.

Think of it as defensive programming.

e.g.

<?php
foreach(range(0, 9) as $i_Index)
 {
 echo <<< END_TR
<tr id="line_{$i_Index}" class="lineRow">
  <td>{$i_Index} &nbsp;<input type="text" class="serial" name="qty[{$i_Index}]" size="10" /></td>
  <td><input type="text" class="date start" name="nominal[{$i_Index}]" size="10" /></td>
  <td><input type="text" class="date end" name="depot[{$i_Index}]" size="10" /></td>
  <td><input type="text" class="credit_amt" name="amount[{$i_Index}]" size="10" /></td>
  <!-- <td align="center"><img src="./img/close.png" class="delRow" border="0"></td> -->
</tr>				
END_TR;
 }

Open in new window

0
 
LVL 1

Author Comment

by:t3chguy
ID: 38802223
RQuadling,

That still displays all 10 rows on load, I was hoping to have one row load by default , and have the 'Add Row' button display a new row each time the button is pressed, for a maximum of 10 rows.
0
 
LVL 40

Expert Comment

by:RQuadling
ID: 38802363
I would think about using jQuery to add a new row to the form, rather than round tripping it to the server.
If you want a button, then maybe the button is a submit button and in your PHP code, you increment ++$_SESSION['RequiredRows']; and use that as the upper limit to your range?
0
 
LVL 1

Author Comment

by:t3chguy
ID: 38802386
I actually think I've got it down...

	<tr> 
		<td>
			<input type="text" id="quantity_1" name="quantity_1" class="fieldclasssm" size="5" />
		</td> 
		<td> 
			<input type="text" id="nominal_1" name="nominal_1" class="fieldclasssm" size="35" /> 
		</td> 
		<td> 
			<input type="text" id="depot_1" name="depot_1" class="fieldclasssm" size="35" /> 
		</td> 
		<td> 
			<input type="text" id="amount_1" name="amount_1" class="fieldclasssm" size="10" /> 
		</td> 
		<td><input type="button" id="addnew" name="addnew" value="Add Distribution" /> </td>
	</tr> 

Open in new window


jQuery:

		var currentItem = 1;
		$('#addnew').click(function(){
			currentItem++;
			$('#items').val(currentItem);
			var strToAdd = '<tr><td><input type="text" id="quantity_'+currentItem+'" name="quantity_'+currentItem+'" class="fieldclasssm" size="5" /></td><td><input type="text" id="nominal_'+currentItem+'" name="nominal_'+currentItem+'" class="fieldclasssm" size="35" /></td><td><input type="text" id="depot_'+currentItem+'" name="depot_'+currentItem+'" class="fieldclasssm" size="35" /></td><td><input type="text" id="amount_'+currentItem+'" name="amount_'+currentItem+'" class="fieldclasssm" size="10" /></td></tr>';
			$('#distributions').append(strToAdd);
			
		});

Open in new window

0
 
LVL 40

Accepted Solution

by:
RQuadling earned 500 total points
ID: 38802508
I would use
'<tr><td><input type="text" id="quantity['+currentItem+']" name="quantity_'+currentItem+'" class="fieldclasssm" size="5" />';

Open in new window


as this will translate nicely in PHP to an array $_POST['quantity'][n], where n is the index.

Otherwise you have $_POST['quantity_n'] and have to hunt for every entry.

And you can go further ...

'<tr><td><input type="text" id="rows['+currentItem+'][quantity]" name="quantity_'+currentItem+'" class="fieldclasssm" size="5" />';

Open in new window


Now you can iterate $_POST['rows'] and each 'row' will have a 'quantity'. This now looks like a result set from an SQL query.

So, names are currently "quantity_n" => "quantity[n]" => "rows[n][quantity]"

I hope that makes some sense.
0

Featured Post

3 Use Cases for Connected Systems

Our Dev teams are like yours. They’re continually cranking out code for new features/bugs fixes, testing, deploying, testing some more, responding to production monitoring events and more. It’s complex. So, we thought you’d like to see what’s working for us.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction Knockoutjs (Knockout) is a JavaScript framework (Model View ViewModel or MVVM framework).   The main ideology behind Knockout is to control from JavaScript how a page looks whilst creating an engaging user experience in the least …
I found this questions asking how to do this in many different forums, so I will describe here how to implement a solution using PHP and AJAX. The logical flow for the problem should be: Write an event handler for the first drop down box to get …
This tutorial will teach you the core code needed to finalize the addition of a watermark to your image. The viewer will use a small PHP class to learn and create a watermark.
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…

864 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

23 Experts available now in Live!

Get 1:1 Help Now