3 Div column classes from a Foreach - php

I'd like to get this code to actually work.
What I'm trying to get is my items separated into 3 columns.
I would also like to call the columns "first", "second", and "third", instead of
class0, class1 and class2
This code isn't working since all my items get called class0
<?php
$count = 0;
foreach ($this->items as $item) {
$count = $count == 3 ? 0 : $count++;
?>
<div class="<?php echo "class".$count ?>">

No need for the == 3 test, a simple:
<div class="classs<?php echo $count++ % 3?>">
would do the trick. Modulo math:
$count = 0 -> 0 % 3 = 0
$count = 1 -> 1 % 3 = 1
$count = 2 -> 2 % 3 = 2
$count = 3 -> 3 % 3 = 0
$count = 4 -> 4 % 3 = 1
etc...
You code is not working because $count++ is returning count's first FIRST, then incrementing the value. But since that original value is returned and assigned back to $count, you continually assign 0 over and over and over.
If you'd done ++$count, then it would have worked. (increment THEN return the new value)

This should work:
<?php
$count = 0;
$names = ['first','second','third'];
foreach ($this->items as $item) :
?>
<div class="class-<?=$names[$count++%3] ?>">
<?php
endforeach;
?>

You can use any of these codes:
1st way:
<?php
$count = 0;
foreach ($this->items as $item) {
$count = $count == 3 ? 0 : $count++;
switch ($count){
case 1: echo "<div class='first' >";break;
case 2: echo "<div class='second' >";break;
case 3: echo "<div class='third' >";break;
}
}
?>
2nd way:
<?php
$count = 0;
$name = null;
foreach ($this->items as $item) {
$count = $count == 3 ? 0 : $count++;
$name = ($count == 1 ) ? 'first': ( $count == 2 ) ? 'second': 'third';
}
?>
<div class="<?php echo $name ?>" >

You can use arrays with hard coded values like :
<?php
$numbers = array('first','second','third');
foreach ($this->items as $item):
$count = $count == 3 ? 0 : $count++;
?>
<div class="<?php echo "class_".$numbers[$count] ?>">
<?php endforeach; ?>

<?php
$count = 0;
foreach ($this->items as $item) {
if ($count==0) {
$class = "first";
$count++;
} else if ($count==1) {
$class = "second";
$count++;
} else {
$class = "third";
$count = 0;
}
?>
<div class="<?php echo $class ?>">
Something like this should work though a select case may be quicker

Related

How to set 2 different classes by if else condtion in foreach loop with predefined order?

Suppose I have 10 records, and 2 different classes namely c1, c2
<div class="c2">..content..</div>
<div class="c2">..content..</div>
<div class="c1">..content..</div>
<div class="c1">..content..</div>
<div class="c2">..content..</div>
<div class="c2">..content..</div>
<div class="c1">..content..</div>
<div class="c1">..content..</div>
<div class="c2">..content..</div>
<div class="c2">..content..</div>
i want the if else condition where class order needs to maintained like c2,c2,c1,c1,c2,c2,c1,c1,c2,c2.....so on
foreach(x as y){
if() {
<div class="<?php echo $class1;?>">..content..</div>
} else {
<div class="<?php echo $class2;?>">..content..</div>
}
class order should be c2,c2,c1,c1,c2,c2,c1,c1,c2,c2.....so on
Check the page url http://themesflat.com/html/nah/portfolio-creative.html
You can use a bitwise operator (&) here, and with 2 and this will toggle the class...
$i = 0;
foreach($x as $y){
if($i & 2) {
$class = "1";
} else {
$class = "2";
}
echo "<div class=$class>..content..</div>";
$i++;
}
I've extracted the echo out as this keeps it consistent, just have a variable for the class you want to have and put that in the if instead.
You can do it with a separate counter
$current = 'c2';
$count = 1;
for ($i = 0; $i < 10; $i++) {
echo '<div class="'. $current . '">..content..</div>';
if ($count == 2) {
$current = $current == 'c1' ? 'c2' : 'c1';
$count = 0;
}
$count++;
}
Demo: https://3v4l.org/7ftjg
This will of course work just as well in a foreach-loop.
Note: If it's only about styling the divs differently, you could do this in CSS alone. Here's a similar question and answer: nth-child: how to pick elements in groups of two
I'm pretty sure you can resolve the problem via css pseudo class :nth-of-type but if you prefered PHP you can try the following example.
<?php
$class_types = ['c2', 'c1'];
$records = array_fill(0, 10, '..content..'); // replace with your records
$records_length = count($records);
$html_output = '';
foreach ($records as $index => $item) {
$type = floor($index / $records_length * $records_length / 2) % 2;
$class = $class_types[$type];
$html_output .= sprintf('<div class="%s">%s</div>', $class, $item);
}
echo $html_output;
Try this code:
$counter = 1;
for($i=0;$i<=10; $i++){
if($counter==1 or $counter==2) {
echo '<div class="c1">..content..</div>';
} else {
echo '<div class="c2">..content..</div>';
}
if($counter==4){
$counter=0;
}
$counter++;
}
?>
How about we chunk the main array into an array or arrays of two
like
<?php
$chunked_array = array_chunk( $your_array , 2 );
// This will give us an array of 2 elements array
// now we will loop
for( $i = 1 ; $i < count( $chunked_array ); $++ ){
$contents = $chunked_array[$i];
foreach( $contents as $content ){
if ( $i%2 == 0 ){
//<div class="<?php echo $class1;?>">..content..</div>
}else{
//<div class="<?php echo $class2;?>">..content..</div>
}
}
}
using this way we have one loop and it will always be in a group of two even when your data grow or shrink

Adding class to a foreach loop every N times

I have an users list, each user is wrapped by a div, this way
<div class="users">
<div>user 1 content</div>
<div>user 2 content</div>
<div>user 3 content</div>
<div>user 4 content</div>...
</div>
then all are displayed this way:
1 2 3
4 5 6
7 8 9
10 11 12
13 14 15
...... and so on
divs numbers 1,4,7,10.. should have a class called class_left for instance,
divs numbers 2,5,8,11,14.. should have a class called class_center and
divs numbers 3,6,9,12,15... should have a class called class_right
I am not quite sure how to do it.
Thank you.
You can simply do this by using modulus operator with 3.
Here is a pseudo code:
if(div_number % 3 ==1)
class = class_left;
else if(div_number % 3 == 2)
class = class_center;
else
class=class_right;
I don't know how you're using your code, but you can use modulus operator in this way: if column number modulus 3 is 1 then you're on the left, else if the result is 2 you're on the center, else with result equal 0, you're on the right.
Suppose that $data is your array of data:
<?php $aligns = array('right', 'left', 'center'); ?>
<div class="users">
<?php foreach($data as $key => $value): ?>
<div class="class_<?php echo $aligns[$key % 3]; ?>">
<?php var_dump($value); ?> // User X's Content
</div>
<?php endforeach; ?>
</div>
Maybe try this way:
var curr = 0;
users.forEach(user){
curr++;
switch(curr){
case 1:
user.class = 'class_left';
case 2:
user.class = 'class_center';
case 3:
user.class = 'class_right';
curr = 0;
}
}
This is only javascript example. Please use your language.
Try this:
$i = 1;
$last = 100;
for ($i =1; $i<$last; $i=+3) {
echo "<div class='class_left'>user ".$i." content</div>";
echo "<div class='class_center'>user ".($i+1)." content</div>";
echo "<div class='class_right'>user ".($i+2)." content</div>";
}
Or if you want a function that will take the number and return the class name you should try something like:
function getClass($num) {
if (!$num % 3) {
return 'class_right';
}
if (!($num + 1) % 3) {
return 'class_center';
}
if (!($num + 2) % 3) {
return 'class_left'
}
}
This code works for any number of div elements per row. (If you set $divsPerRow to 2, class_center will not be used. If you set it to 1, neither will class_right.)
$divsPerRow = 3;
$users = range(1, $divsPerRow * 3);
echo '<div class="users">' . PHP_EOL;
for ($i = 0; $i < count($users); $i++) {
$class = "left";
$column = $i % $divsPerRow + 1;
if ($column > 1) {
$class = ($column == $divsPerRow) ? "right" : "center";
}
echo '<div class="class_' . $class . '">user ' . $users[$i]
. ' content</div>' . PHP_EOL;
}
echo '</div>' . PHP_EOL;
What is you looking for is:
(i-1)%3 == 0

Php break the ul li

I am showing images in php in ul list. I want to show 5 li in my ul then 2 li and after that again 5 li.I am using this code but it is showing 5 li every row.
<?php
$data = array(1,2,3,4,5,6,7,8,9,10,11,12);
$break_after = 5;
$counter = 0;
$totalNumber = count($data);
foreach ($data as $item)
{
if ($counter % $break_after == 0)
{
echo '<ul>';
}
echo '<li>'.$item.'</li>';
if ($counter % $break_after == ($break_after-1) || $counter == $totalNumber-1) {
echo '</ul>';
}
++$counter;
}
dfff
fdfddf
fdfd
ffd
fdfd
fddf
dfdf
fddf
dfdf
dfdf
fddf
fddf
fdfd
fddf
fddf
fdfd
fddf
Hope this solution might help you :
When you want a break after 5,2,5 Y not take that an array array(5,2,5) instead of just break_after=5. break_after=5 will breake the ul at every 5 intervals. I have some change in logic for you :
$data = array(1,2,3,4,5,6,7,8,9,10,11,12);
$break_after = array(5,2,5);
$counter = 0;
$break_key=0;
$totalNumber = count($data);
foreach ($data as $item){
if ($counter % $break_after[$break_key] == 0){
echo '<ul>';
}
echo '<li>'.$item.'</li>';
if ($counter % $break_after[$break_key] == ($break_after[$break_key]-1) || $counter == $totalNumber-1) {
echo '</ul>';
++$break_key;
$counter = 0;
}else{
++$counter;
}
}
Output for same is :
<ul><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li></ul>
<ul><li>6</li><li>7</li></ul>
<ul><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li></ul>
To achieve what you want use the following:
<?php
$data = array(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22);
$total = count($data);
foreach ($data as $index => $item)
{
if ($index == 0 || $index == 5 || $index == 7 || ($index > 8 && ($index - 2) % 5 == 0))
{
echo '<ul>';
}
echo '<li>'.$item.'</li>';
if ($index == 4 || $index == 6 || $index == $total - 1 || ($index > 6 && ($index - 2) % 5 == 4)) {
echo '</ul>';
}
}
Pretty much the same answer as varunsinghal and Vivek Tankaria, but refactored to separate the logic and the view:
<?php
$pattern = [5, 2, 5, 5];
$data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18];
if (count($data) < array_sum($pattern)) {
throw new Exception('Please provide at least the same amount of data as lines required in the pattern');
}
?>
<?php foreach ($pattern as $limit): ?>
<ul>
<?php for ($i = 0; $i < $limit; $i++): ?>
<li><?= $data[$i]; ?></li>
<?php endfor; ?>
</ul>
<?php endforeach; ?>
For multiple values in array.
$data = array(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36);
$break_after = array(5,2,5);
$counter = 0;
$break_key=0;
$totalNumber = count($data);
foreach ($data as $item){
if ($counter % $break_after[$break_key] == 0){
echo '<ul>';
}
echo '<li>'.$item.'</li>';
if ($counter % $break_after[$break_key] == ($break_after[$break_key]-1)) {
echo '</ul>';
++$break_key;
if(count($break_after)==($break_key)){
$break_key=0;
}
$counter = 0;
}else{
++$counter;
}
}
?>
You can try this logic
<?php
$data = array(1,2,3,4,5,6,7,8,9,10,11,12);
$breakPoint=4;
$ct=1;
echo '<ul>';
foreach($data as $k=>$v){
echo '<li>'.$v.'</li>';
if($breakPoint == $k && $ct==1){
$breakPoint=$breakPoint+2;
$ct=2;
echo '</ul><br/><ul>';
}elseIf($breakPoint == $k && $ct==2){
$breakPoint=$breakPoint+5;
$ct=1;
echo '</ul><br/><ul>';
}
}
echo '</ul>';
?>
Output:
1
2
3
4
5
6
7
8
9
10
11
12
First break is at 5 so $i will be 4 then 2 elements more so $i will be 6. After this the break is required after every 5 elements, so we have 5+2+5 = 12 elements which gives $i=11 So similarly other break points will be 11 16 21 26 31 36 and so on.
<ul>
<?php
$i=0;
foreach($data as $item){
echo '<li>'.$item.'</li>';
if($i==4 || $i==6 || $i==11 || $i==16 || $i==21 || $i==26){
echo '</ul><ul>';
}
$i++;
}
?>
</ul>

Split query results in 2 div's

i have this php mysql query
<?php
$product = mysql_query('SELECT * FROM products LIMIT 6 ');
$pro = mysql_fetch_assoc($product);
?>
Now that query will return 6 products from database and what i want to do is echo 3 products inside a <div> and the other 3 products inside another <div> like this
<div class="first-3>
///Here i want to echo 3 products from the query from 1-3
<?php echo $pro['title']; ?>
</div>
<div class="second-3>
///Here i want to echo the rest 3 products of the query from 4-6
<?php echo $pro['title']; ?>
</div>
<?php
$num = 6;
$product = mysql_query('SELECT * FROM products LIMIT $num');
$firstDiv = "";
$secondDiv = "";
$i = 0;
while ($pro = mysql_fetch_assoc($product)) {
if ($i < ($num /2)) {
$firstDiv .= $pro['title'];
}
else {
$secondDiv .= $pro['title'];
}
$i++;
}
?>
And:
<div class="first-3>
<?php $firstDiv ?>
</div>
<div class="second-3>
<?php $secondDiv ?>
</div>
Iterate and output the values.
<?php
$product = mysql_query('SELECT * FROM products LIMIT 6 ');
$i = 1;
echo '<div class="first-3">';
while ( $pro = mysql_fetch_assoc($product) ) {
if ($i === 3) {
echo '</div><div class="second-3">';
}
echo $pro['title'];
$i++;
}
echo '</div>';
?>
Note that it's not safe to use mysql_query, you should be using mysqli or preferrably PDO.
mysql_fetch_assoc is used to retrieve a row in the resultset.
Doc: http://php.net/manual/es/function.mysql-fetch-assoc.php
A loop is required to iterate on each row.
A very simple example:
// Get a collection of 6 results
$products = mysql_query('SELECT * FROM products LIMIT 6 ');
// iterate over the 6 results
$i=0;
echo '<div class="first-3>';
while ($pro = mysql_fetch_assoc($products)) {
$i++;
// Print an item
echo $pro["title"];
// If 3 items are printed end first div and start second div
if($i==3){
echo '</div><div class="second-3">';
}
}
echo '</div>';
// Free the collection resources
mysql_free_result($products);
Just set up a counter to divide in groups of 3:
$count = 0;
while (...)
{
// your code
$count++;
if ( ($count % 3) === 0 )
{
echo '</div><div class="...">';
}
}
Please note that the mysql_* functions are deprecated and you should switch to PDO or mysqli.
$product = mysqli_query($conn, 'SELECT * FROM products LIMIT 6 ');
$results = array();
while($pro = mysqli_fetch_assoc($product)) {
$results[] = $pro;
}
echo '<div class="first-3">';
for($i = 0; $i < 3; $i++) {
echo $results[$i]['title'];
}
echo '</div><div class="second-3">';
for($i = 3; $i < 6; $i++) {
echo $results[$i]['title'];
}
echo '</div>';
Everytime you get the multiple of 3, ($k % 3 == 0) you will increment the flag variable, you can do then some conditions with the variable flag, i used here iterators because the hasNext() beauty.
Example
$pro = array(1, 2, 3, 4, 5, 6);
$flag = 0;
$pro = new CachingIterator(new ArrayIterator($pro));
foreach ($pro as $k => $v) {
// if multiples 3
if ($k % 3 == 0) {
$flag++;
if ($flag == 1) {
echo '<div class="first-3" style="border:1px solid black;margin-bottom:10px;">';
} else if ($flag == 2) {
echo '</div>'; // Closes the first div
echo '<div class="second-3" style="border:1px solid red">';
}else{ // if you have more than 6
echo '</div>';
}
}
// insert Data
echo $v . '<br/>';
if (!$pro->hasNext())
echo '</div>'; // if there is no more closes the div
}

Most Efficient Way to Parse Array Into HTML Structure

For the sake of simplicity let's say I have the following array:
$a = array();
$a[0]['lab'] = 1;
$a[0]['name'] = 'test1';
$a[1]['lab'] = 1;
$a[1]['name'] = 'test2';
$a[2]['lab'] = 2;
$a[2]['name'] = 'test3';
$a[3]['lab'] = 2;
$a[3]['name'] = "test4";
$a[4]['lab'] = 2;
$a[4]['name'] = "test5";
Keep in mind that the length of that array is completely variable and the number of items associated with each lab can vary as well. There might be one per lab there might be 100.
My desired HTML structure is the following:
<div class="parent"> <!-- Records for lab == 1 -->
<div class="child">test1</div>
<div class="child">test2</div>
</div>
<div class="parent"> <!-- Records for lab == 2 -->
<div class="child">test3</div>
<div class="child">test4</div>
<div class="child">test5</div>
</div>
I currently have a for loop with a bunch of extra logic now which is ugly/inefficient and occasionally misses the closing tag for the last "parent" div. I know there is a far more elegant way to do this and I would love to see what others have come up with.
** Edit:
Here is the logic I have in place now which is actually working for the test cases I have thrown at it but it looks horrible:
<?php
$labId = 0;
for($i = 0; $i < count(a); $i++)
{
if(($i+1) < count($a)) { $j = $i + 1;}
if($labId == 0 || $labId != $a[$i]['lab'])
{
echo '<div class="parent">';
}
echo '<div class="child">'.$a['name'].'</div>';
if(($a[$j]['lab'] != $labId && $a[$i]['lab'] != $labId && $labId != 0) || count($a) == 1)
{
echo '</div>';
}
$labId = $a[$i]['lab'];
}
?>
I would do it like this:
$a = ... // copied from your code
$newArray = array();
foreach($a as $e){
$newArray[$e['lab']][] = $e['name'];
}
foreach($newArray as $lab){
echo "<div class=\"parent\">\n";
foreach($lab as $child){
echo "\t<div class=\"child\">".$child."</div>\n";
}
echo "</div>\n";
}
Hope that's simple enough.
The code below should do the trick without creating a new array
foreach ($a as $key0 => $labs) {
foreach ($labs as $key1 => $value) {
if ($key1 == 'lab') {
echo '<div class="parent">';
} else {
echo '<div class="child">'.$value.'</div>';
}
}
//Close parent divs
if (isset($key0['lab'])) {
echo '</div>';
}
}
My solution was somewhat of a combination of the responses and some other trial and error.
<?php
// define original test array
$a = array();
$a[0]['lab'] = 1;
$a[0]['name'] = 'test1';
$a[1]['lab'] = 1;
$a[1]['name'] = 'test2';
$a[2]['lab'] = 2;
$a[2]['name'] = 'test3';
$a[3]['lab'] = 2;
$a[3]['name'] = "test4";
$a[4]['lab'] = 2;
$a[4]['name'] = "test5";
// new array has to be defined outside the foreach() loop, or it will be treated as a local var
$anew = array();
// for each entry, assign to $anew[lab#][next_avail_entry#]['name'] = <value>
foreach ($a as $arec)
$anew[$arec['lab']][]['name'] = $arec['name'];
// output: one parent div for each lab, plus subdivs for as many values as are avail for each lab
foreach ($anew as $alab)
{
printf("<div class=\"parent\">\n");
foreach ($alab as $arec)
printf(" <div class=\"child\">%s</div>\n", $arec['name']);
printf("</div>\n");
}
?>
* Edit: One other solution I found was to query for the labs and items separately and loop through the lab as the outer loop and the items as an inner foreach loop.

Categories