inspireddesign Posted March 1, 2010 Share Posted March 1, 2010 Hi guys, I have a small issue that I can't seem to figure out. I have an array that loops through and creates tables every two rows in the array. So if I have four rows of data in the array it will output two tables with two columns. However, if I have 3 rows in the array it will only output 1 table with two rows and not display the last row in the array. Why would this be happening? Thanks for the help. $i=1; foreach($listAI as $ai) { echo $i . ':'; $ai_name .= '<td width="175">' . $ai->ai_name . '</td>'; $ai_nie .= '<td width="175">' . $ai->ai_nie . '</td>'; $ai_address .= '<td width="175">' . $ai->ai_address . '</td>'; $ai_loc .= '<td width="175">' . $ai->ai_city. ' '.$ai->ai_state. ', ' .$ai->ai_zip . '</td>'; if($i==1){ $aiOutput .= '<table width="100%" border="0" cellspacing="0" cellpadding="0" style="font-size:8pt;">'; } if ($i%2==0) { $aiOutput .= '<tr>'. $ai_name . '</tr> <tr>' . $ai_nie .'</tr> <tr>'. $ai_address . '</tr> <tr>' . $ai_loc . '</tr>'; $aiOutput .= '</table><hr />'; $i=0; $ai_name = ''; $ai_nie = ''; $ai_address = ''; $ai_loc = ''; } $i++; } $aiOutput .= '</table>'; Quote Link to comment Share on other sites More sharing options...
schilly Posted March 1, 2010 Share Posted March 1, 2010 because you close off and add the table data every two rows, if you have an odd number of rows the table won't be completed. you need another loop after your main loop to check for this case. $i=1; foreach($listAI as $ai) { echo $i . ':'; $ai_name .= '<td width="175">' . $ai->ai_name . '</td>'; $ai_nie .= '<td width="175">' . $ai->ai_nie . '</td>'; $ai_address .= '<td width="175">' . $ai->ai_address . '</td>'; $ai_loc .= '<td width="175">' . $ai->ai_city. ' '.$ai->ai_state. ', ' .$ai->ai_zip . '</td>'; if($i==1){ $aiOutput .= '<table width="100%" border="0" cellspacing="0" cellpadding="0" style="font-size:8pt;">'; } if ($i%2==0) { $aiOutput .= '<tr>'. $ai_name . '</tr> <tr>' . $ai_nie .'</tr> <tr>'. $ai_address . '</tr> <tr>' . $ai_loc . '</tr>'; $aiOutput .= '</table><hr />'; $i=1; $ai_name = ''; $ai_nie = ''; $ai_address = ''; $ai_loc = ''; } $i++; } while($i %2 != 0){ $aiOutput .= '<tr>'. $ai_name . '</tr> <tr>' . $ai_nie .'</tr> <tr>'. $ai_address . '</tr> <tr>' . $ai_loc . '</tr>'; $i++; } $aiOutput .= '</table>'; Quote Link to comment Share on other sites More sharing options...
ialsoagree Posted March 1, 2010 Share Posted March 1, 2010 I don't think the above suggestion will work. When $i is 3 it won't output the last row, but it'll increment it to 4, and leave the loop. Then you'll get the schilly's loop which will be false on the 1st check (after all, 4%2 == 0) and it'll just skip it. What you SHOULD do, which doesn't require a second loop, is check for your exceptions. Since you ALWAYS add a row, instead check if you need to start the table. You have that with your $i==0, then at the end check if you need to end your table, I've provided some code that I believe should work... $i=1; foreach($listAI as $ai) { echo $i . ':'; $ai_name .= '<td width="175">' . $ai->ai_name . '</td>'; $ai_nie .= '<td width="175">' . $ai->ai_nie . '</td>'; $ai_address .= '<td width="175">' . $ai->ai_address . '</td>'; $ai_loc .= '<td width="175">' . $ai->ai_city. ' '.$ai->ai_state. ', ' .$ai->ai_zip . '</td>'; if($i==1){ $aiOutput .= '<table width="100%" border="0" cellspacing="0" cellpadding="0" style="font-size:8pt;">'; } $aiOutput .= '<tr>'. $ai_name . '</tr> <tr>' . $ai_nie .'</tr> <tr>'. $ai_address . '</tr> <tr>' . $ai_loc . '</tr>'; $ai_name = ''; $ai_nie = ''; $ai_address = ''; $ai_loc = ''; if ($i%2==0) { $aiOutput .= '</table><hr />'; $i=0; } $i++; } $aiOutput .= '</table>'; Quote Link to comment Share on other sites More sharing options...
Psycho Posted March 1, 2010 Share Posted March 1, 2010 Give this a try. Not tested so there may be some syntax or other minor issues: <?php $recordsPerTable = 2; $aiOutput = ''; $tableRecords = array(); function createTable($dataArray, $maxRecords) { $htmlOutput = "<table>\n"; foreach($dataArray as $field => $values) { $htmlOutput .= "<tr>\n"; for ($i=0; $i<$maxRecords; $i++) { $value = (isset($values[$i])) ? $values[$i] : ''; $htmlOutput .= "<td width=\"175\">{$value}</td>\n"; } $htmlOutput .= "</tr>\n"; } $htmlOutput .= "</table>\n"; return $htmlOutput; } foreach($listAI as $ai) { //Add current record data to temp array $tableRecords['name'][] = $ai->ai_name; $tableRecords['nie'][] = $ai->ai_nie; $tableRecords['address'][] = $ai->ai_address; $tableRecords['citystzip'][] = "{$ai->ai_city} {$ai->ai_state}, {$ai->ai_zip}"; if (count($tableRecords)==$recordsPerTable) { //Create output for table and reset array $aiOutput .= createTable($tableRecords, $recordsPerTable); $tableRecords = array(); } } //Output last table if there were uneven records if (count($tableRecords)>0) { $aiOutput .= createTable($tableRecords, $recordsPerTable); } echo $aiOutput; ?> Quote Link to comment Share on other sites More sharing options...
schilly Posted March 1, 2010 Share Posted March 1, 2010 I don't think the above suggestion will work. When $i is 3 it won't output the last row, but it'll increment it to 4, and leave the loop. Then you'll get the schilly's loop which will be false on the 1st check (after all, 4%2 == 0) and it'll just skip it. crap your right. i usually have my counter at the start of the loop so it does work. your code however, isn't exactly what he wants as you only get one column per table. also for even rows you will get a double closing table tag. mjdamato's looks nice though. might have to steal =) Quote Link to comment Share on other sites More sharing options...
Psycho Posted March 1, 2010 Share Posted March 1, 2010 OK, I decided to test my code and found some errors. I created some test data and it seems to work as you are looking for. It is completely customizable as to how many records (columns) you want for each table by setting the $recordsPerTable variable <?php $recordsPerTable = 2; $recordCount = 0; $aiOutput = ''; function resetDataArray() { $dataArray = array(); $dataArray['name'] = array(); $dataArray['nie'] = array(); $dataArray['address'] = array(); $dataArray['citystzip'] = array(); return $dataArray; } function createTable($dataArray, $maxRecords) { $htmlOutput = "<table width=\"100%\" border=\"1\" cellspacing=\"0\" cellpadding=\"0\" style=\"font-size:8pt;\">\n"; foreach($dataArray as $field => $values) { $htmlOutput .= "<tr>\n"; for ($i=0; $i<$maxRecords; $i++) { $value = (isset($values[$i])) ? $values[$i] : ''; $htmlOutput .= "<td width=\"175\">{$value}</td>\n"; } $htmlOutput .= "</tr>\n"; } $htmlOutput .= "</table>\n"; return $htmlOutput; } $tableRecords = resetDataArray(); foreach($listAI as $ai) { $recordCount++; //Add current record data to temp array $tableRecords['name'][] = $ai->ai_name; $tableRecords['nie'][] = $ai->ai_nie; $tableRecords['address'][] = $ai->ai_address; $tableRecords['citystzip'][] = "{$ai->ai_city} {$ai->ai_state}, {$ai->ai_zip}"; if ($recordCount%$recordsPerTable==0) { //Create output for table and reset array $aiOutput .= createTable($tableRecords, $recordsPerTable); $tableRecords = resetDataArray(); } } //Output last table if there were uneven records if ($recordCount%$recordsPerTable>0) { $aiOutput .= createTable($tableRecords, $recordsPerTable); } echo $aiOutput; ?> Quote Link to comment Share on other sites More sharing options...
inspireddesign Posted March 1, 2010 Author Share Posted March 1, 2010 Fantastic! It's doing what I need it to... man you are the best! Wasn't expecting you to write the function for me. Thank you so much mjdamato! Quote Link to comment Share on other sites More sharing options...
Psycho Posted March 1, 2010 Share Posted March 1, 2010 No problem. I misunderstood what you were doing at first and ended up changing gears half way through, so it is not as efficient as it could be. If I were to rewrite it, I would just add all the records to the temp array and then generate the tables in one go from that array. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.