I am displaying a listing of TV shows on a website in rows with three columns per row. When I do not have enough shows in multiples of three, I want to fill the empty slots with alternate content.
The code I am using to display the listing is:
<?php $counter = 1; ?>
<?php foreach ($show_listingsRecords as $record): ?>
<?php if($counter % 3 == 0) : ?>
<!-- ROW 3 -->
<div> ... display name + description + link ...</div>
<?php elseif ($counter % 3 == 2) : ?>
<!-- ROW 2 -->
<div> ... display name + description + link ...</div>
<?php elseif ($counter % 3 == 1): ?>
<!-- ROW 1 -->
<div> ... display name + description + link ...</div>
<?php endif; ?>
<?php $counter++; ?>
<?php endforeach ?>
I've tried to insert the following conditional statement, but it does not work because the foreach() loop dictates the number of records to be displayed. How do I achieve displaying alternate content if slots 2 or 2 & 3 are empty?
<?php if(!$show_listingsRecords): ?>
Display my alternate content
<?php endif ?>
I would recommend doing all of the processing first and then only using foreach() to display it.
The first step is checking what kind of modification is needed to prepare your $show_listingsRecords array.
If there are no subarrays, then you will need to use all three $alternates subarrays.
If the number of subarrays does not evenly divide by $chunk_size (number of subarrays per batch), then merge only the necessary amount of subarrays from $alternates to complete the "batch".
Code: (Demo)
$show_listingsRecords=array(
array("name"=>1,"description"=>2,"link"=>3),
array("name"=>4,"description"=>5,"link"=>6),
array("name"=>7,"description"=>8,"link"=>9),
array("name"=>10,"description"=>11,"link"=>12),
array("name"=>13,"description"=>14,"link"=>15)
);
$alternates=array(
array("name"=>"backup1A","description"=>"backup1B","link"=>"backup1C"),
array("name"=>"backup2A","description"=>"backup2B","link"=>"backup2C"),
array("name"=>"backup3A","description"=>"backup3B","link"=>"backup3C") // needed if no listings at all
);
$chunk_size=3; // 3 is used in this case
// conditionally prepare array
if(!$size=sizeof($show_listingsRecords)){ // if no listings at all (empty array)
$show_listingsRecords=$alternates;
}elseif($over=$size%$chunk_size){ // $over is how many extra elements beyond "even" (0,1,2 in this case)
$show_listingsRecords=array_merge($show_listingsRecords,array_slice($alternates,0,$chunk_size-$over));
}
// display
foreach(array_chunk($show_listingsRecords,$chunk_size) as $batch){ // iterate in batches
echo "<div>\n";
foreach($batch as $listing){ // iterate the arrays in the batch
echo "\t<div>",implode(' + ',$listing),"</div>\n";
}
echo "</div>\n";
}
Output:
<div>
<div>1 + 2 + 3</div>
<div>4 + 5 + 6</div>
<div>7 + 8 + 9</div>
</div>
<div>
<div>10 + 11 + 12</div>
<div>13 + 14 + 15</div>
<div>backup1A + backup1B + backup1C</div>
</div>
You could add another loop after your code:
//As long as there is some remainder
while($counter % 3) {
//add desired content
switch($counter++ % 3) {
case 1: break;
case 2: break;
}
}
A would also suggest you use a constant/variable instead of magic number 3. If you decide to use 4 columns in the future all you need to do is change the variable and add conditions for the fourth column instead of manually checking and rewriting the "correct" numbers 3 (find and replace could change number 3 in other part of your code you do not want to change).
Related
My count loop currently works but it is not working correctly. I need every second item to go into the right column and the rest stay in the left. So 1, 3, 5 etc in the column called split-left and 2, 4, 6 to go into the column called split-right
<!-- SPLIT EFFECT PAGE BUILDER -->
<div class="page-builder">
<?php if( have_rows('split_effect_page_builder') ): ?>
<div class="split-left">
<?php $i = 1; ?>
<?php while ( have_rows('split_effect_page_builder') ) : the_row(); ?>
<?php get_template_part('template-parts/page', 'builder'); ?>
<?php
if($i % 2 == 0){
echo '</div><div class="split-right">';
$i = 0;
}
$i++;
?>
<?php endwhile; ?>
</div>
<?php else : ?>
<?php // no layouts found ?>
<?php endif; ?>
</div>
<!-- END SPLIT EFFECT PAGE BUILDER -->
Seems you just need to reset your counter whenever it reaches 2..
<?php
if($i == 2){
echo '</div><div class="split-right">';
$i =0; // set back to zero...
}
$i++; // and now it's 1 again so next iteration would be left aligned
?>
PS.. not sure why you close a PHP tag only to immediately re-open it.. That won't break anything, but probably a good habit to get rid of.
Below is my Code.
<?php
$folder_name=$_GET['folder_name'];
$dirname = "customized_kits/images/";
$images = glob($dirname."*");
$filecount = count( $images );
$i=0;
for($i=0;$i<200;$i++) { ?>
<div class="col-md-2"> <div class="photos">
<div id="images1">
<a href=# data-lightbox="roadtrip">
<?php
if($filecount>$i) {
$filename = substr($images[$i], strrpos($images[$i], '/') + 1);
echo '<img src="'.$images[$i].'" style="width:150px;height:150px" /><br/>';
?>
<i class="fa fa-remove"></i>
<?php } else {
echo '<a ><img style="width:150px;height:150px;background-color:#eee" /></a>';
} ?>
</div>
</div>
</div>
<?php } ?>
Here I created 200 boxes with foreach loop I want to show 20 divs for single page and with help of pagination I want to show other divs.I searched in many websites I didnt get exact answer please help me to get out of this issue.
Okay so from your code you can have 200 values of $i and you want to paginate them in segments of 20. Let us start off by adding a script above your code to get the range that needs to be displayed. Page number comes as a GET parameter in number. ex example.com/feeds?number=2.
<?php
$pageno = $_GET['number']; // Page number from frontend
// Now this value will give you 1,2,3 etc
$start = $pageno*20;
// $start contains the initial offset or the value of `$i` from to start
for($i=$start;$i<$start+20;$i++) {
// Will only show 20 elements on the page
}
?>
Remember this is a very basic example. Although i would recommend using range in sql query instead so you don't have to load the complete dataset in each query.
More explanation
Suppose you have M results and you want to show N results on each page, the results on page x would start from x*N to x*(N+1) pure math here. In your code you are iterating $i over the whole loop rather just iterate over that specific range to get results. The value of x is the example is the page number that we get from number in GET verb.
I want to build a layout where I show teasers of two different content type (A-B).
The teasers will be just images, where 1 teaser of content type A is the half in height of content type B and I would like to have for each row 3 columns.
So first and last columns with 2 teaser each of content type A and the center column with one teaser of content type B. 1A-1A -- 1B -- 1A-1A.
I used the following code in the views-view-unformatted.tpl.php to have the correct layout structure (probably I should have done this on template.php)
<?php foreach ($rows as $id => $row): ?>
<?php if($id % 5 == 0){ print '<div class="row">'; } ?>
<?php if($id % 5 == 2){ print '<div class="col-center">'; } ?>
<div class="<?php print $classes_array[$id]; ?>"><?php print $row; ?></div>
<?php if($id % 5 == 2){ print '</div>'; } ?>
<?php if($id % 5 == 4){ print '</div>'; } ?>
<?php endforeach; ?>
Now I get stuck on giving the order to the content type to display, so telling views that two first teasers have to be content type A, center one is content type B, last two content type A.
Here a screenshot of how should look like the layout, so maybe is easier to understand :) screenshot layout
Any suggestion will be appreciate! Thanks for reading
That`s a wrong way of doing it.
Do your operations in pre render function and then render variables in tpl file.
URL: hook_views_pre_render
How to show 3 random divs on 3 random places
I have 6 potentionaly places for divs.
All 6 divs need to be hidden for now.
When page load I need to show only 3 random divs, and another 3 divs need to be hidden.
<?php
$divs = array('<div id="divFirst">First Div</div>','<div id="divFirst">Second Div</div>','<div id="divFirst">Third Div</div>');
// Array with 3 random keys from $divs
$randKeys = array_rand($divs, 2);
//echo $divs[$randKeys[0]]; // First random div
//echo $divs[$randKeys[1]]; // Second random div
//echo $divs[$randKeys[2]]; // 3rd div
//shuffle($divs);
?>
<div class="text">This is a simple text</div>
<?php echo $divs[$randKeys[0]]; ?>
<div class="text">This is a simple text</div>
<?php echo $divs[$randKeys[1]]; ?>
<div class="text">This is a simple text</div>
<?php echo $divs[$randKeys[2]]; ?>
<div class="text">This is a simple text</div>
<?php echo $divs[$randKeys[1]]; ?>
<div class="text">This is a simple text</div>
<?php echo $divs[$randKeys[0]]; ?>
<div class="text">This is a simple text</div>
<?php echo $divs[$randKeys[2]]; ?>
Look at this: $randKeys = array_rand($divs, 2);
The second parameter specifies the number of items you want out of the array. You want 3, but you told it you want 2.
Then you're doing <?php echo $divs[$randKeys[2]]; ?> That is, trying to print the third element from the array (i.e. arrays start counting at 0). But you only have 2 elements in the array now.
Also, it would make more sense to only keep the contents of the divs in your array. Then you can do like:
$randKeys = array_rand($divs, 6);
//because you want 3 shown, 3 hidden, thus 6
for($i=0; $i<6; $i++)
{
$style='display: block';
if($i>=3)
{
//we hide the last 3
$style='display: none';
}
echo "<div id='div_$i' style='$style'>" . $divs[$randKeys[$i]] . "</div>";
}
That solves the problem mentioned in the comments about your div ids not being unique.
However, in order to pick 6, you need to actually have 6 elements in the $divs array because the docs for array_rand() state:
Trying to pick more elements than there are in the array will result in an E_WARNING level error, and NULL will be returned.
So what I'm trying to do is select all the distinct months from my database and then print them in a list. That, I can accomplish. The problem lies in the fact that I need my list to be two column. The way that I achieve this with CSS is by using 2 different div's "left" and "right" which are floated next to each other. This poses a problem with PHP because it needs to echo a div close and a new div open after it echoes the sixth month. Then it needs to start again from where it left off and finish. I can't just list all of the months in the HTML, either because I don't want it to list a month if I don't have any records in the DB for that month, yet. Any ideas? I hope I was clear enough!
Thanks!
-williamg
Something like this should work (the basic idea being to just keep a count of the months an increment it as you loop through them):
<div class="left">
<?php
$x = 1;
foreach($months as $month) {
# switch to the right div on the 7th month
if ($x == 7) {
echo '</div><div class="right">';
}
echo "<div class=\"row\">{$month}</div>";
# increment x for each row
$x++;
}
</div>
<?php
$numberOfMonths = count($months);
$halfwayPoint = ceil($numberOfMonths / 2);
echo "<div class=\"left\">";
for($i=0; $i<$halfwayPoint; $i++){
echo $months[$i] . "<br />";
}
echo "</div><div class=\"right\">";
for($i=$halfwayPoint; $i<$numberOfMonths; $i++){
echo $months[$i] . "<br />";
}
echo "</div>";
?>
Rant: on
When displaying tabular data, use table instead of floating div. It will make sense when viewing the page with css disabled. If you use floated div, then you data will displayed all way down. Not all table usage is bad. People often hate table so much, so using floated div. Table only bad when used for page layout.
Rant: off
When I need to have certain content displayed with some open, close, and in-between extra character, I will make use of implode. This is the example:
$data = array('column 1', 'column 2');
$output = '<div>'.implode('</div><div>', $data).'</div>';
//result: <div>column 1</div><div>column 2</div>
You can extends this to almost anything. Array and implode is the power that php have for many years. You will never needed any if to check if it last element, then insert the closing character, or check if it first element, then insert opening character, or print the additional character between elements.
Hope this help.
Update:
My bad for misread the main problems asked. Sorry for the rant ;)
Here is my code to make a data displayed in 2 column:
//for example, I use array. This should be a result from database
$data = array(1, 2, 3, 4, 5, 6, 7, 8, 9);
//should be 12 month, but this case there are only 9 of it
for ( $i = 0; $i <= 5; $i++)
{
//here I do a half loop, since there a fixed number of data and the item for first column
$output = '<div class="left">'.$data[$i].'</div>';
if ( isset($data[$i+6] )
{
$output = '<div class="right">'.$data[$i+6].'</div>';
}
echo $output."\n";
}
//the result should be
//<div class="left">1</div><div class="right">7</div>
//<div class="left">2</div><div class="right">8</div>
//<div class="left">3</div><div class="right">9</div>
//<div class="left">4</div>
//<div class="left">5</div>
//<div class="left">6</div>
Other solution is using CSS to format the output, so you just put the div top to down, then the css make the parent container only fit the 6 item vertically, and put the rest to the right of existing content. I don't know much about it, since it usually provided by fellow css designer or my client.
Example assumes you have an array of objects.
<div style="width:150px; float:left;">
<ul>
<?php
$c = count($categories);
$s = ($c / 3); // change 3 to the number of columns you want to have.
$i=1;
foreach($categories as $category)
{
echo '<li>' . $category->CategoryLabel . '</a></li>';
if($i != 0 && $i % $s == 0)
{
?>
</ul>
</div>
<div style="width:150px; float:left;">
<ul>
<?php
}
$i++;
}
?>
</ul>
</div>