I have a table with a row of 3 div's then another row or 3 div's then another and then another.
But what I'm trying to achieve is to highlight every other row. And each row contains 3 div's.
So the first row will be .mydiv .even and then the .even's will be grey. Then the next row will be .mydiv .odd and then the .odd's will be white.
I am using this code from css-tricks.com ($xyz++%2) to make every other div a different class.
All help is apreciated.
This is my code
$get_new_games = mysql_query("SELECT game_title,game_description,id from games ORDER BY added_date LIMIT 10");
while ($row = mysql_fetch_array($get_new_games)) {
$new_game_title = $row['game_title'];
$new_game_description = $row['game_description'];
$new_game_id = $row['id'];
$new_games_display .= '<div class = "game_module class-'.($xyz++%2).'"><img src = "game_thumbnails/'.$new_game_id.'/_thumb_100x100.png" class = "game_img"></div>';
}
It would make more sense to add the class to the row, to output the table rows in PHP, use something like this:
<?php for ($i = 0; $rows[$i]; $i ++): ?>
<tr class="<?php echo $i % 2 ? 'odd' : 'even'; ?>">
<td>
<div />
</td>
<td>
<div />
</td>
<td>
<div />
</td>
</tr>
<?php endfor; ?>
The modulo operator % will return the remainder of the division, in this case the division is by two and any equal number will give a remainder of zero, and any unequal number will give a remainder of one.
The selector for the div would then be:
tr.odd td > div
tr.even td > div
this will make sure that only the top div in each row is selected.
UPDATE:
From the code you've supplied it doesn't really appear you're using a table at all (maybe you meant it in a looser sense than the actual HTML element?). Going by your code you already use the modulo in the way described above, but you need to change the following.
$xyz = 0;
$get_new_games = mysql_query("SELECT game_title,game_description,id from games ORDER BY added_date LIMIT 10");
while ($row = mysql_fetch_array($get_new_games)) {
$new_game_title = $row['game_title'];
$new_game_description = $row['game_description'];
$new_game_id = $row['id'];
$new_games_display .= '<div class = "game_module class-'.($xyz++%2 ? 'odd' : 'even').'"><img src = "game_thumbnails/'.$new_game_id.'/_thumb_100x100.png" class = "game_img"></div>';
}
I've added the first line to initialize the variable to zero and changed the $new_games_display-line to ($xyz++%2 ? 'odd' : 'even'). This will ensure that every other div has the class class-odd and the rest class-even.
The only issue I'm having is that the code you supplied doesn't really correspond to your initial problem, with rows of three divs, maybe I'm missing something -- feel free to supply more code and I'll be able to help you more.
While looping through and printing out the rows, you will use the index to determine even or odd.
if(!$index%2){
echo "even";
}
else{
echo "odd";
}
The % is the modulus operator, which returns the remainder when its operands are divided.
Edit:
So in your case, your last line would be
$new_games_display .= '<div class = "game_module class-'.(($xyz++%2) ? 'odd' : 'even').'"><img src = "game_thumbnails/'.$new_game_id.'/_thumb_100x100.png" class = "game_img"></div>';
try some thing like this:
$i = 0;
while ($row = mysql_fetch_array($get_new_games))
{
...
$i++;
$class = ($i%2)? "even" : "odd";
$new_games_display .= '<div class = "game_module class-' . $class .'"><img src = "game_thumbnails/'.$new_game_id.'/_thumb_100x100.png" class = "game_img"></div>';
}
instead of check $i%2 ==0 or not you can use something like
$class = ($i & 1) ? "odd" : "even";
or
if($i & 1){
$class = "odd";
}else{
$class = "even";
}
Your code is only highlighting every other row instead of groups of three rows. You could use an :nth-child css selector, but using php will ensure browser compatibility since the class is hard coded. Anyway..
$evenodd = false; // false indicates odd
$count = 0;
while (...) {
... //display
$count++;
if ($count == 2) {
$evenodd = !$evenodd;
$count = 0;
}
}
Related
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.
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 have a database that contains donor information and then have PHP pages that pull that data and display it under the donor's specific category.
The code I am using is as follows:
// 10,000 DONORS
echo "<p><b>$10,000 cont.</b></p>";
$sql = "SELECT * FROM donor WHERE DonationAmount = 10000 AND Category = '1' or DonationAmount = 10000 AND Category IS NULL ORDER BY LastName ASC LIMIT 10000 OFFSET 6";
$result = mysqli_query($conn, $sql);
$i = 0;
$total_rows = $result->num_rows;
echo "<table><tr>";
if (mysqli_num_rows($result) > 0) {
// output data of each row
while ($row = mysqli_fetch_assoc($result)) {
// test if the DisplayName field is empty or not
echo "<td>";
if (empty($row['DisplayName'])) {
// it's empty!
if (empty($row['FirstName'])) {
echo $row['LastName'];
}
else {
echo $row["LastName"] . ", " . $row["FirstName"];
}
} else {
// Do stuff with the field
echo $row["DisplayName"] . "";
}
echo "</td>";
$i++;
if ($i % 2 == 0 && $i != $total_rows) {
echo "</tr><tr>";
}
}
} else {
} echo "</tr></table>";
My question is as follows: right now the names are inserted into the table in a manner that makes the read left->right->left->right etc. I need them to show up like a normal list works and reads top to bottom, and rolls to the next column when it is told to (counter?). How can I do this?
Here is a preview off the page
EDIT: tried this code:
$sql = "SELECT * FROM donor WHERE DonationAmount = 1000 AND Category = '1' or DonationAmount = 1000 AND Category IS NULL ORDER BY LastName ASC";
$result = mysqli_query($conn, $sql);
$i = 0;
$count = 0;
$total_rows = $result->num_rows;
$halfsize = $total_rows / 2;
$FirstArray = array();
$SecondArray = array();
while ($row = mysqli_fetch_assoc($result)){
while ($count <= $halfsize){
$FirstArray[] = $row['DisplayName'];
//echo "$FirstArray[$count]";
$count++;
}
$SecondArray[] = $row['DisplayName'];
//echo "$SecondArray[$count]";
}
echo "<table>";
for($j=0; $j<count($FirstArray); $j++){
echo "<tr><td>". $FirstArray[$j] . "</td><td>" . $SecondArray[$j] . "</td> </tr>";
}
echo "</table>";
And I just get the same field (the first result) for all of the first column (The First Array?) and then the second column (SecondArray) contains all of the results.
Your issue is not your PHP or your MySQL but your output handling.
So there's an array of data that's being dumped on your HTML and you need to order it to look nice . Two columns reading left to right in a table format.
The <table> tag is perfect for this, and while most people hate the table tag, it is useful for tabled data.
It's worth noting that due to the flexibility and accommodating nature of CSS/HTML that this is not the only correct way but one of many ways this issue can be addressed
Method:
You have a while loop outputting one unit at a time, a unit in this case being a name in a <td></td> block. So that's your unit:
while {
print "unit";
}
So if you have two columns you want to arrange then you need to tell the while loop to distinguish between the first and the second column, this can be done with detecting if the counter (+1 for each itteration) is odd or even.
You can do this with the modulus divisor in PHP:
while {
counter++
if (counter%2) == 1 ){
//odd number.
}
}
So to sum it all up and give you a basic example:
$output = "";
$rowsTotal = mysqli_num_rows($result); //from your original code.
$counter = 0;
while ($row = mysqli_fetch_assoc($result)) {
$counter++; //plus 1 each itteration
if (($counter%2) == 1){
/// is odd so open the row of the table.
$output .= "<tr>";
}
$output .= "<td>";
if (empty($row['DisplayName'])) {
// it's empty!
if (empty($row['FirstName'])) {
$output .= $row['LastName'];
}
else {
$output .= $row["LastName"] . ", " . $row["FirstName"];
}
}
else {
// Do stuff with the field
$output .= $row["DisplayName"] . "";
}
$output .= "</td>";
if (($counter%2) == 0){
// if even so close the row of the table.
$output .= "</tr>";
}
// special case: If there area total of odd number of outputs
if($counter == $rowsTotal && $counter%2 == 1){
// so the last counter value is an odd number so force closure
// of </tr> (or add a blank space)
$output .= "<td> </td></tr>
}
} //end while.
...
print "<table>";
print $output;
print "</table>";
I don't want to dive deep into getting really creative with CSS but you can use CSS to finesse and improve the core HTML output setout above with some wonderful Cascading Style sheets, but above is a very rough outline of the sortof approach you could use to simulate a base level intelligence for the script to output names in the layout you are looking for.
Good luck.
CSS example:
table td {
background-color:#000;
color: #fff;
font-size:1.5rem;
text-align:left;
width:49%; /* 50% sometimes causes overflow, so set a tiny bit smaller */
padding:0.25rem;
margin:0;
box-sizing: border-box;
}
VERSION 2
From comments, OP Needs the results from the SQL query to be two columns, rather than two rows. This means that table (a row structure) is inappropriate for this output and so instead we should use a more customised CSS / div tag set:
The layout would be two columns of approximatly 49% width each, and then each column contains block elements, This blob of blocks will then need to be split in half and a divider added to generate two shorter columns from one long one.
The block elements are output in a foreach loop and once the halfway point is met then an extra HTML code is inserted to break the elements up into a second <div> . this is a little bit hacky it feel to me, but, does the job.
requirements:
A predefined counter of result rows. One can easily be generated. And that the SQL query is already ordered in the intended way, using MySQL ORDER BY.
Semi-Pseudo code:
$array = SQL data result.
$counter = counter of how many array rows are returned.
$divisorCount = ceil($counter /2);
$foreachCount = 1
foreach ($array as $row){
$foreachCount++;
$block[] = "<div class='block'>".$row['data']."</div>\n";
if($foreachCount > $divisorCount){
$foreachCount = 0; //reset, as this will not be true again.
end($block);
$key = key($block); //most recent block array reference.
$block[$key] .= "</div><div class='column'>"; //the insert.
}
}
unset($row,$key,$foreachCount,$divisorCount); //tidyup.
The above generates a bunch of array elements, one for each name. There is an inserted splitter that ends the initial column and starts a second column, finally we wrap the whole block array into a final <div> wrapper.
$output = "<div class='tableContainer'>
<div class='column'>".implode($block)."</div>
</div>";
The above output will be the opener for the first column but the closer for the second column. Within output we now have the complete columns for two columns of all results contained in a Div Container element.
The following CSS classes would need some tweaking to get right but should be a start:
CSS
.block{
line-height: 2rem;
display:block;
padding:0.25rem;
box-sizing:border-box;
}
.column{
width: 49%;
min-width:150px; /* or whatever. */
display:inline-block;
}
.tableContainer{
max-width: 800px; /* or whatever. */
min-width: 300px; /* or whatever. */
width:100%;
margin:auto; //centres it.
}
The CSS would be 49% rather than 50% because box sizes can have a tendancy to overflow on different browsers (Firefox especially), but the $output would finally be:
HTML
<div class='tableContainer'>
<div class='column'><div class='block'>My Name</div>
<div class='block'>Your Name</div>
<div class='block'>His Name</div></div>
<div class='column'><div class='block'>Their Name</div>
<div class='block'>Her Name</div>
<div class='block'>Smacked HorseBombs</div>
</div>
</div>
You could also possibly substitute display:inline-block for float:left, but thats the basics, have a play on jsfiddle to tweak as you need.
I won't use tables for this. There may be some other css tricks. But for the sake of question, I'm answering.
Create two arrays.
Get the size of resultset with mysqli_num_rows, and divide it by two, then walk through this first array and move them until halfsize into array1. And then remainig into array2.
At the end you'll have something like this
Array 1 Array 2
------- -------
[0] Row 1 [0] Row 4
[1] Row 2 [1] Row 5
[2] Row 3
Then walk through it and fill your html table. (with controlling them against being empty)
for($i=0; $i<count($array1); $i++){
echo '<tr><td>'.$array1[$i].'</td><td>'.$array2[$i].'</td></tr>';
}
I have 3 tables as I mentioned in my logic. No. of categories and no. of domains for each category are not fixed because they are managed from admin panel. So 3 columns per row are fix but how many rows will be there is not fixed.
I want to display categories and data of each category in following mentioned way.
I am using below logic to achieve desired output it's giving different output.Please help to correct my logic so it can work like above example.
<?php
$str_query_select = "SELECT d.domainpkid,d.domainname,c.categorytitle,dc.categorypkid FROM tr_domainname_category dc ";
$str_query_select .= "LEFT JOIN t_domainname d ON dc.domainpkid=d.domainpkid ";
$str_query_select .= "LEFT JOIN t_domainname_category c ON dc.categorypkid=c.categorypkid ";
$str_query_select .= "WHERE c.visible='YES' AND d.visible='YES' ORDER BY c.categorytitle,d.domainname ";
$rs_cat_list = GetRecordSet($str_query_select);
if (!$rs_cat_list->eof()) { // Check if recordset is not empty
$int_cnt = 0; // Used to make new row
$int_cat_pkid = 0; // Used to validate categorypkid
while (!$rs_cat_list->eof()) { // loop starts
if (($int_cnt % 3) == 0) { // To display 3 columns per row
?>
<tr>
<?php } ?>
<td width="250" align="left" valign="top">
<?php
if ($int_cat_pkid != $rs_cat_list->fields("categorypkid")) {
$int_cat_pkid = $rs_cat_list->fields("categorypkid");
print("<b>" . $rs_cat_list->fields("categorytitle") . "</b><br/>");
}
print($rs_cat_list->fields("domainname") . "<br/>");
?>
</td>
<?php
$int_cnt++;
$rs_cat_list->MoveNext();
if (($int_cnt % 3) == 0) { //
?>
</tr>
<?php
}
}
}
?>
While below is output I am getting. Please help to resolve this issue.
Thank you in advance,
KRA
Create an array of categories first:
$cat = array();
while (!$rs_cat_list->eof()) { // here is your while loop
$cat[$rs_cat_list->fields("categorypkid")][] = $rs_cat_list->fields("domainname");
$rs_cat_list->MoveNext();
}
Now use the $cat array to do the processing.
foreach($cat as $key=>$val) {
//here you can put the above logic just use the $cat array to do the things
if (($int_cnt % 3) == 0) { // To display 3 columns per row
?>
", $val);
?>
if (($int_cnt % 3) == 0) { //
?>
</tr>
<?php
}
}
}
Note: Please do changes according to your need.
Use just 1 row with 3 columns;
Print normal <div> with a fixed size for each item in category.
My Website
As you can see on the above link there are several 'kids', the information for each one is grabbed from a database.
I want to make each alternating image float to the left, so that the images go left, then right, then left etc. At the moment they all float left. This is what I have so far:
<?php
$query="SELECT id, title, text, media, media2, thumb, deleted FROM kids ORDER BY id DESC";
$result=mysql_query($query);
while($row = mysql_fetch_array($result)){
if($row['deleted'] == 0) {
echo '<div id="'.$row['title'].'">';
echo '<img src="images/'.$row['media'].'" class="floatLeftClear" id="border" />';
if($row['media2'] != "") {
echo '<img src="images/'.$row['media2'].'" class="floatLeftClear" id="border" />';
}
echo '<p id="text">';
echo '<span class="kisstitle">'.$row['title'].'</span><br>';
echo $row['text'];
echo '</p>';
echo ' <p align="center" id="spererater"><img src="images/seperater.jpg" width="900" height="5" />Top<br /></p>';
}}
?>
I tried to check the ID, if even, float left, if odd, float right, but I couldn't work out how to do it, plus the ID may not always be even / odd alternating so I'd rather find a different solution if possible.
Use a counter variable, increment by one each time you're looping over an item -- and use that counter with a modulo, to determiner whether you are on an even or odd line :
$counter = 0;
while($row = mysql_fetch_array($result)){
if (($counter % 2) == 0) {
// even
} else {
// odd
}
// use the data of the current $row, display it
$counter++; // increment the counter, for next iterator
}
Add a counter. Before loop $i = 0; and inside loop $i++, if ($i % 2 == 0) { // odd} else {// even}