Reputation: 437
I'm currently in developing module shop for the company I work for and there is a little problem. While extracting records from the table, I want for every third data record to close HTML "UL" tag.
This is what I currently have:
<?php
$selektKat = "SELECT * FROM `proizvodi` WHERE `kategorija` = '$kat'"; //don't worry about SQLi; I will fix it
$result = mysqli_query($con, $selektKat) or die(mysqli_error());
// Line where the loop starts
<?php
while ($row = mysqli_fetch_array($result)) { ?>
<ul class="products-grid clearfix" style="margin-right: 5px; margin-left: 20px;">
<li class="item" style="min-height: 339px">
<a id="product-image-42321" href="proizvod.php" title="naziv" class="product-image">
<img src="http://static.511tactical.com/mag/media/catalog/product/cache/1/small_image/220x/9df78eab33525d08d6e5fb8d27136e95/5/3/53212_716_Alternate1.jpg" width="220" alt="<?php echo $row['naziv'] ?>" />
</a>
<ul class="swatches clearfix">
<li id="swatch-228" class="swatch product-42321">
<a href="proizvod.php" title="<?php echo $row['naziv']; ?>">
<img src="<?php echo __DIR__ . '/images/' . $row['slika'] . '.jpg'; ?>" />
</a>
</li>
</ul>
<div class="price-box">
<span class="label" id="configurable-price-from-42321">
<span class="configurable-price-from-label">
</span>
</span>
<div class="product-name"><a id="product-name-140981" href="proizvod.php"><?php echo $row['naziv']; ?></a></div>
<span class="regular-price" id="product-price-42321">
<span class="price"><?php echo $row['cijena']; ?><sup>KM</sup>
</span>
</span>
</div>
<div class="actions">
</div>
</li>
<?php
}
?>
</ul> // This has to be closed in loop after every 3 records
</div>
Picture:
Cheers.
Upvotes: 3
Views: 2937
Reputation: 10202
You specifically ask for opening and closing <ul>
tags, but may I suggest an alternative, using only css, which can be easily converted into a responsive solution?
To start with, just put your items in a div instead of an list item (omitting the <ul>
altogether):
<div class="product-grid">
<?php while ( $row = mysqli_fetch_array( $result ) ): ?>
<div class="item"> ... </div>
<?php endwhile; ?>
</div>
Now just use plain old css to float the grid and add margins in between the columns. Then using the nth-of-type
pseudo-selector we can clear the margin on the nth
element, depending on how many items you want in a row.
Always-3-column-grid example (Fiddle)
.product-grid { width: 100%; }
.product-grid .item { float: left; width: 32%; margin-left: 2%; margin-bottom: 2%; }
.product-grid .item:nth-of-type(3n+1) { margin-left: 0; }
Now the items are placed nicely in a grid, and it doesn't matter at all how wide the container is.
Fiddle note: the overflow: hidden
is a kind of clearfix to show the border. It also works without it.
Now if you want, for instance, add breakpoints to show a 2-column grid instead of a 3-column grid on smaller devices, just change the width of the item and the counter of the pseudo selector. I've put the 3-grid counter in a media query as well, so you don't have to overwrite that one.
3-to-2-column-grid example (Fiddle)
Don't forget to resize the example panel to see the responsive result ;)
.product-grid { width: 100%; }
.product-grid .item { float: left; width: 32%; margin-left: 2%; margin-bottom: 2%; }
/* 3-column */
@media (min-width: 501px) {
.product-grid .item:nth-of-type(3n+1) { margin-left: 0; }
}
/* 2-column. Don't forget to alter the item width accordingly */
@media (max-width: 500px) {
.product-grid .item { width: 49%; }
.product-grid .item:nth-of-type(2n+1) { margin-left: 0; }
}
And here you go! Your fully responsive 3-to-2-column grid :) Just alter the breakpoints to your needs, and the width and margin sizes (just to make sure that in a 3-column version 3*columnWidth + 2*marginWidth
adds up to 100%, and 2*columnWidth + marginWidth
for the 2-column version).
Upvotes: 1
Reputation: 111839
First, I provide simple PHP script that can be addapted to your needs. In this script open and end tags are handled properly.
I added also $break_after
variable - you can set here any positive value you want - in your case it's 3 because you want to do the action after each 3rd element.
First method (it assumes you can get number of data elements before loop)
<?php
$data = array(1,2,3,4,5);
$break_after = 3;
$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;
}
Second method (it assumes you cannot get number of data elements before loop)
<?php
$data = array(1,2,3,4,5);
$break_after = 3;
$counter = 0;
foreach ($data as $item) {
if ($counter % $break_after == 0) {
echo '<ul>';
}
echo '<li>'.$item.'</li>';
if ($counter % $break_after == ($break_after-1)) {
echo '</ul>';
}
++$counter;
}
if ((($counter-1) % $break_after) != ($break_after-1)) {
echo '</ul>';
}
Regarding your question, you also need to remember to start your <ul>
each 3rd record (not just closing it) but also make sure to close it after your loop. In your case you can use second method because you don't know number of elements (in fact you can get them using mysqli_num_rows
function and then you could also use method 1). For your case your code should probably look like this:
<?php
$selektKat = "SELECT * FROM `proizvodi` WHERE `kategorija` = '$kat'"; //don't worry about SQLi; I will fix it
$result = mysqli_query($con, $selektKat) or die(mysqli_error());
// Line where the loop starts
<?php
$counter = 0;
$break_after = 3;
while ($row = mysqli_fetch_array($result)) {
if ($counter % $break_after == 0) {
?>
<ul class="products-grid clearfix" style="margin-right: 5px; margin-left: 20px;">
<?php } ?>
<li class="item" style="min-height: 339px">
<a id="product-image-42321" href="proizvod.php" title="naziv" class="product-image">
<img src="http://static.511tactical.com/mag/media/catalog/product/cache/1/small_image/220x/9df78eab33525d08d6e5fb8d27136e95/5/3/53212_716_Alternate1.jpg" width="220" alt="<?php echo $row['naziv'] ?>" />
</a>
<ul class="swatches clearfix">
<li id="swatch-228" class="swatch product-42321">
<a href="proizvod.php" title="<?php echo $row['naziv']; ?>">
<img src="<?php echo __DIR__ . '/images/' . $row['slika'] . '.jpg'; ?>" />
</a>
</li>
</ul>
<div class="price-box">
<span class="label" id="configurable-price-from-42321">
<span class="configurable-price-from-label">
</span>
</span>
<div class="product-name"><a id="product-name-140981" href="proizvod.php"><?php echo $row['naziv']; ?></a></div>
<span class="regular-price" id="product-price-42321">
<span class="price"><?php echo $row['cijena']; ?><sup>KM</sup>
</span>
</span>
</div>
<div class="actions">
</div>
</li>
<?php
if ($counter % $break_after == ($break_after - 1)) {
echo '</ul>';
}
++$counter;
}
if (($counter-1) % $break_after != ($break_after - 1)) { // make sure there will be closing </ul>
echo '</ul>';
}
?>
</div>
Upvotes: 7
Reputation: 1188
<?php
//Our images
$array = array(1,2,3,4,5,6,7,8,9,10,11,12,13,14);
//Count array for last ul
$count_array = count($array);
//Counter
$count = 0;
foreach ($array as $key => $value) {
$count++;
//Begin
if ($count % 3 == 1) {
echo '<ul>';
}
//Output data
echo '<li>' . $value . '</li>';
//Close ul
if ($count % 3 == 0 || $count_array == $count) {
echo '</ul>';
}
}
?>
Output:
<ul><li>1</li><li>2</li><li>3</li></ul><ul><li>4</li><li>5</li><li>6</li></ul><ul><li>7</li><li>8</li><li>9</li></ul><ul><li>10</li><li>11</li><li>12</li></ul><ul><li>13</li><li>14</li></ul>
Upvotes: 1
Reputation: 5326
Add a varaible
, let's say $i
in you while that you increment at each iteration.
And when it is a multiple of 3, just close your ul
.
while ($row = mysqli_fetch_array($result)) {
// YOUR CODE HERE
$count++;
if ($count % 3 == 0) echo '</ul>';
}
For the record the %
operator will give you the remainder of the euclidean division.
Upvotes: -2