I have the following code which with the following variables set numberofColumns = 2 and numberArticles = 10, will create 2 columns for articles, the article order is from left to right (column1 to column2) going down the page.
Id just like to add some code </div><div class="whatever"> after every 2nd article.
Any help would be much appreciated.
if ($numberColumns >= 1) {
$columnArticles = intval(($numberArticles + $numberK2Articles) / $numberColumns);
}
$columns = array();
for($columnIndex = 0; $columnIndex < $numberColumns; $columnIndex++) {
$columns[$columnIndex] = '<div class="column col-' . ($columnIndex + 1) . '">';
}
$articleIndex = 0;
while($articleIndex < count($articles)) {
foreach ($columns as $columnIndex => $column) {
if (isset($articles[$articleIndex])) {
$columns[$columnIndex] .= modCTRandomArticleHelper::getArticleHtml($params, $articles, $articleIndex);
$articleIndex++;
}
}
}
for($columnIndex = 0; $columnIndex < $numberColumns; $columnIndex++) {
echo $columns[$columnIndex] . '</div>';
}
I've always used the Modulus operator (%) to determine if my current index was one of n rows. $index % 2 returns 0 for every second row. $index % 3 returns 0 for every third row, and so on.
http://php.net/manual/en/internals2.opcodes.mod.php
The first comment on that page suggests that a bitwise operation is more efficient when you just need to determine odd or even. So, $index & 1 (odd) is a faster alternative to !$index % 2 (odd).
Related
I have an ordered list which is 19 entries long (but could change and be more or less). I'm listing it on a drop down menu but because of its length the column is dropping below the fold of the page.
I'd like to create a separate column (ul or div) to either divide the list into 2 or 3 equally, or have set list sizes e.g. max 7 per list.
Any ideas? Current code:
<div id="colour" class="dropmenudiv">
<?php
$sql = "select * from rug_colours where id <> 0 and active = 1 order by name";
$rs = $database->query($sql);
$index = 0;
foreach($rs as $v) {
echo "<a href=\"//$base_url/?action=search&colour=".$v['id']."\" >".$v['name']."</a>";
}
?>
Try something along the lines of:
<div id="colour" class="dropmenudiv">
<?php
$sql = "select * from rug_colours where id <> 0 and active = 1 order by name";
$rs = $database->query($sql);
$column_height = 7;
echo "<div class='column'>";
foreach($rs as $idx => $v) {
echo "<a href=\"//$base_url/?action=search&colour=".$v['id']."\" >".$v['name']."</a>";
if($idx % $column_height) echo "</div><div class='column'>";
}
echo "</div>";
?>
and for equal split you might try this:
$max_column_height = 7;
$no_of_cols = ceil(count($rs) / $max_column_height);
$column_height = floor($count($rs) / $no_of_cols);
You should use index variable to divide it into 2 or 3 div.
Following is example to make it in three parts:
$index = 0;
foreach($rs as $v) {
if($index > 7){
$index = 0; // reset to zero. You can also seperate it by any tag div or ul if you want
}
echo "<a href=\"//$base_url/?action=search&colour=".$v['id']."\" >".$v['name']."</a>";
$index++;
}
For an evenly spread distribution, first divide the number of elements by 7 (or whichever maximum rows you want to allow), rounding upwards. This gives the number of columns. Then divide the number of elements by the number of columns, rounding upwards: this gives you the actual number of rows you need.
I like array_chunk for this purpose:
$maxRowCount = 7;
$colCount = ceil(count($rs) / $maxRowCount);
$chunkSize = ceil(count($rs) / $colCount);
foreach(array_chunk($rs, $chunkSize) as $column) {
echo "<div class='column'>\n";
foreach($column as $v) {
echo "<a href=\"//$base_url/?action=search&colour={$v['id']}\" >{$v['name']}</a>";
}
echo "</div>\n";
}
You can create array of columns based on current index in foreach() loop like
$abc = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15];
$cols = [];
$perCol = 7;
foreach($abc as $index => $val) {
$colInd = $index / $perCol;
$cols[$colInd][] = $val;
}
print_r($cols);
This will split data in $abc into 3 coluns by 7 items per column.
So, I want to distribute evenly lists across 3 columns. The lists cannot be broken up or reordered.
At the moment, I have 5 lists each containing respectively 4, 4, 6, 3 and 3 items.
My initial approach was:
$lists = [4,4,6,3,3];
$columns = 3;
$total_links = 20;
$items_per_column = ceil($total_links/$columns);
$current_column = 1;
$counter = 0;
$lists_by_column = [];
foreach ($lists as $total_items) {
$counter += $total_items;
$lists_by_column[$current_column][] = $total_items;
if ($counter > $current_column*$links_per_column) {
$current_column++;
}
}
Results in:
[
[4],
[4,6],
[3,3]
]
But, I want it to look like this:
[
[4,4],
[6],
[3,3]
]
I want to always have the least possible variation in length between the columns.
Other examples of expected results:
[6,4,4,6] => [[6], [4,4], [6]]
[4,4,4,4,6] => [[4,4], [4,4], [6]]
[10,4,4,3,5] => [[10], [4,4], [3,5]]
[2,2,4,6,4,3,3,3] => [[2,2,4], [6,4], [3,3,3]]
Roughly what you need to do is loop over the number of columns within your foreach(). That will distribute them for you.
$numrows = ceil(count($lists) / $columns);
$thisrow = 1;
foreach ($lists as $total_items) {
if($thisrow < $numrows){
for($i = 1; $i <= $columns; $i++){
$lists_by_column[$i][] = $total_items;
}
}else{
//this is the last row
//find out how many columns need to fit.
//1 column is easy, it goes in the first column
//2 columns is when you'll need to skip the middle one
//3 columns is easy because it's full
}
$thisrow++;
}
This will be an even distribution, from left to right. But you actually want a modified even distribution that will look symmetrical to the eye. So within the foreach loop, you'll need to keep track of 1.) if you're on the last row of three, and 2.) if there are 2 remainders, to have it skip col2 and push to col3 instead. You'll need to set that up to be able to play around with it,...but you're just a couple of logic gates away from the land of milk and honey.
So, I ended up using this code:
$lists = [4,4,6,3,3];
$columns = 3;
$total_links = 20;
$items_per_column = ceil($total_links/$columns);
$current_column = 1;
$lists_by_column = [];
for ($i = 0; $i < count($lists); $i++) {
$total = $lists[$i];
$lists_by_column[$current_column][] = $lists[$i];
//Loop until reaching the end of the column
while ($total < $items_per_column && $i+1 < count($lists)) {
if ($total + $lists[$i+1] > $items_per_column) {
break;
}
$i++;
$total += $lists[$i];
$lists_by_column[$current_column][] = $lists[$i];
}
//When exiting the loop the last time we need another break
if (!isset($lists[$i+1])) {break;}
//If the last item goes onto the next column
if (abs($total - $items_per_column) < abs($total + $lists[$i+1] - $items_per_column)) {
$current_column++;
//If the last item goes onto the current column
} else if ($total + $lists[$i+1] > $items_per_column) {
$i++;
$lists_by_column[$current_column][] = $lists[$i];
$current_column++;
}
}
Is it possible to control a for-loop when it reaches a certain condition?
Explanation:
I'm retrieving the folder path to a collection of images from a database: these images are then printed out via a for-loop. What I would need to do is control how these images are displayed on the page (say, 5 images per row).
As of now, the for-loop prints out 40 images in a single row, which makes you scroll to the furthest right of the page.
Is there a solution for controlling the for-loop, as in for instance, after 5 successful loops, echo out a < br >? Here's a vulgar thought:
for ($i = 1; $i < $rows; $i++) {
$path = $image[$i];
$folder_path = $path['folder_path']; //since it's an array
echo '<img src="' . $folder_path . '">';
//pseudocode
if ($i == 5) {
echo '<br>';
...continue with the loop
}
}
I know the pseudocode looks crazy, but that's pretty much what I need to do: loop for x amount of instances, add something, then continue.
As per #m69's comment, the best option would be to use the % (modulus) comparison operator. As explained by the PHP docs:
$a % $b returns the remainder of $a divided by $b.
So, in your case:
for ($i = 0; $i < $rows; $i++) {
$path = $image[$i];
$folder_path = $path['folder_path']; //since it's an array
echo '<img src="' . $folder_path . '">';
if ($i % 5 == 0) { //do this if $i divided by 5 has a remainder of 0
echo '<br>';
}
}
As a side note, you should set $i to 0 at the beginning of your for loop, assuming $rows is set to the number of rows returned from your query. Setting it to 1 will keep it from iterating through the last row, because $i will == 40 (assuming 40 rows), and so will NOT be < 40.
The same loop. The condition for inserting the is ($i % 5 == 0), which means (if this element is the fifth one of his series) will be useful for you.
<?php
for ($i = 1; $i < $rows; $i++) {
$path = $image[$i];
$folder_path = $path['folder_path'];
echo '<img src="' . $folder_path . '">';
if ($i % 5 == 0) {
echo '<br>';
}
}
I am having a basic problem, but now it gives pain me lot. I just want a table which have three column in each row. I want to add a extra empty column in a row when it has two columns. code here...
$j=0;
while ($data = mysql_fetch_assoc($q))
{
// when 3 columns fill, it create new row
if (($j%3) == 0)
{
echo "ADD A ROW";
}
$j++;
}
But now I need to know how many columns ($j value) in this loop to add a extra empty column in a row when it has two columns. I know count() is not available in loop. If know $columnNumber, I can handle this look like...
if ($columnNumber == 2)
{
echo "ADD A COLUMN";
}
How I do
As j will be the total number of columns after your while loop has completed, you can calculate how many extra columns you need with:
$remainder = (j % 3);
$columnsLeft = ($remainder == 0 ? 0 : 3 - $remainder);
$j = 1;
while($data=mysql_fetch_assoc($q))
{
if($j == 3)
{
echo "ADD A ROW";
$j = 0;
}
$j++;
}
this will done the things
I have a little script that prints a certain amount of rows in a mysql database.
Is there any way to make it so that after every second row it prints, there is a line break inserted?
Adding a line break after every row is simple, but I don't know how to add one after every other row. Is that possible?
You write "script" but in tags you have PHP, so I suppose you need PHP code:
foreach ($rows as $row) {
if ($i++ % 2) {
// this code will only run for every even row
}
...
}
$i=1;
while ($row = mysql_fetch_array($query))
{
//your code
if ($i % 2 == 0)
echo '<br>';
$i++;
}
add new variable before the loop
$i = 0;
then in your loop add
if ($i != 0 && $i%2 == 0)
echo '<br/>';
Depending on the language, something like this should do it: (in php) (where $arr is an array of results)
$str = '';
$i = 0;
for ($i=0; $i<count( $arr ); $i++)
{
if ( ( $i + 1 ) % 2 === 0 )
{
$str .= $arr[$i] . '<br />';
}
else
{
$str .= $arr[$i];
}
}
echo $str;
Use php and modulo.
such as
if($i % 3)
{
echo '<br />'..
If you need to do this inside the query for some reason, you could use something like
SELECT
<your fields>,
IF (((#rn:=#rn+1) % 3)=0,'<br>','') as brornot
FROM
<your tables and joins>,
(#rn:=0)