Jump to content

Recommended Posts

I am trying to get my data to output and display in a 3 column table. I can't figure out the loop becuase it keeps outputing </tr></table> after every image.

function displayLiterature()
{
global $wpdb;
define('COLS', 3); // number of columns
 $col = 0; // number of the last column filled
$output = "";
$query = "SELECT * FROM literature ORDER By lit_id DESC";
 $literature = $wpdb->get_results($query, ARRAY_A);


echo '<table>';


if(count($literature) > 0) :
foreach($literature as $lit)
{

	 $col++;
 $output .= "<td>";
$output .= "<img src='".....{$lit['lit_image']}' width='130' height='170' alt='thumbnail'/>";
 $output .= "<a href='........{$lit['lit_pdf']}'>" . $lit['lit_title'] ."</a>";
 {if ($col == COLS) // have filled the last row
		 $output .= "</tr><tr>"; // start a new one
 }

 $output .= "</tr>"; // end last row
$output .= "</table>";
}

else: $output .= "<p>Sorry no results</p>";
endif;
echo $output;

}

Link to comment
https://forums.phpfreaks.com/topic/268750-output-a-3-column-table/
Share on other sites

foreach($literature as $lit)

 

use as $index => $lit and the modulus operator to detect when to output the </tr><tr>

 

and move

$output .= "</tr>"; // end last row
$output .= "</table>";

 

outside loop, like so

 

<?php
$r=99;
?>
<table>
<tr>
<th>c1</th>
<th>c2</th>
<th>c3</th>
</tr>
<tr>
<?php
while($r-->0){
printf("<td>%d</td>", $r);
if (($r % 3) == 0){
 printf("</tr><tr>");
}
}
?>
</tr>
</table>

Ok I moved that </tr> and </table> outside the loop. now I get one row of three and the rest are are on a second row.

function displayLiterature()
{
 global $wpdb;
 define('COLS', 3); // number of columns
    $col = 0; // number of the last column filled
 $output = "";
 $query = "SELECT * FROM literature ORDER By lit_id DESC";
 $literature = $wpdb->get_results($query, ARRAY_A);


 echo '<table>';
	  echo '<tr>';

 if(count($literature) > 0) :
  foreach($literature as $lit)

  {

	    $col++;
  $output .= "<td>";
  $output .= "<img src='...{$lit['lit_image']}' width='130' height='170' alt='thumbnail'/>";
  $output .= "<a href='http:...../{$lit['lit_pdf']}'>" . $lit['lit_title'] ."</a>";
  $output .= "</td>";
 {if ($col == COLS) // have filled the last row
		    $output .= "</tr>"; // start a new one
 }


  }
$output .= "</tr>"; // end last row
   $output .=  "</table>";
else: $output .= "<p>Sorry no results</p>";
endif;
echo $output;
//var_dump($lit);
}

<?php
function displayLiterature()
{
global $wpdb;
define('COLS', 3); // number of columns
   $col = 0; // number of the last column filled
$output = "";
$query = "SELECT * FROM literature ORDER By lit_id DESC";
$literature = $wpdb->get_results($query, ARRAY_A);

if(count($literature) > 0) :
 printf("<table>\n");
 printf("<tr>\n");
 foreach($literature as $col => $lit)
 {

 printf("<td>\n");
 printf("\t<img src=\"%s\" width=\"130\" height=\"170\" alt=\"thumbnail\" />\n", $lit["lit_image"]);
 printf("\t<a href=\"%s\" target=\"\">%s</a>\n", $lit["lit_pdf"], $lit["lit_title"]);
 printf("</td>\n");
 if (($col % 3) == 0) {
 printf("</tr>\n<tr>\n");
 }
 }
 printf("</tr>\n");
 printf("</table>\n");
else:
 printf("<p>Sorry No Results</p>");
endif;
}
?>

$literature is an indexed array, $col => $lit roughly translates to $lit=$literature[$col]

 

The modulus operator takes the left hand value and divides it by the right hand value, returning the remainder for evaluation, so it basically says if $col divides by 3 and leaves no remainder.

Edited by krakjoe

krakjoe: Why would you use printf () for every line, especially when the OP were already using an output variable? Why not set up an output template, and use sprintf () to add to the variable?

 

Mallen: I've taken the liberty of cleaning up your code, and fixing it to utilize some best practises.

Some of the things I've done is to remove the use of the global keyword, and put the DB connection variable in the function definition instead. I've also moved the number of columns there, and made it a variable instead of a constant, so that you can define how many columns you want when you call the function.

Also moved the "no records found" message up above the loop, to utilize the "exit early" principle. It helps cut down on the unnecessary nesting of blocks, and thus improves readability. To further improve readability I've added a output template, using the HereDOC syntax, which I'm using in combination with sprintf (). Which I'm also using to add security against XSS attacks with htmlspecialchars ().

The last two changes I did was to make sure that the script actually completes the last row of the table, to prevent some potential odd behaviour from browsers. As well as removing all echo from the function, and made it return the completed strings instead.

 

/**
* Creates a table with pictures and links of the literature in the database.
* 
* @param object $wpdb The database object.
* @param int[optional] $numCol The number of columns to construct, 3 by default.
* @return string.
*/
function displayLiterature ($wpdb, $numCol = 3) {
   $query = "SELECT * FROM literature ORDER By lit_id DESC";
   $literature = $wpdb->get_results ($query, ARRAY_A);

   // If we didn't find any rows in the database, return status message.
   if (count ($literature) <= 0) {
       return "<p>Sorry no results</p>";
   }

   // Set up the template for the individual records, so that we can use sprintf () later.
   // Using the HereDOC syntax. to make it easier to read the HTML block.
   $template = <<<Output
       <td>
           <img src="%s" width="130" height="170" alt="thumbnail" />
           <a href="http://%s">%s</a>
       </td>
Output;

   $output = "<table>\n\t<tr>\n";

   foreach ($literature as $col => $lit) {
       $output .= sprintf ($template, htmlspecialchars ($lit['lit_image']),
             htmlspecialchars ($lit['lit_pdf']), htmlspecialchars ($lit['lit_title']));

       // If the current row has been filled.
       if ($col % $numCol == 0) {
           // Start a new one
           $output .= "\t</tr>\n\t<tr>";
       }

   }

   // Add empty cells until last row is filled.
   while ($col % $numCol != 0) {
       $output .= "\t\t<td>&nbps;</td>\n";
   }

   // Finalize the table and return output.
   return $output."\t</tr>\n</table>";;
}

Edited by Christian F.
This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.