I have a table of category, I want to show category data into 4 equal bootstraps 4 rows dynamically, and data must be shown in alphabetically order.
First I am counting the number of data and dividing by 4 then run 4 queries to find the first 25 data and in the second query next 25 data and so on, but looking for a better solution.
$catCount = Category::all()->count();
$inOneRow = intval( $catCount / 4);
What I want
Assuming Category is a table of category names - you can select ALL categories at once and use the ORDER BY clause on the query:
$query = 'SELECT name FROM db.categories ORDER BY name ASC;';
You can alternatively use sort on the result-set:
$query = 'SELECT name FROM db.categories;';
/* execute query here... */
sort($resultSet);
Let's assume you did this, the styling would be easy using bootstrap grid (notice mock result-set in fiddles):
<?php
const NUM_COLS = 4;
$numResults = count($dummyResult);
$numPerCol = round($numResults / NUM_COLS);
?>
<div class="container">
<div class="row">
<?php
for($i = 0, $col = 0; $col < NUM_COLS; $col++){
echo '<div class="col">';
for($colLimit = min($numResults, $i + $numPerCol); $i < $colLimit; $i++){
echo '<div class="row">'.$dummyResult[$i]['category'].'</div>';
}
echo '</div>';
}
?>
</div>
</div>
Here is a fiddle
Easier to understand, albeit probably slower example:
<?php
const NUM_COLS = 4;
$numResults = count($dummyResult);
$numPerCol = round($numResults / NUM_COLS);
?>
<div class="container">
<div class="row">
<?php
for($i = 0; $i < NUM_COLS; $i++){
echo '<div class="col">';
foreach( array_splice($dummyResult, 0, $numPerCol) as $row ){
echo '<div class="col">'.$row['category'].'</div>';
}
echo '</div>';
}
?>
</div>
</div>
Here is a fiddle
Note: Container will be 100% width of it's parent, unless styled otherwise.
Column widths will be equal by default. See Bootstrap Grid.
Related
I have some HTML in a variable that I'd like to loop 4 time per row. I am making a couple of queries first. In one I get the number of rows and store it in a variable. The second, I am looking to fetch the associated data that I will need to display.
$results = $dbCon->query("SELECT * FROM table WHERE status = '1' ORDER BY id DESC LIMIT $start, $limit");
$total = mysqli_num_rows($results);
$res = $dbCon->query($results);
$data = $res->fetch_assoc();
$link = $data['link'];
$title = $data['title'];
$image = $data['image'];
$imgAlt = $data['imgAlt'];
Third, I store what I want to display in a variable. The HTML I plan on displaying looks something like this
$html = printf("<div style=\"text-align:center; max-width:270px; white-space:normal; word-wrap:break-word; border-left:1em solid transparent; border-right:1em solid transparent; text-overflow: ellipsis; float:left;\">
<a href=\"%s\">
<img style=\"width:270px; height:232px; margin-bottom:40px; border-radius:45px; -moz-border-radius:45px; -webkit-border-radius:45px; box-shadow:0px 0px 3px #fff; -moz-box-shadow:0px 0px 3px #fff; -webkit-box-shadow:0px 0px 3px #fff;\" src=\"images/recentshoots/%s\" alt=\"%s\" />
<p>%s</p> <br /></a>
</div>", $link, $image, $imgAlt, $title);
Next, I would like to loop the 20 items per page in 4 items per row. This is where I am having some trouble. My issue is that the number of characters in the $title are always different so the layout breaks apart. At first a tried a simple way using css and php to do a str_pad() but it doesn't seem to work right with empty spaces. I always get some containers that are taller than others which distorts my row. So I did some research in this platform to model after someone else example.
I m having some trouble with what I found because the examples I've seen have information missing that I need to understand how to modify my own. I have seen it done with foreach and while loops. Can someone help me find a way to understand this better?
How can I loop the data retrieved and make sure that only 4 per row exist in a page of 20 items? Thank you so much for your help. I started with something like this
$startingPoint = 1;
echo "<div class=\"row\">";
foreach($startingPoint < 4){ //this foreach is not even starting the right way, how can I fix this?
echo $html;
}
Can I use a foreach? or a while loop? or do-while?
which one is the best solution and the fastest or most efficient way to go? The shorter the code the better.
Foreach loops are used for array datatypes whilst a while loop can be used for booleans and more.
What you're looking for is a for loop, this allows your to set a counter and each time the loop is ran it adds to a counter. Once the expression is met, it ends the loop.
for($i = 1; $i == 4; $i++)
{
echo 'Loop ' . $i . ': This will loop 4 times';
}
However, you could fix your foreach by using this snippet:
$startingPoint = [1,2,3,4];
foreach($startingPoint as $start)
{
echo $html;
}
Since there are 4 items inside the array, the loop will continue 4 times.
Your SQL is returning more than one row of data thus creating $data to become multidimensional, your loop therefore may not work how its written, you could try this:
for($i = 1; $i >= $limit; $i++)
{
print_f(<!-- html here -->, $data[$i]['column']);
}
You can try this code. Full pagination and view:
Example: index.php
<?php
//get page id for pagination and limit query
$limit = 4;
if(isset($_GET["page"]))
$page = intval($_GET["page"]);
else
$page = 1;
$total = $limit * $page;
$start = $total - $limit;
//GEt data from database. I have used mysqli for testing purpose.
$conn=mysqli_connect("localhost","root","","dbname");
$result = mysqli_query($conn, "SELECT * FROM table WHERE status = '1' ORDER BY id DESC LIMIT $start, $limit");
$total = mysqli_num_rows($result);
?>
<!--Your html code what you want-->
<table>
<tr>
<th>Title</th>
<th>Image</th>
<th>Link</th>
</tr>
<!--loop inside html-->
<?php while($data = mysqli_fetch_assoc($result)) { ?>
<tr>
<td><?php echo $data['title']; ?></td>
<td><img src="<?php echo $data['image']; ?>" alt="<?php echo $data['imgAlt']; ?>"> </td>
<td>Link</td>
</tr>
<?php } ?>
</table>
<?php
/**======== Pagination Url generate=============*/
$totalPages = ceil($total/$limit);
if($page <=1 ){
" <span style='font-weight: bold;'> < Prev </span> ";
}else{
$j = $page - 1;
echo " <a href='index.php?page=$j'>Prev</a> ";
}
for($i=1; $i <= $totalPages; $i++){
if($i<>$page){
echo " <a href='index.php?page=$i'>$i</a> ";
}else{
echo " <span style='font-weight: bold;'>$i</span> ";
}
}
if($page == $totalPages ){
echo " <span style='font-weight: bold;'>Next ></span> ";
}else{
$j = $page + 1;
echo " <a href='index.php?page=$j'>Next</a></span> ";
}
?>
I want to create a dynamic drop down menu using PHP and MySQL. Menus is OK but not the way I wanted.
I want the menu like this as below (sorted vertically and limiting number of items vertically and horizontally)
I tried achieving this as per below code:
<?php foreach ($result as $riw) { ?>
<div class="four columns">
<li><a href="<?php echo $riw['fmprmlink']; ?>"><?php echo
$riw['remedy_name']; ?></a> </li>
</div>
<?php } ?>
By above approach i am getting this as a result which is not rquired
and without using <div class="four columns"> the result is as below which is again not required
I want items to be arranged and shown alphabetically vertically.
A simple possibility of sorting first, then second, then etc. column.
Can something be improved.
Shows one of many possibilities.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>4 columns</title>
<link rel="stylesheet" type="text/css" href="style.css" />
</head>
<body>
<?php
function setline($conte,$i,$count,$ILines){
$act1 = $i;
$act2 = 1*$ILines + $i;
$act3 = 2*$ILines + $i;
$act4 = 3*$ILines + $i;
echo "<li>".$conte[$act1]."</li>\n"; // 0
if ($act2 < $count){ echo "<li>".$conte[$act2]."</li>\n";}
if ($act3 < $count){ echo "<li>".$conte[$act3]."</li>\n";}
if ($act4 < $count){ echo "<li>".$conte[$act4]."</li>\n";}
}
//-----------main---------------
echo "<ul id=\"quad\">";
$anArry = array("CSS","XHTML","Semantics","Accessibility","Usability","Web Standards","PHP","Typography","Grids","CSS3","HTML5");
sort($anArry);
$count = count($anArry);
$Idiv = (int)($count/4);
if ($count - ($Idiv * 4)>0) {$ILines = $Idiv+1;} else {$ILines = $Idiv;}
for ($i = 0; $i < $ILines; $i++) {
setline($anArry,$i,$count,$ILines);
}
echo "<ul/>";
?>
</body>
</html>
Next is the normal standard look of a 4 column list.
To get it we changed only the for loop.
Sorted from left to right ( not what OP wants)
for ($i = 0; $i < $count; $i++) {
echo "<li>".$anArry[$i]."</li>\n";
}
Now that we know the matrix ...
1| 0-2 3-5 6-8 9-11
col| 1 2 3 4
---|---------------
r 1| 0 3 6 9
o 2| 1 4 7 10
w 3| 2 5 8 11
... we can write a simpler function.
function sortfor4c($cont,$i,$ILines,&$ICol,&$IRow){
echo "<li>".$cont[$ICol * $ILines - $ILines + $IRow -1]."</li>\n";
$ICol++;
if ($ICol > 4) {
$ICol = 1;
$IRow++;
}
}
....
$ICol = 1;
$IRow = 1;
for ($i = 0; $i < $count; $i++) {
sortfor4c($anArry,$i,$ILines,$ICol,$IRow);
}
style.css
body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6{
margin:0;
padding:0;
}
ol,ul{
list-style:none;
}
body{
font-family:Georgia, "Times New Roman", Times, serif;
color:#333;
}
ul{
width:760px;
margin-bottom:20px;
overflow:hidden;
border-top:1px solid #ccc;
}
li{
line-height:1.5em;
border-bottom:1px solid #ccc;
float:left;
display:inline;
}
#quad li { width:25%; }
Presumably, you would want to use some sort of for loop to order the data appropriately. You could do this with PHP or you could do it with JavaScript.
Either way, you will need to process the entries returned by the server so as to limit the number of rows added to each column. The way you'll process the data depends on how it is returned by the server. If the server sends JSON data representing the data cells in question (and you're using AJAX), you'll likely need to take a javascript approach. If you plan to load all menu field data upon the initial page load, you can probably use PHP to create the menu entries.
This is an example of using a for loop to create a table using PHP. You should be able to do the same thing with either list items and/or divs. If this answer is confusing, there are numerous other examples on both SO and the internet at large.
<?php
echo "<table border='1'><br />";
for ($row = 0; $row < 5; $row ++) {
echo "<tr>";
for ($col = 1; $col <= 4; $col ++) {
echo "<td>", [YOUR MENU ENTRY GOES HERE], "</td>";
}
echo "</tr>";
}
echo "</table>";
?>
The following code uses 2 loops to create a 4 column table from an assoc array. $z is calculated to sort rows in each column in ascending order.
$count = count($result);
$rows= floor($count/5);
for ($x = 0; $x <= $rows; $x++) {
for ($y = 0; $y <= 4; $y++) {
$z=($rows*$y)+$x+$y;
if($z<$count){
$html .="<td>".$result[$z]['fmprmlink']."</td>\n";
}else{
$html .="<td></td>\n";
}
}
$html .="</tr>\n";
}
$html .="</table>";
echo $html;
I have a problem with my pagination, I need your help please.
I have 53 records but with this pagination, I can get 50 records only, I can't see the 3 others
I want to change this code to get all records please, and if I want to make the pagination easy to navigate for big records. Like this (for exp):
<< 1 2 3 4 5 ...... 184 185 >>
Thanks
<?php
include("db.php"); //include config file
//sanitize post value
$page_number = filter_var($_POST["page"], FILTER_SANITIZE_NUMBER_INT, FILTER_FLAG_STRIP_HIGH);
//validate page number is really numaric
if(!is_numeric($page_number)){die('Invalid page number!');}
//get current starting point of records
$position = ($page_number * $item_per_page);
//Limit our results within a specified range.
$results = mysqli_query($db,"SELECT id,name,message FROM paginate ORDER BY id ASC LIMIT $position, $item_per_page");
//output results from database
while($row = mysqli_fetch_array($results))
{
echo' <ul class="page_result">
<li class="page_result_img"><img src="images/pic1.jpg" class="img-responsive" alt=""/></li>
<li class="page_result_desc" id="item_'.$row["id"].'">
<h3>'.$row["id"].'.'.$row["name"].'</h3>
<p>'.$row["message"].'</p>
</li>
<p class="no">'.$row["id"].'<br><span>projet</span></p>
<div class="clearfix"> </div>
</ul>';
}
?>
projet.php
<?php
include("db.php");
$results = mysqli_query($db,"SELECT COUNT(*) FROM paginate");
$get_total_rows = mysqli_fetch_array($results); //total records
//break total records into pages
$pages = ceil($get_total_rows[0]/$item_per_page);
//create pagination
if($pages > 1)
{
$pagination = '';
$pagination .= '<ul class="paginate">';
for($i = 1; $i<$pages; $i++)
{
$pagination .= '<li>'.$i.'</li>';
}
$pagination .= '</ul>';
}
?>
.
.
.
.
<div class="approach" id="app">
<div class="container">
<div class="gallery-head text-center">
<h3>Nos projets</h3>
<p>Trouvez ici tout les projets</p>
<span> </span>
</div>
<ul id="results"></div>
<?php echo $pagination; ?>
</div>
</div>
For correct LIMIT in SQL query must be value of $page_number for the first page equal to 0. But your pagination starts from 1. Then you never get $position = 0 and SQL query skips first $item_per_page records.
Try modify $position calculation:
$position = (($page_number - 1) * $item_per_page);
Second problem is in projet.php. For 53 records (and $item_per_page = 10) is value of $pages = 6. But for cycle stops on 5. It should be:
for($i = 1; $i <= $pages; $i++)
I like to work this way .. So try this code hope it help
$results = mysqli_query($db,"SELECT * FROM paginate");
$get_total_rows = mysqli_num_rows($results); //total records
$item_per_page = 10;
//break total records into pages
$pages = ceil($get_total_rows/$item_per_page);
//create pagination
if($pages > 1)
{
?>
<ul class="paginate">
<?php
for($i = 1; $i<$pages; $i++)
{
if($pages <= 5){
?>
<li><?php echo $i; ?></li>
<?php
}elseif($pages >= $pages - 5){
?>
<li><?php echo $i; ?></li>
<?php
}
}
?>
</ul>
<?php
}
I have a table for users already created so for example I will run a query which will SELECT * FROM users WHERE accType='1' and I am looking to run a foreach loop on the results and put each result into this element
<div class="title-desc-wrap col-xs-12 col-md-8">
<div class="title-wrap "><h4>User Name</h4></div>
<div class="excerpt-wrap">PROFILE PICTURE</div>
</div>
I want to restrict the page to only show 8 users on each page. How would I go about structuring this foreach loop in PHP?
Not too sure on foreach but for a for loop, if you are placing the results into an array, you could;
<?php
for($count = 0; $count < 8; $count++) {
$holder = $array_name['$count'];
echo "<a href=LINK TO USERS PROFILE>". $holder['userName'] ."</a>";
echo "<div class=excerpt-wrap>". $holder['ProfilePic'] ."</div>";
}
then for the next page;
<?php
for($count = 8; $count < 16; $count++) {
$holder = $array_name['$count'];
echo "<a href=LINK TO USERS PROFILE>". $holder['userName'] ."</a>";
echo "<div class=excerpt-wrap>". $holder['ProfilePic'] ."</div>";
}
and so on, bit basic but it should work.
Hey, I am still trying to allow multiple filters to be selected for my pagination script but not sure how to do it being very new to php and programing in general.
So in my pagination, when a user clicks the 'marketing' button(link) it queries the database just for the category that = marketing. The same goes for the other 2 filter buttons as seen in the script below. (automotive, sports).
The problem is, I want to be able to select multiple filters like only marketing and auomotive or automotive and sports, for example if I click the marketing filter and then the automotive, it would display the categories that equal marketing, and automotive.
I have no idea how to accomplish this, so I have come to the experts to help me out.
This is the script I am working on:
<h3>Filter results by:</h3>
<a href='pagi_test.php?category=marketing'>marketing</a>
<a href='pagi_test.php?category=automotive'>automotive</a>
<a href='pagi_test.php?category=sports'>sports</a>
<br />
<h3>Results:</h3>
<?php
//connecting to the database
$error = "Could not connect to the database";
mysql_connect('localhost','root','root') or die($error);
mysql_select_db('ajax_demo') or die($error);
//max displayed per page
$per_page = 3;
//get start variable
$start = $_GET['start'];
$category = mysql_real_escape_string($_GET['category']);
//count records
$record_count = mysql_num_rows(mysql_query("SELECT * FROM explore WHERE category='$category'"));
//count max pages
$max_pages = $record_count / $per_page; //may come out as decimal
if (!$start)
$start = 0;
//display data
$get = mysql_query("SELECT * FROM explore WHERE category='$category' LIMIT $start, $per_page");
?>
<table width="800px">
<?php
while ($row = mysql_fetch_assoc($get))
{
// get data
$id = $row['id'];
$site_name = $row['site_name'];
$site_description = $row['site_description'];
?>
<tr>
<td><?php echo $id; ?></td>
<td><?php echo $site_name; ?></td>
<td><?php echo $site_description; ?></td>
</tr>
<?php
}
//setup prev and next variables
$prev = $start - $per_page;
$next = $start + $per_page;
//show prev button
if (!($start<=0))
echo "<a href='pagi_test.php?category=$category&start=$prev'>Prev</a> ";
//show page numbers
//set variable for first page
$i=1;
for ($x=0;$x<$record_count;$x=$x+$per_page)
{
if ($start!=$x)
echo " <a href='pagi_test.php?category=$category&start=$x'>$i</a> ";
else
echo " <a href='pagi_test.php?category=$category&start=$x'><b>$i</b></a> ";
$i++;
}
//show next button
if (!($start>=$record_count-$per_page))
echo " <a href='pagi_test.php?category=$category&start=$next'>Next</a>";
?>
Any help on this would be great. Thank you.
-- EDIT --
If anyone has a better method of doing a pagination system with multiple filters than the one above, please let me know.
While selecting second filter u can add the category
ex:
At first ur variable $category has
$category="Marketing";
When user filter with another category suppose automotive then add it to $category with a delimeter,Now
$category="Marketing:Automotive";
when u access thru GET use explode:
$cat=explode(":",$_GET['category']);
and write your condition
$condition="category=category[0]";
for($i=1; $i<sizeof($cat); $i++)
{
$condition="AND category=$cat[$i]";
}
$where="WHERE $condition";
use $where in ur query, like
$record_count = mysql_num_rows(mysql_query("SELECT * FROM explore $where"));
I see two separate issues
How to allow the user to select more than one category to filter by
How to propagate those choices to the pagination links
Each for which I have a solution!
How to allow the user to select more than one category to filter by
A form is going to be the most direct approach.
<h3>Filter results by:</h3>
<form action="pagi_test.php" method="GET">
<input type="checkbox" name="category[]" value="marketing" id="cat_marketing"/>
<label for="cat_marketing">Marketing</label>
<br/>
<input type="checkbox" name="category[]" value="automotive" id="cat_automotive"/>
<label for="cat_automotive">Automotive</label>
<br/>
<input type="checkbox" name="category[]" value="sports" id="cat_sports"/>
<label for="cat_sports">Marketing</label>
<br/>
<input type="submit" value="Filter!" />
</form>
Now, $_GET['category'] will be an array of every category that was selected.
$categories = $_GET['category'];
$inClause = "'" . implode( "','", array_map( 'mysql_real_escape_string', $categories ) ) . "'";
//count records
$record_count = mysql_num_rows(
mysql_query( "SELECT * FROM explore WHERE category IN($inClause)" )
);
Of course, you'd probably want to add a check here to make sure $categories isn't empty before you execute the query.
You'll need to modify the actual selection query as well
//display data
$get = mysql_query("SELECT * FROM explore WHERE category IN($inClause) LIMIT $start, $per_page");
Bingo! Now that part is done!
How to propagate those choices to the pagination links
Since we already have an array of the categories selected stored in $categories, this will be trivial using http_build_query().
//setup prev and next variables
$prev = $start - $per_page;
$next = $start + $per_page;
// Get the categories in an HTML-safe array
$requestVars = array_map( 'htmlspecialchars', $categories );
//show prev button
if (!($start<=0))
{
$requestVars['start'] = $prev;
echo 'Prev ';
}
//show page numbers
//set variable for first page
$i=1;
for ( $x = 0; $x < $record_count; $x = $x + $per_page )
{
$requestVars['start'] = $x;
if ( $start != $x )
{
echo ''. $i .' ';
} else {
echo '<b>'. $i .'</b> ';
}
$i++;
}
//show next button
if (!($start>=$record_count-$per_page))
{
$requestVars['start'] = $next;
echo 'Next ';
}
Now, there are still holes in this implementation.
Since the <form> is printed to the page before the rest of the logic, there's no way to pre-select the checkboxes that represent the current filter choices. Which you could definitely change.
Also, you have categories as literal strings in the PHP script - they would really be better in their own table in the database.
The way you retrieve a count for the entire data set is inefficient - it sends the entire data set over the wire to PHP, which then is responsible for determining the record count. It's much better to run a separate query that uses SELECT count(*) ... instead.