I am currently generating a table in the following manner:
A0 A1 A2 A3
B0 B1 B2 B3
C0 C1 C2 C3
D0 D1 D2 D3
I'd like to do:
A0 B0 C0 D0
A1 B1 C1 D1
A2 B2 C2 D2
A3 B3 C3 D3
So basically make it progress vertically with 4 columns.
Current code:
<table cellspacing="2px">
<?php
# display products in 4 column table #
$i=0;
while ($data=mysqli_fetch_array($result)){
if($i > 0 and $i % 4 == 0) {
echo '<tr></tr>';
}
//passing id in link to retrieve product details
echo '<td>'.$data['name'].'</td>';
$i++;
}
?>
</table>
Can someone point me in the right direction to accomplish this?
Clarification
In the illustration above, I'm merely pointing out that I'd like to have the result progress vertically down and it also needs to expand to 4 columns (I've only shown 2 however it needs to expand to 4).
In the code snippet it progresses horizontally.
I have also updated the question to keep it simple.
I hope that clears any ambiguity.
This should do it.
<table>
<?php
$i = 0;
while ($data = mysql_fetch_array($result);
if ($i % 4 == 0) {
if ($i > 0) {
// End last row unless this is the first row
echo '</tr>';
}
// Start a new row
echo '<tr>';
}
echo '<td>...</td>';
$i++;
}
if ($i > 0) {
// Close out the last row, unless there wasn't any data
echo '</tr>';
}
?>
</table>
You had <tr></tr> backwards -- if you want to end one row and start a new one, it must be </tr><tr>. But the first row needs to be treated specially, since there's no previous row to end. If you know there will always be data, you can output the first <tr> and last </tr> unconditionally as part of the HTML code, but I wrote my code defensively.
Meh... who uses TABLES anymore? Do it with CSS! Very Easily done. Adjust my sample as needed.
<?
$x = 0;
$y = 0;
$count = 0;
$total = 100; // whatever your total is from sql result;
while ($count < $total) {
echo '<img src="foldername/'.$itempic[$count].'" style=\'postion:absolute;top:'.$y.'px;left:'.$x.'px;\'>'."\n";
$y = $y + 50;
if ($y > 300){
$y = 0;
$x = $x + 50;
}
$count++;
}
?>
Here is another example I made specifically for you:
Yes it is a bit gimp, but the logic is what you can glean from it and adjust it to your needs.
It does work though, I just wasn't going to take the time to make an example perfect.
<?
$info = Array(
A0,A1,A2,A3,
B0,B1,B2,B3,
C0,C1,C2,C3,
D0,D1,D2,D3);
$count = 0;
$total = 20;
$row = 0;
$col = 0;
while ($count < $total){
echo $info[$col+$row];
$col++;
$row = $row +3;
if($col > 4){
$col = 0;
$row = $row - 14;
echo '<br/>';}
$count++;
}
?>
Related
I want to make something like this:
A1
B1
C1
D1
D2
D3
C2
C3
B2
C4
D10
D11
D12
C5
C6
B3
C7
C8
C9
D25
D26
D27
So it's always groups of three, with every level ascending by a letter. First level is A, second B, C, D, E and so forth. The numbers are also listed in ascending order. Level A can only reach 1, B has 3, C has 9, D has 27, and so forth.
This is really easy to generate manually, converting the letters to their ASCII equivalent, adding one and converting them to character equivalent again. Problem is, I have to loop it till S, for instance, and my mind is getting messier and messier trying to put loops within loops.
What I got (toLetter and toNumber literally does what they do):
echo "<ul><li>";
echo "A1";
echo "<ul><li>";
$b = toNumber(A);
$b++;
$b = toLetter($b);
$bnum = 1 - 1;
$bnum = $bnum * 3;
$bnum++;
echo $b;
echo $bnum."</li>";
$bnum++;
echo "<li>".$b;
echo $bnum."</li>";
$bnum++;
echo "<li>".$b;
echo $bnum."</li>";
Making this:
A1
B1
B2
B3
I really can't figure out how to just loop everything so it can reach till Z.
A pretty simple version which only goes up to the 'C' level; increase as necessary.
<?php
function outputListItems($char) {
static $index = array('A' => 1);
if (!isset($index[$char])) {
$index[$char] = 1;
}
for ($i = 0; $i < 3; $i++) {
echo '<li>';
echo $char;
echo $index[$char]++;
if ($char < 'C') {
echo '<ul>';
$nextChar = $char;
outputListItems(++$nextChar);
echo '</ul>';
}
echo '</li>';
}
}
?>
<ul>
<li>
A1
<ul><?php outputListItems('B'); ?></ul>
</li>
</ul>
A is treated as special chase, since it only has one entry.
in PHP, you can use ++ on a string, so you don't need to Letter/toNumber
And to support unlimited nesting, you need a recursion (or at least it will be easier for you)
I try to create a binary tree as html-table which is not recursive build. The order of the fields should be like this:
C1 C2 C3
7
3
8
1
9
4
10
11
5
12
2
13
6
14
C1 stands for col 1, C2 for col2 etc.
The following code creates a table in a recursive way, but this is not what I want!
<?php
$cols = 4;
$counter = 0;
$lines = pow(2,$cols);
echo '<table border=1 style="border:1px solid black;"> ';
for($i = 0; $i < $lines; $i++){
echo '<tr>';
for($j = 0; $j < $cols; $j++){
$rowspan = $lines/pow(2,$j+1);
if(0 === $i%$rowspan) {
$counter++;
echo '<td rowspan='.$rowspan.'>'.$counter;
}
}
}
echo '</table>';
?>
I hope someone could give me a hint how to solve this problem.
Used this expression to calculate the row's values: ($i / $rowspan + pow(2,$j+1) - 1) wherein $i / $rowspan is the number of the row in the current level starting with 0 for the first row and pow(2,$j+1) - 1 is the level's first value, i.e. 7 for the third level.
$cols = 4;
$lines = pow(2,$cols);
echo '<table border=1 style="border:1px solid black;">';
for($i = 0; $i < $lines; $i++){
echo '<tr>';
for($j = 0; $j < $cols; $j++){
$rowspan = $lines/pow(2,$j+1);
if(0 === $i%$rowspan) {
echo "<td rowspan='$rowspan'>".
($i/$rowspan + pow(2,$j+1)-1).
"</td>";
}
}
}
echo '</table>';
Outputs your desired result. Hope your teacher won't hate me now! ;-)
You can alternativly use ($i/$lines + 1 ) * pow(2,$j+1) - 1 for the row's value, if you don't want to depend on $rowspan.
I am sure the title is not even right on this one.
Here is the issue , I have 3 columns and 6 results
that are displayed like this
Column1 Column2 Column3
result1 result3 result5
result2 result4 result6
but need them like this
Column1 Column2 Column3
result1 result2 result3
result4 result5 result6
my array holds all 6 results and so far I see I need to pick every 0 and 2nd to be displayed in column1 and continue( array starts at 0).
the code is pretty large but the main part for switching results is here
$count = count($result);
for ($result = 0; $result < $count; $result++) {
$getorder= "";
if ($count != 1) {
if ($result == 0) $getorder= "first";
if ($result == $count - 1) $getorder= "last";
}
echo '<div class="'.$getorder.'width'.intval(100 / $count).'">'.$mycolumn[$result].'</div>';
}
so this here should have some kind of division. Here is just dumb example
$mycolumn[$result % X == X]
i hope I did not confuse you and you get the idea. If you ask yourself why i don't just do rows instead columns , answer is complete css reconstructions. whit this here figured out I can target the results and keep columns and css as they are
Don't use ($result / 3) since you can have seriuous rounding problem.
Since to me it's not very clear the name of your vars I post you a php generic code and it is:
echo '<div class="result">';
for($i = 0; $i < $columnNum; $i++)
{
echo '<div class="column">';
for($j = $i; $j < $resultNum; $j += $columnNum)
echo '<label class="value">' . array[j] . "</label>";
echo '</div>';
}
echo '</div>';
Just change the vars name with your needs and this is the solution to your problem.
$mycolumn[intval($result / 3) + intval(($result % 3) * $count / 3)]
Demo http://codepad.viper-7.com/hdSi6b
Working flawlessly.
You can change whole code as AurelioDeRosa said.
I have simple table that has about 80 rows, which I populate dynamically using PHP. What I am trying to do is to layout those rows in chunks for each column. So if I have 80 rows, I would like 4 columns of 20 rows or so, maybe the last column has less or more depending on the total number of rows. The total number of rows can change!
I am having trouble coming up with an implementation method that will not get messy! Anyone know of a simple way that I can implement this.
I have tried using a counter as I loop the data to populate the table and when a multiple of of 20 is reached move to the next block but that didn't work for me as I had extra rows left over.
foreach($indexes as $index){
$counter++;
echo '<tr>';
if($counter > 20){
$multiplier = $counter / 20;
$head = '<td></td>';
for($i=1; $i<$multiplier; $i++){
$head .= '<td></td>';
}
}
if($counter < 20){
$head = '';
}
echo "$head<td>$index</td><td><input id='$index' name='$index' type='checkbox' /></td>";
echo '</tr>';
}
Thanks all for any help
I would do :
$nbCols = 4;
$nbRows = count($indexes)/$nbCols;
for($row=0; $row<$nbRows; $row++) {
echo "<tr>";
for($i=0; $i<$nbCols; $i++) {
$index = $indexes[$row + ($i*$nbRows)];
echo "<td>$index</td><td><input id='$index' name='$index' type='checkbox' /></td>";
}
echo "</tr>";
}
Wouldn't you want to see the remainder of your division and deal with that also?
if($counter % 20 == 0){
// You've no remainder
}else{
// Do another loop to output the odd rows
}
Or you could % 2 == 0 to see if it's even, and then just multiply the whole result by 10.
Be sure to look at ceil() and floor() also for ensuring your number of rows is a round number.
if you dont mind to have this kind of cell order:
1 2 3 4
5 6 7 8
you can use <div style='float:left'>$cellValue</div> in the loop without use of table.
<?php
$combinedArray = array("apple","banana","watermelon","lemon","orange","mango");
$num_cols = 3;
$i = 0;
foreach ($combinedArray as $r ){
/*** use modulo to check if the row should end ***/
echo $i++%$num_cols==0 ? '<div style="clear:both;"></div>' : '';
/*** output the array item ***/
?>
<div style="float:left; width:33%;">
<?php
echo $r;
?>
</div>
<?php
}
?>
<div style="clear:both;"></div>
The above code will print out the array like this:
apple --- banana --- watermelon
lemon --- orange --- mango
However, I need it like this:
apple --- watermelon --- orange
banana --- lemon --- mango
Do you know how to convert this? Basically, each value in the array needs to be placed underneath the one above, but it must be based on this same structure of 3 columns, and also an equal amount of fruits per column/row (unless there was like 7 fruits there would be 3 in one column and 2 in the other columns.
Sorry I know it's confusing lol
Thanks everyone for your help... I realized a better way to do it though. Simple put, I have 3 columns floating next to eachother. And in each column, I add a list of the items into it and stop when I hit the max items per row.
working code:
<div style="float:left; width:33%;">
<?php
$combinedArraySizeOf = sizeof($combinedArray);
$num_cols = 3;
$iPerRow = $combinedArraySizeOf / $num_cols;
for ($i=0; $i!=$combinedArraySizeOf; $i++){
if ($i % $iPerRow == 0){
echo '</div><div style="float:left; width:33%;">';
}
echo $combinedArray[$i]."<br />";
}
?>
</div>
<div style='clear:both;'></div>
Don't forget to clear both at the end if necessary :P
Why aren't you doing exactly what you want to do? I mean show them in columns, instead of rows?
$combinedArray = array("apple","banana","watermelon","lemon","orange","mango");
$num_cols = 3;
$rowCount = ceil(count($combinedArray)/$num_cols);
$i = 1; // in order the modulus to work correctly
?>
<div style="float: left; width:33%"> <!-- this is the first column -->
foreach ($combinedArray as $r ){
?>
<div> <!-- just a div containing $r -->
<?php
echo $r;
?>
</div>
<?php
// this is where the magic happens
// check if we have enough rows and start another column
if ($i % $rowCount == 0) {
?>
</div> <!-- close the previous column and start a new one -->
<div style="float: left; width:33%"> <!-- this is the new column -->
<?php
}
$i++;
}
?>
</div> <!-- closing the last open column -->
<div style="clear:both;"></div>
This should do just the job you wish. Marvin's answer is better if you want to use only tables without divs.
$combinedArray = array("apple","banana","watermelon","lemon","orange","mango");
$step = 2;
$i = 0;
$new_array = array();
foreach ($combinedArray as $r ){
$remainder = ($i % $step);
$new_array[$remainder][] = $r;
$i++;
}
foreach($new_array as $array)
{
echo implode(' --- ', $array)."<br>";
}
Would this work?
$combinedArray = array("apple","banana","watermelon","lemon","orange","mango");
$num_cols = 3;
$rows = ceil(count($combinedArray)/$num_cols);
for($i = 0; $i < $rows; $i++){
for($j = 0; $j < $num_cols; $j++){
echo $combinedArray[(($i+$j) * $rows)-$i];
}
echo "<br />";
}
This would also need to check that the value existed for cases where the number of items wasn't precisely divisible by the number of columns, you could do that with the following change:
$combinedArray = array("apple","banana","watermelon","lemon","orange","mango");
$num_cols = 3;
$rows = ceil(count($combinedArray)/$num_cols);
for($i = 0; $i < $rows; $i++){
for($j = 0; $j < $num_cols; $j++){
$cell = (($i+$j) * $rows)-$i;
if($cell > count($combinedArray)) break;
echo $combinedArray[$cell];
}
echo "<br />";
}
If this order is what you ideally want, but it's not critical that it works in all browsers, perhaps you should look at coloumn layout (still very experimental css3 draft). If you use dispay inline block for the element in each coloumn you'll have the current order as a fallback.
You could also use a table for the layout and use a for loop something like this (pseudo php code, it's been a while since I've coded any php):
maxHeight = Math.ceil(array.length / 3) // meaning length=6 will give 3,
// length=7 will give 4
$x = -1; // horizontal index
for(i = 0; i < array.length(); i++){
$y = i % maxHeight; // vertical index
if($y == 0){
$x++;
}
addToTable($x,$y, array[i]);
}