I have this code:
<div class="big">
<div class="small">
<img src="images/icons/AC.png" />
AC & Refrigeration
</div>
<div class="small">
<img src="images/icons/AC.png" />
AC & Refrigeration
</div>
</div>
The code is such that the class='big' has to be repeated to show the icons enclosed in the class='small'.
the class-'small' is to display only 2 icons inside the div for class='big' once the two icons in the class='small' has displayed two icons, the div big has to be repeated. the same shall continue for about 80 icons.
please suggest how i can use a counter variable (e.g. one that begins with 1, increments to 2 and then resets to 1). Use the counter value to wrap two folder items (i.e. div class="small" ../div) within the div class="big"../div.
Provided an even number of icons, something like this would work:
<?php
$counter = 0;
foreach( $icons as $icon ) {
if ( $counter % 2 == 0 ) echo '<div class="big">';
?>
<div class="small">
<img src="<?= $icon->src ?>" />
<?= $icon->name ?>
</div>
<?php
if ( $counter % 2 == 1 ) echo '</div>';
$counter++;
}
?>
You'd have to add a little extra code to account for odd cases in necessary. The trick is to keep track of when you are on an even or odd icon with $counter % 2
Related
I have a structure of divs that are generated based on php code. Each row has 3 divs. It is generated like this:
Defining columns:
<?php
$numOfCols = 3;
$rowCount = 0;
$bootstrapColWidth = 12 / $numOfCols;
?>
First row, starting the loop and defining width:
<div class="row">
#foreach($datas as $data)
<div class="col-md-<?php echo $bootstrapColWidth; ?>">
Then there's a bunch of content.
Then, in the end, each loop adds one to rowcount, and checks if the row has ended, so we can add a new one:
<?php
$rowCount++;
if($rowCount % $numOfCols == 0) echo '</div><div class="row">';
?>
#endforeach
Now, it all works great, the problem is that as I add different amounts of content on each div, the heights become different and ends up becoming quite ugly.
What I'm trying to do: I'm trying to check in each row which div has the biggest height, so I can apply the same height to the other two.
-I've thought of adding a id to each div that increments, problem is I don't know how many divs there will be, so I can't prepare for each outcome.
-I've tried selecting each row with $('row div'), problem is then all divs will become the same size as the biggest of all. And I want to check by row.
Sorry for the long question, and thanks for any input!
Bootstrap 4 has flexbox classes that allow you to do this with just css. Take a look at this example: https://getbootstrap.com/docs/4.3/utilities/flex/#align-self
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet"/>
<div class="d-flex">
<div class="align-self-stretch mr-3" style="background-color:lightblue">Aligned flex item</div>
<div class="align-self-stretch mr-3" style="background-color:lightblue">Aligned flex item<br />With<br />More<br />Lines</div>
<div class="align-self-stretch" style="background-color:lightblue">Aligned flex item</div>
</div>
I think flex-box is your solution : all into flex container will have the same height.
<div style="display:flex">
<div>
... some content
</div>
<div>
... some content
</div>
</div>
You can use .row-eq-height in Bootstrap 4
I want to create a loop for my posts which wraps a and class to every three posts group. The tricky part is that there are 3 different classes which need to keep looping.
So, basically it should create a div with a class of "right" wrapping around the first 3 posts and then a second div with a class of "left" wrapping around the next 3 and a third div wrapping around the next 3 ones after that.
This pattern needs to repeat as the posts go on.
It will look something like this:
<div class="right">
<div>Post 1</div>
<div>Post 2</div>
<div>Post 3</div>
</div>
<div class="left">
<div>Post 4</div>
<div>Post 5</div>
<div>Post 6</div>
<div class="inner-div"></div>
</div>
<div class="middle">
<div>Post 7</div>
<div>Post 8</div>
<div>Post 9</div>
<div class="inner-div"></div>
</div>
And repeat
Ive tried this: PHP loop: Add a div around every three items syntax But its only adding the first class and then repeating the second class.
I have modified the reference answer you linked to fit according to your requirement.
Original answer: PHP loop: Add a div around every three items syntax
<?php
$i = 1;
$j = 0;
$target_class = array( 'right', 'left', 'middle' );
//added before to ensure it gets opened
echo '<div class="'.$target_class[$j].'">';
if ( $wp_query->have_posts() ) : while ( $wp_query->have_posts() ) : $wp_query->the_post();
// Do whatever you want here.
// if multiple of 3 close div and open a new div
if($i % 3 == 0) {
// echo inner div if target class is not right
echo ( $j != 0 ? '<div class="inner-div"></div>' : '' );
// send back to first position if it goes above the third position
$k = ( ++$j == 3 ? 0 : $j );
echo '</div><div class="'.$target_class[$k].'">';}
$i++; endwhile; endif;
//make sure open div is closed
echo '</div>';
?>
This should work. Did not test it though.
Edit: Tested and fixed. Code is working
Edit: 2 Update code to entertain request from comment.
Edit: 3 Update code to entertain request from comment.
I am displaying information in a card-based layout, but if any title in the card is longer than 41 characters, it doesn't fit into the card.
I thought about using [wordwrap], but all that would do is cause the one specific title to wrap and change the height of that card, affecting the layout of the other cards.
This is the PHP I use to print my results for pagination purposes, so it only prints 9 things at a time.
<div class="row">
<?php
while ($row = mysql_fetch_assoc($rs_result)) {
?>
<div class="col xl4 l4 m12 s12">
<div class="card z-depth-5">
<div class="card-content">
<p><? echo $row["title"]; ?></p>
<p>Category: <? echo $row["category"]; ?></p>
</div>
</div>
</div>
<?php
};
?>
</div>
How would I go about line breaking every title if even one title is detected as longer than 41 characters?
EDIT: This is the solution I created:
$titlebreak = $row["title"];
if (strlen($titlebreak) >= 40)
{
$titlebreak2 = wordwrap($titlebreak, 39, "</p><p>");
}
else
{
$titlebreak2 = $row["title"] . "<p> </p>\n";
}
I've included 3 possible solutions below - adding manual line breaks as you asked about in your question; a basic but unsatisfactory CSS option and a jQuery solution which in this case is the one I would suggest as the most flexible.
Although a CSS-only solution is usually the preferred way of fixing a layout issue, when it comes to equal heights of elements there isn't a clear-cut way to do it and often a jQuery solution like the one below is required.
Manual line-break - as requested in your question
Instead of doing an additional SQL query as mentioned, you can easily do it in the PHP in 2 different ways:
(a) loop through the rows before displaying them to calculate the title lengths, then loop again to display with/without the line break
or
(b) if you really down't want to loop twice, you could include the line break regardless of length as you loop once, but also calculate the line length in that loop. Then hide the line break using CSS if its not required
(a) 2 loops: Calculate length to determine whether to add the line break or not:
<?php
$maxchars = 41;
$cards = array();
$bLongTitle = false;
while ($row = mysql_fetch_assoc($rs_result)) {
// save detaisl to $cards array
$cards[$row["title"]] = $row["category"];
// check title lengths until we find one over 41 - no need to check any more after that
if (!$bLongTitle && strlen($row["title"])) > $maxchars)
$bLongTitle = true;
}
?>
<div class="row">
<?php
foreach ($cards as $title => $category) {
?>
<div class="col xl4 l4 m12 s12">
<div class="card z-depth-5">
<div class="card-content">
<p><?
// if there were any long title, wrap them all text
if ($bLongTitle)
$title = wordwrap($title, $maxchars, "<br />\n");
echo $title;
?></p>
<p>Category: <? echo $category; ?></p>
</div>
</div>
</div>
<?php
}
?>
</div>
(b) 1 loop: Always display line break, and hide it if not required
<div class="row">
<?php
$bLongTitle = false;
while ($row = mysql_fetch_assoc($rs_result)) {
?>
<div class="col xl4 l4 m12 s12">
<div class="card z-depth-5">
<div class="card-content">
<p class="cardTitle"><? echo wordwrap($title, $maxchars, "<br />\n"); ?></p>
<p>Category: <? echo $row["category"]; ?></p>
<?php
// check title lengths until we find one over 41 - no need to check any more after that
if (!$bLongTitle && strlen($row["title"])) > $maxchars)
$bLongTitle = true;
?>
</div>
</div>
</div>
<?php
};
?>
</div>
<?php if ($bLongTitle) {?>
<script>.cardTitle br {display:none;}</script>
<?php } ?>
CSS-only solution - not viable for the OP?
Because the titles are aren't direct siblings, the only way would be to fix the height of all title. This isn't a desirable solution, as I'm sure titles can vary a lot in length so its impossible to pick a "default" height to suit every possibility, and even that's complicated by the responsive width of the columns potentially changing the heights dynamically.
But for the sake of completeness:
add a class (e.g. .cardTitle) to the title in your loop
identify suitable heights for the title with and without a line break, and set these in your CSS
add the corresponding class (e.g. wrapTitle) to your <p> if any title is too long in a loop (similar to adding a line break above)
CSS
p.cardTitle { height:20px; } /* example of the default height for title */
p.cardTitle.wraptitle { height:40px; } /* example of height for wrapped title */
PHP (after looping through SQL rows to fill $cards array as option (a) above)
<?php
foreach ($cards as $title => $category) {
?>
<div class="col xl4 l4 m12 s12">
<div class="card z-depth-5">
<div class="card-content">
<p class="cardTitle <?php if ($bLongTitle) echo "wrapTitle"; ?>"><? echo $title; ?></p>
<p>Category: <? echo $row["category"]; ?></p>
</div>
</div>
</div>
<?php
};
?>
jQuery
You could use jQuery to loop through all elements to calculate the heights, and set them all to the tallest.
You could write the code yourself (see How to make all div columns of the same height automatically with jQuery or Setting equal heights for div's with jQuery but there is a library available to do this for you: matchHeight
Using the library, all you need to do is include it on your page and call it like this (assuming you've added the class cardTitle to the <p> that holds your title)
jQuery(document).ready(function() {
$(".cardTitle").matchHeight();
});
I would perform a new SQL query first to see if any results have a title length of greater than 41 characters:
select count(*) from table where length(title)>41
And then set the result of this query to be a variable, e.g. $has41
You can then use an if statement within your loop ...
if($has41) {
// do something with $row['title']
} else {
// do something else with $row['title']
}
I have a series of repeatable div's where the user can go in and add as many as they want, I just want to number the div's. The idea I have now is to use PHP to count them and echo the number from 1 to infinity with 1 being the first div and so on.
I'm not sure how this works, but I think we have to start with some math?
<?php $i = 0; ?>
...and then something about foreach div.tiles-wrap echo $i + 1...?
<div class="tiles-horizontal">
<div class="tiles-wrap">
<div class="title"><p class="center"><?php echo i; ?></p></div>
<div class="image"><img src="#" /></div>
</div>
</div>
Thanks in advance for any help!
After display count number in each div you need to increment $i value, like this:
<div class="tiles-horizontal">
<div class="tiles-wrap">
<div class="title"><p class="center"><?php echo $i; ++$i;?></p></div>
<div class="image"><img src="#" /></div>
</div>
</div>
Put:
<?php $i++; ?>
at the bottom of the loop body to increment the counter variable.
This really is not any kind of math problem just very simple programming. If you wish to accomplish this with php you will need something like
Lets say you have a button they press each time they wish to add another div in php we take care of it like this:
Forgot to add we need a Session variable to keep track of it
if(isset($_POST['submitbutton']))
$_SESSION['count']++;
...
After you only need to do a for loop and echo out as many div's as you need like this
<?php for($i=0; $i<$_SESSION['count'];$i++): ?>
<div>
<p> Div Number <?php echo $i ?> </p>
</div>
<?php endfor ?>
And thats it you may also need to add a button like this :
<form action="" method="POST">
<input type="submit" name="submitbutton" value="Click to add div" />
</form>
every second item needs to be on right side of the page, but inline with first item, so it would create 2x2 type grid of both echoed items.
I added some CSS like this
.container{float:left; width:50%;} but it didn't work.
if ($file6 % 2 == 1)
{
echo '<div id="container">
<div id="thumbnail">
<img src="/images/tirgus/thumbs/'.$row['id'].'.jpeg" width="141" height="74" alt="image" />
</div>
<br>
<div id="info1"><sub>' .cleanString($file2).'</sub></div>
<br>
<div id="info2"><sub>Telefons: ' .cleanString($file3). '</sub><br><sub>email: '.cleanString($file4).'</sub></div><br>
<div id="info3"><sub>Iepostoja:</sub> ' .cleanString($file5). '</div><br>
</div><widgets><customization><css> <link rel="stylesheet" href="template_faili/gallery.css"></css></customization></widgets>';
}
else if ($file6 % 2 == 0) {
echo '<div id="container2">
<div id="thumbnail2">
<img src="/images/tirgus/thumbs/'.$row['id'].'.jpeg" width="141" height="74" alt="image" />
</div>
<br>
<div id="info1"><sub>' .cleanString($file2).'</sub></div>
<br>
<div id="info2"><sub>Telefons: ' .cleanString($file3). '</sub><br><sub>email: '.cleanString($file4).'</sub></div><br>
<div id="info3"><sub>Iepostoja:</sub> ' .cleanString($file5). '</div><br>
</div><widgets><customization><css> <link rel="stylesheet" href="template_faili/gallery.css"></css></customization></widgets>';
}
}
.container{float:left; width:50%;}
will be want you want. FYI, please DO NOT use duplicate ids in your html.
In the interest of showing how you would use a modulo to achieve this, you would want to do something like:
foreach($files as $file_count => $file) {
if ($file_count % 2 == 0)
{
echo '<div class="thumb row">';
}
echo '
<div class="container">
<div class="thumbnail">
<a href="/images/'. $file .'" title="'.cleanString($file).'" class="thickbox">
<img src="/images/'.$row['id'].'.jpeg" width="141" height="74" alt="image" />
</a>
</div>
<br />
<div id="info"><sub>' .cleanString($file2).'</sub></div>
<br />
<div id="info"><sub>text ' .cleanString($file3). '</sub><br><sub>email: '.cleanString($file4).'</sub></div>
<br />
<div id="info"><sub>text </sub> ' .cleanString($file5). '</div>
<br />
</div>';
if ($file_count % 2 == 1)
{
echo '</div>';
}
}
Note that the above will probably not work as-is with your script because I am using a made up array that loops with the value $file while your code appears to have the various values in separate arrays. The overall idea is this:
foreach($files as $file_count => $file) {
Loops over each image/file you are wanting to output, starting at 0, so that :
$file_count % 2 == 0
indicates the first of two pair and
$file_count % 2 == 1
indicates the second of two pair.
So before the first of two are output, you start a container div such as:
<div class="thumb row">
Then you output your interior html as you already are, using the same html for both thumbnails.
and after the second of two are output, you close that div via:
</div>
Now each two of your thumbnail divs are wrapped in the thumb row container div, allowing you to apply css such as:
.thumb.row .container {
display: inline-block;
}
which will line them up side by side but still break on the outer row div.
Also, in addition to this being an ill-advised approach, you should not be setting the id attribute inside a loop, as this will set the same id to multiple elements, which is invalid HTML. Instead, update the code to use class which can be applied to multiple elements.
Each div need to use different classes/ids, where the inline behavior is defined or not.
$col[0] = 'class1';
$col[1] = 'class2';
for ($i=0; $i<$count; $i++) {
$output .= '<div class="'. $col[$i%2] . ' >';
}