I have a MySQL table that contains people's names.
Using PHP, what's the best way of dividing these names up and displaying them in 3 columns.
This could be achieved using an HTML table, but would it be possible to do this using only <div>'s?
I heard that this can be done using the % operator. Would this be the best way, and how would this be done?
You could do this using the modulus operator, however it's actually possible with just CSS.
Using display: inline-block, you can get a good column effect. Take a look at this JSFiddle here. I'm only using JavaScript because I'm lazy; the <div> list would be generated by PHP in your case. If you want to confine them to a certain width, just put them in a container <div> with a fixed width.
I've come up with a solution using tables, which is really what you should be doing (you haven't given any special use cases). The code is below, as well as a working demo here.
$columns = 4; // The number of columns you want.
echo "<table>"; // Open the table
// Main printing loop. change `30` to however many pieces of data you have
for($i = 0; $i < 30; $i++)
{
// If we've reached the end of a row, close it and start another
if(!($i % $columns))
{
if($i > 0)
{
echo "</tr>"; // Close the row above this if it's not the first row
}
echo "<tr>"; // Start a new row
}
echo "<td>Cell</td>"; // Add a cell and your content
}
// Close the last row, and the table
echo "</tr>
</table>";
And to finish off, we have our column-centric layout, this time going back to divs. There's some CSS here; this should be put in a separate file, not left inline.
<?php
$rows = 10; // The number of columns you want.
$numItems = 30; // Number of rows in each column
// Open the first div. PLEASE put the CSS in a .css file; inline used for brevity
echo "<div style=\"width: 150px; display: inline-block\">";
// Main printing loop.
for($i = 0; $i < $numItems; $i++)
{
// If we've reached our last row, move over to a new div
if(!($i % $rows) && $i > 0)
{
echo "</div><div style=\"width: 150px; display: inline-block\">";
}
echo "<div>Cell $i</div>"; // Add a cell and your content
}
// Close the last div
echo "</div>";
?>
Related
Each table is to be produced by one loop; a for loop and a while loop creating two separate tables.
Alternate rows shall be coloured using html attribute names
Every cell containing the result of the square of a number (1x1, 2x2, 3x3 etc) shall also have distinctive background using a html attribute name
Create the times table from 1 to12. (ie: 1x1 ... 12x12) - for both times tables.
Please display only the result (i.e: 1, 2, 4, 144) for the FOR loop table and display the calculation and result (i.e: 1x1=1, 2x2=4, etc) for the WHILE loop table.
<head>
<meta charset="utf-8">
<title>Multiplication Table</title>
<link href="style.css" rel="stylesheet" type="text/css">
</head>
<body>
<h1 align="center">Multiplication Table with a "forloop"</h1>
<table border ="1" align="center" width="80%">
<?php
// Create first row of table headers
$l = 12;
$c = 12;
echo '<th>X</th>';
for ($l = 1; $l <12; $l++){
echo "<th bgcolor=#d3d3d3>". $l . "</th>";
}
//set alternating table row colors
for($i = 1; $i <=$l ; $i++){
if($i%2 == 0){
echo "<tr bgcolor =#CAE3FF>";
echo "<th bgcolor =#d3d3d3>$i</th>";
}else{
echo "<tr bgcolor =#d3d3d3>";
echo "<th bgcolor =#d3d3d3>$i</th>";
}
//Set color for squared numbers
for($c = 1; $c<13; $c++){
if($i == $c){
echo "<td bgcolor = #ffffff>".$i * $c . "</td>";
}else{
echo "<td>".$i * $c ."</td>";
}
}
echo "</tr>";
}
?>
</table>
<br><br>
<h1 align="center">Multiplication Table with a "Whileloop"</h1>
<table border ="1" align="center" width="80%">
<?php
$r = 12;
$c = 12;
echo "<th>X</th>";
$r = 1;
while ( $r<= 12) {
echo "<th bgcolor = #d3d3d3>".$r. "</th>";
$r ++;
}# End of While loop
echo "</tr>";
$x = 1;
while ( $x <= $r) {
if($x % 2 == 0){
echo "<tr bgcolor =#CAE3FF>";
echo "<th bgcolor =#d3d3d3>$x</th>";
}else{
echo "<tr bgcolor =#d3d3d3>";
echo "<th bgcolor =#d3d3d3>$x</th>";
} # End of if-else 1
$y = 1;
while ( $y <=12) {
if($x == $y){
echo "<td bgcolor = #ffffff>".$x. "x" .$y."=".$x * $y . "</td>";
}else{
echo "<td>".$x. "x" .$y."=".$x * $y ."</td>";
} // End of if-else 2
$y ++;
}
$x++;
} # End of the main While loop
?>
</tr>
</table>
</body>
</html>
Since you're new, I'll do for you what I wish someone had done for me.
I've re-written your code to highlight some elements of simplification. If you'll bear with me, this will hopefully save you mountains of time and frustration. :-)
Like most beginners, you are using nested if statements because you have not yet learned to think like a professional programmer. You're mentally looping through the cells in your head and you're making decisions about them. Your code reflects that.
Lets look at what you did:
You needed to fill up this block, so we randomly put an X here. That's somewhat OK, but there's a better way.
You create a header row. also, not bad.
You're making a decision on each cell based on its content. But this is where you start to make things complicated. Not only are you needlessly printing the tr bgcolor (doesn't matter when you change the cell color), but you'r making an either or decision with an else inside a loop. That's hard to read, hard to maintain, and if you continue to develop this way, other developers will want to strangle you.
You have a secondary for loop to handle squares. This is wholly unnecessary.
But it's OK! You should see the trash I wrote when I was starting out!
Let's change the way you think to fix the code.
You probably did not start out by drawing your table on a piece of paper and coloring in your cells, but you should have. It helps you visuallize what you're about to do. I had the benefit of just running your code to see what you were doing. Quite honestly - I wasn't able to visualize it just looking at your code.
After I ran it, I saw you have three objectives:
Show odds in grey (also the default color)
Show evens in blue
Show squares in white
Now, let's think about what actually has to go on here to make this happen.
We need a header
We need to loop through 1 to 12 twice to create the table.
We need a header column so we can create that nice "x * y" lookup table
We need to change the cell color based on its value.
So, let's use a couple of rules to force us to write cleaner, better code.
Implement separation of concerns so that any given section of code is only doing one thing.
Avoid nested loops and nested if's like the plague. Only use them when necessary. (We need a nested loop to do our mutiplication, so it's ok there).
'else' is never necessary.
When making decisions, allow the decision to cascade down a decition tree until a matching condition is found.
KISS
Don't repeat yourself.
Here's the resulting code (note" I am using images because it will be easier for me to annotate the changes. The code is here in this gist for you.
The HTML
The HTML section is at the bottom of the code, and contains two simple PHP snippets to print the header and print the table.
Printing the header
Keeping with simplicity and separation of concerns, this does one thing: it prints the header. I also changed $l to $i since i is more synonymous with an index or pointer in programming.
And, I fixed a bug. You were using <12 instead of <=12 so your last column wasn't printing.
Printing the table
Again, separating out concerns, this function only wants to print the table. It doesn't care about the cells.
Here's what we're doing:
$x represents the row number.
Here, I open the row. Because each time $x increments, I should be starting a new row.
$y represents the column. I need this here only because the column matters to the row. I am NOT concerned with printing the cell in this function.
This function separates teh concern of dealing with the cell to another function aptly named print_cell.
After I have printed all the cells for the row, I should close it out so I can start a new row, or finish out the table.
Printing the cells
Again - separation of concerns: I only want to deal with printing the cell. And, thus far, I don't care about colors!
I need $x and $y, so I receive them here.
I am using printf and a format string instead of concatenation. Anytime I see an abundance of concatenation, I know I am dealing with a novice programmer who doesn't know any better. You now know better. :-)
This line determines the color, but you can see I refactored out the color logic into its own function because this function doesn't care about making color decisions - only about printing the cell.
This line is a convenience so I can deal with $n instead of $x * $y. It fills up the symbol table uselessly, but sometimes you can just splurge on a little extra memory.
This is a ternary operation, which is a basic shorthand for if...else. It doesn't violate the "else is never necessary" rule because it is limited to a single line and an "either or" condition, whereas "else" is a catch-all. It also avoids block if decisions. It's still clean code.
Here, I am printing the cell using printf.
Choosing cell colors
First, there is no need to color the <tr> because we are choosing all the cell colors, which would just override it anyway. So we don't care about <tr>'s bgcolor.
Next, Please note that the numbers in the image below do not go from top to bottom like the others 1 is at the bottom for a reason!
This function is dedicated to choosing a cell color based on its content. We want it to execute from top to bottom, and return the color for the cell as soon as it gets a match. Therefore, we put the "special" colors towards the top of the function and default, non-special ones at the bottom.
This is the default value. Cells are grey unless they are special. In order for a cell to be grey, they cannot match any of the rules above it.
Our first column for each row is actually a header. In your original code, you were creating extra code to handle this, but in reality, it's just column 0. When $y == 0, make it blue.
This is our first "special" condition for a cell color. If it's a square it's white (doesn't matter if it is even or odd).
This is our next special condition, but not as special as squares. If it's even, it's blue.
What's very important about this type of structure is that it allows the processor to return a value from a function the instant it gets a result. Nested if's, on the other hand, have to exit if after if after if after if after else before they can exit the function. This doesn't matter in an application like what you've written, but at scale when every CPU cycle counts, that's important. Plus, this is DRASTICALLY easier to read than what you wrote with all the nested statements and concatenated strings.
Conclusion
Welcome to the programming club. I hope you found this useful and helpful. Keeping your code clean and following these pracitces (as well as knowing the PSRs, and how to refactor) will go a long way in making you an excellent addition to our community. (Not just SO, but the programming community in general).
Knowing design patterns is extremely helpful too.
Remember: "Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live." Because sometimes that violent psychopath will be you in 6 months when you're trying to figure out what the hell you did when you wrote "that code" six months ago.
Here's the re-written code
<?php
/**
* Prints the top row of the table.
* */
function print_header() {
echo '<th>X</th>';
$format = "<th bgcolor=#d3d3d3>%s</th>";
for( $i = 1; $i <=12; $i++) {
printf($format,$i);
}
}
/**
* Determines the color of the cell.
* */
function get_color($x, $y) {
//These are header rows / columns.
if($y == 0) return "#CAE3FF";
//If they are squared, x == y. This is the override.
if( $x == $y ) return "#ffffff";
//If they are even, return blue.
if( ($x * $y ) % 2 == 0 ) return "#CAE3FF";
//what's left over is either odd or weird. Return grey.
return "#d3d3d3";
}
/**
* Prints the cell
* */
function print_cell($x, $y) {
$format = "<td bgcolor = %s>%s</td>";
$color = get_color($x,$y);
$n = $x * $y;
$output = ( $n == 0 ? $x : $n);
printf($format,$color,$output);
}
/**
* Prints the rows of the table and holds the primary loop
* */
function print_table() {
for($x = 1; $x <=12; $x++) {
echo "<tr>";
for($y = 0; $y <=12; $y++) {
print_cell($x,$y);
}
echo "</tr>";
}
}
?>
<head>
<meta charset="utf-8">
<title>Multiplication Table</title>
<link href="style.css" rel="stylesheet" type="text/css">
</head>
<body>
<h1 align="center">Multiplication Table with a "forloop"</h1>
<table border ="1" align="center" width="80%">
<?php print_header() ?>
<?php print_table() ?>
</table>
</body>
</html>
What I'm looking for is a way to print two complete form elements next to each other as they go down a php page. Essentially two columns of repeating elements.
I have a "div" loop that creates multiple elements on my page using the same div I guess? I'm using two variables to set their location on the page as it goes down, ex. ($down += 200, $left += 200) and it works pretty well. The problem I'm facing is that I have to put an excessive amount of space between each element because some parts are 20px tall and some are 50px tall. With the div loop it looks like they're not aware of each other as far as I can tell meaning all the smaller ones cause the next larger element not to move far enough down the page making them overlap. It'd rather not account for each individual one to only have it do extra space on the smaller ones. I feel like there should be a better option for this. I would also like to avoid a table unless someone can show me a table without the table portion and just the formatting.
while ($results = mysqli_fetch_assoc($towerquery))
{
if ($number % 2 == 0 && $number !== 0 ){ $left = 200; $down += 320; }
print '<span style="display:block;position:relative;left:'.$left.'px;top:'.$down.'px;font-family:tahoma;font-size:13px;margin:40px;">';
$down -= 300;
$left += 500;
}
You can always use Flexbox to create equal height divs:
.paddingBlock {
padding: 20px 0;
}
.eqDisplay {
display: flex;
}
.equal {
padding: 10px;
}
.equal:nth-of-type(odd) {
background: darkgreen;
}
.equal:nth-of-type(even) {
background: black;
}
.eqHW {
flex: 1;
}
.eqHWrap {
justify-content: space-between;
color: #eee;
}
<div class="paddingBlock">
<h1>Equal Column Height</h1>
<div class="eqHWrap eqDisplay">
<div class="eqHW equal">
<p>Using</p>
<p>flex</p>
</div>
<div class="eqHW equal">
<p>works</p>
<p>well</p>
<p>despite</p>
<p>content</p>
<p>length</p>
</div>
</div>
</div>
Using that in php you could echo the results:
<?php
$yourVariable = array(1,9,5,12,73);
echo '<div class="paddingBlock"><div class="eqHWrap eqDisplay">';
while (x === x) {
echo '<div class="eqHW equal">' . $yourVariable . '</div>';
}
echo '</div></div>';
?>
The answer above definitely what lead me down the path to victory and dominance of my webpage, but I had to add a separate part to make it work for me which I have posted below
$number = 0;
if ($number % 2 == 0 || $number == 0 ) { print '<div class="eqHWrap eqDisplay">'; }
print '<div class="eqHW equal">';
print '<p>';
//multiple if statements, span elements, line breaks, returns
print '</p>';
if ($number % 2 !== 0 && $number !== 0 ) { print '</div>'; }
print '</div>';
$number++;
This extra code allowed me to only use one div and have it execute as two, because I'm pulling from an array of IPs and I can't get current and get next at the same time due to the coding disasters I kept running into. I assume other people run into the same problem when creating a loop to pull from an array as you can typically only do one at a time in sequence. My code is now successfully working though as seen below in the link!
I have a huge list of data I want to display, 10,000's, with filters hopefully just a few thousand at a time.
Languages: HTML, PHP, CSS
I was thinking of the best way to display this data and thought of an idea I like. I would like to have a box (say a div) with a fixed height (90% or 100% of the screen/browser resolution). No horizontal scrolling. Data would display visually in columns, filling the first column, then the second, third, forth, etc.. as many as required. The boxes would house the columns and increase in number as required downwards (for vertical scrolling). This will need to be dynamic as I will not know what data will be displayed (based on filter), I will not know the users browser size etc..
Made a paint image if that helps more:
http://postimage.org/image/630pxp3sx/
If the box thing is not possible, could you at least tell me how to achieve the coloumn effect.
Hope that makes sense.
Ideally I think I want to achieve this with CSS?
Thanks
The closest you can get with pure CSS is with the columns property, but it won't fill exactly the way you want. The elements will fill from top to bottom, left to right, and divided equally so that all of the columns are as close to the same height as possible.
ul {
columns: 5em; /* some browsers require prefixes (eg. -moz-columns, etc.) */
}
http://jsfiddle.net/VQXH3/
Flexbox could do what you're asking for, but support for it is poor at the moment (IE10+, Opera, Chrome; Firefox is adding support for the new spec soon).
http://jsfiddle.net/VQXH3/1/ (try in Opera, didn't add prefixes to the demo)
If you want the columns to be as even as possible, simply figure out how many results are being displayed beforehand. Then, decide how many columns you want to display them. Say you had 100 results, and wanted to divide them among 5 columns, that would be 20 results for each column. You could do something like this in PHP/MySQL:
<?php
$con = mysql_connect('localhost', 'user', 'pass');
$db = mysql_select_db('data');
$get = mysql_query("SELECT * FROM table");
$columns = 5; // number of columns you want to have
$total = mysql_num_rows($get);
$perCol = ceil($total/$columns);
$counter = 0; // start counter at 0 and increment it as the loop progresses
$data = "<div class=\"column\">\n"; // create blank string for storing results
$counterTotal = 0; // keep track of total results
while($a = mysql_fetch_array($get)) {
$counter++;
$counterTotal++;
if ($counter == 1 ) { // no <br /> tag necessary
$data .= " " . $a['data'];
} else {
if ( $perCol == $counter ) {
$data .= "<br />\n " . $a['data'] . "\n</div>\n<div class=\"column\">\n";
$counter = 0; // reset counter for new column
} else {
$data .= "<br />\n " . $a['data'];
}
}
}
$data .= "\n</div>\n";
echo $data;
mysql_close($con);
?>
If you were wondering why I added all the new lines (\n) and whitespace in the code, it's just to make the source code look nice and pretty. :) Feel free to take that out if you wish, but I like my source code to look nice and readable, even when it's being dynamically generated.
Then if you want the columns to fill the whole width of the screen, you can just inject PHP into the <style> tag in the header, like this: (assuming it's on the same page as the code above so you can still access the $columns variable)
<style type="text/css">
.column {
float: left;
width: <?= floor(100/$columns); ?>%;
margin: 0px;
padding: 0px;
}
</style>
Of course this would only work if there is no remainder in the division, but it should come close even if it isn't a perfect division. Here is the code from a sample page I made to do this:
<?php
$con = #mysql_connect("localhost", "user", "pass");
$db = #mysql_select_db("sampleDB", $con);
$get = mysql_query("SELECT * FROM dataTable");
$columns = 5; // number of columns you want to have
$total = mysql_num_rows($get);
$perCol = ceil($total/$columns);
$counter = 0; // start counter at 0 and increment it as the loop progresses
$data = "<div class=\"column\">\n"; // create blank string for storing results
$counterTotal = 0; // keep track of total results
while($a = mysql_fetch_array($get)) {
$counter++;
$counterTotal++;
if ($counter == 1 ) { // no <br /> tag necessary
$data .= " " . $a['data'];
} else {
if ( $perCol == $counter ) {
$data .= "<br />\n " . $a['data'] . "\n</div>\n<div class=\"column\">\n";
$counter = 0; // reset counter for new column
} else {
$data .= "<br />\n " . $a['data'];
}
}
}
$data .= "\n</div>\n";
#mysql_close($con);
?>
<html>
<head>
<title>Data In Columns</title>
<style type="text/css">
.column {
float: left;
width: <?= floor(100/$columns); ?>%;
margin: 0px;
padding: 0px;
}
</style>
</head>
<body>
<?= $data; ?>
</body>
</html>
If you'd like to see the results of this code, you can check out the sample that I made here: http://mdl.fm/sample.php
UPDATE: If you'd like to fit the content to the height of the screen and determine the number of columns needed, you would need to manually dictate how many items go in each column, so you would make the following replacements:
// replace this
$perCol = ceil($total/$columns);
// with this
$perCol = 20;
$columns = ceil($total/$perCol);
// the line above will just override the manual declaration of $columns
However, PHP cannot detect the browser's dimensions, so if you want to do that, you can forward to the PHP page again via Javascript with the dimensions included. Here is a piece of sample code you could use, put this in the tag of your page:
<script type="text/javascript">
function getDims() {
var myWidth = 0, myHeight = 0;
if( typeof( window.innerWidth ) == 'number' ) {
//Non-IE
myWidth = window.innerWidth;
myHeight = window.innerHeight;
} else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) {
//IE 6+ in 'standards compliant mode'
myWidth = document.documentElement.clientWidth;
myHeight = document.documentElement.clientHeight;
} else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
//IE 4 compatible
myWidth = document.body.clientWidth;
myHeight = document.body.clientHeight;
}
return {
'width' : myWidth,
'height' : myHeight
};
}
function loadDims() {
if ( document.URL.indexOf("?w=") < 0 ) {
var dims = getDims();
window.location.href = '/sample.php?w=' + dims.width + '&h=' + dims.height;
}
}
</script>
Then update your with an onload like this:
<body onload="loadDims();">
At this point, you will know the browser dimensions inside the PHP code, so you can divide the given height by the text-size and see how many items can be contained in one column without the need for scrolling. Again, I have updated my page with this code, so just check it out if you want these complete snippets. Also, if you have any questions implementing them, just contact me through my website (http://mdl.fm) and I'd be glad to help.
I am wondering if it's possible to create a grid-like layout using div's that are dynamically created using PHP.
I am creating a product page that will display all products in a PHP database. I want each product to be housed in a div, and 3 divs to display in a row with as many rows as needed to get through all the products.
Something like this:
div div div
$row['product1'] $row['product2'] $row['product3']
div div div
$row['product4'] $row['product5'] $row['product6']
I would prefer not to use a table. I know how to line divs up using the float and clear properties, but not if they are all being created in a while statement, which makes me think it might not be possible.
So I guess, is this possible without using tables, or should I just stick with that?
This can be done the way you ask, though it isn't the best way. It's entirely possible to identify the <div> positions within columns in a while loop:
// Looping over your results simplified...
$i = 1;
while ($results) {
if ($i % 3 == 1) {
$div_class = 'left';
}
else if ($i % 3 == 2) {
$div_class = 'middle';
}
else {
$div_class = 'right';
}
$i++;
// output, simplified
echo "<div class='$div_class'>$row_contents</div>";
}
Then use your CSS to float and clear as necessary for the left, middle, right classes.
.left, .middle, .right {
float: left;
}
.left { clear: left; }
.right { clear: right; }
However,
Given all of this, I still probably wouldn't bother with <div>s. Semantically if this is a list of products, you should be listing them in <li> tags. Then just style the <li> to float: left; and make each one 33% the width of the container so you get 3 per line.
I am trying to display the retrieved data in grid.
I used while loop and retrieved every thing.I applied css but now all rows are getting displayed in same color.
I am trying to do like this row0 blue color row1 green color row2 blue color row3 green color.How do i do it?
Use something like this (of course, adapt it to your loop) :
echo '<table>';
$i = 0;
foreach($myrows as $row) {
echo '<tr class="row'.(++$i % 2).'"><td>';
echo $row;
echo '</td></tr>';
}
echo '</table>';
With the following CSS code :
tr.row0 > td { background-color: blue; }
tr.row1 > td { background-color: green; }
Few methods if happy using CSS3 look at nth-child
Or place a counter inside your while statement and use mod function to apply a class
e.g.
while(...){
if($count%2)
{
\\add class
}
$count++;
}
You can do it in CSS3 (see http://www.w3.org/Style/Examples/007/evenodd)
In PHP, you can apply a "odd" class using a modulo:
<?php for ($i = 0; $i < 10; $i++) {
$class = ($i%2 != 0) ? ' class="odd"' : '';
echo '<tr'.$class.'>...</tr>';
}
You can also use a free tool like SDTable.com and it will do the job for you. You just go in into template css file and change row-1 and row-2 background colors or create a rule which specify the background color dynamicly based on the native data in your database.