Divs according to mysql result in a loop - php

First off, sorry if the title is confusing! I'm working on a part of a blog that determines how lists of recent posts (sometimes determined by a date) in a category are to be displayed. In the database, each category has a "type" set that determines whether the div it goes in is small or large.
I can get the results to display but each link in the list has its own div, instead of being contained in one "main" category div.
Shorter explanation:
The database pulls results from the categories table and the posts table, as you can see in the query. The loop then runs so that the category boxes and the links in them can be created dynamically.
The problem is that the divs, which are supposed to house a list of links, are instead wrapping around each individual link and not the set that is desired.
While the code below shows only two "types", I had planned on adding more in the future.
Here is the code
<?
require("classes/Database.class.php");
$db = new Database(DB_SERVER, DB_USER, DB_PASS, DB_DATABASE);
$time = $_REQUEST['time'];
$db->connect();
$sql = "SELECT
cm.id,
cm.title AS cmtitle,
cm.sectionid,
cm.type AS cmtype,
cd.id,
cd.time,
cd.link,
cd.title,
cd.description,
cd.sectionid AS sectionid
FROM c_main AS cm
JOIN c_data AS cd ON cd.sectionid=cm.sectionid
WHERE cd.sectionid=cm.sectionid AND time = '".$time."' ORDER by id ASC";
$rows = $db->query($sql);
while($record = $db->fetch_array($rows)){
//determine what div to use by checking "type"
if ($record['cmtype'] == 'large') {
?>
<div class="large" >
<?
} elseif ($record['cmtype'] == 'small') {
?>
<div class="small">
<?
}
for($x =0; $x <= $db->affected_rows; ++$x)
{
if ($record['cmtype'] == 'small') {
echo $record['title'].'<br/>';
} else {
echo $record['title'].'<br/>'.$record['description'];
}
break;
}
echo '</div>';
}
$db->close();
?>
Basically I am trying to have it like this:
/-------------------\
| Category Title |
| -relevant link |
| -relevant link |
\____________________/
/-------------------\
| Category Title |
| -relevant link |
| -relevant link |
\____________________/
.... and so on for each subsequent category
And not this (which is how it's being outputted)
/-------------\
\relevant link/
-------------
/-------------\
\relevant link/
-------------
etc.
Here is the mysql wrapper I'm currently using, if that's of any significance http://ricocheting.com/scripts/php_mysql_wrapper.php

If you only want 2 divs, one large and one small, you should do ORDER BY cmtype, and then you will only need to create a div when the type changes or it is the first type.

your code will echo a div for every row, that is your problem/question.
my suggestion is to create two queries: one selecting all links of type A and the second query selecting all links of type B (WHERE type = '…')
then you'll have to print the starting tag of your first div:
echo '<div class="large">';
after that, loop your result and output your links:
while(($record = $db->fetch_assoc($rows)) !== FALSE){
echo htmlspecialchars($record['title']),'<br/>';
}
close your div:
echo '</div>';
now you can start your second category, same game, same rules:
open div
loop results
close div
~~~
another way like others said to order your result by type, then by id (ORDER BY type, id) and then check for a change in the row’s type:
$currenttype = '';
while(($record = $db->fetch_assoc($rows)) !== FALSE) {
$currenttype = $record['cmtype'];
echo '<div class="',htmlspecialchars($record['cmtype']),'">';
while($record['cmtype'] == $currenttype
&& ($record = $db->fetch_assoc($rows)) !== FALSE) {
// output link according to your type:
echo htmlspecialchars($record['title']);
}
echo '</div>';
}
i assume this is what you wanted to achieve in the first place

Maybe I get this completely wrong, but if you want to display the elements grouped by their type I think you should order them by type straight away, so that order of elements is correct when you start outputting HTML code?

If you are certain about your table contents you can use:
echo "<div class='" . $record['cmtype'] . "'>";

Maybe i am wrong in understanding your question, but you try to add all relevant link in a single DIV, then check your php result html (browser->view source)

Related

php/mqsql multiple calls to DB and multiple loops - different logic needed

Firstly let me apologise for my vague question title, this is my first post on this site; after spending 2 days searching for the answer to my question (and getting quite close in some cases) I've hit a wall. Normally I can find everything I need from stackoverflow but this time I've run out of ways to word my question in the search bar.
I have a mysql table containing data for clothes (tbl_clothing) and in this table (I've simplified this for my problem) I have columns: style, colour_url, size, carton_price
The 'style' is for a particulate type of garment $row['style'] in the first sql statement comes from the initial request to the database to find out if the users choice is actually a valid choice (don't worry I've sanitized it, no direct user input is ever used!)
I am grouping by colour_url to create an array of all the colour variations for the chosen style. Incidentally the colour_url is also the actual url to the image file for that colour (used later). Yes this does mean that in the database there is repeating data, the colour_url is repeated as many times as there are sizes for that colour - I've inherited it and can't change that yet.
I then iterate over this array 'foreach' of the different colours and perform another DB lookup to select all sizes and prices for the chosen style and the current colour.
Still in the above foreach loop I perform a while loop to create a second array to hold the sizes and prices (multiple rows are returned from the DB).
Still in the above foreach loop I perform another foreach loop on the second array to create the table structure for outputting.
This is now screaming at me that it is not the best way of achieving what I'm tying to do.
Am I just over thinking this or is there a much simpler way of doing things? I've tried doing a single sql lookup to retrieve a multidimensional array all in one hit but then cant separate out the data into correct groups I've been over and over transposing arrays re-looping through the array creating other "reference" arrays all without any success.
The basic logic works like this:
1 style = many colours
1 colour = many sizes
1 size = 1 price
And i'm trying to get a table output (for each colour) like this:
_________________________________
| (IMG A) | Size(1) | Size(2) | Size(3) |
| colour_A | Price(1) | Price(2) | Price(3) |
|_________|_______________________|
_________________________________
| (IMG B) | Size(1) | Size(2) | Size(3) |
| colour_B | Price(1) | Price(2) | Price(3) |
|_________|_______________________|
Here is my code, it does the job but this cant be the best way to do it:
$sql = "SELECT colour_url FROM tbl_clothing WHERE style = '".$row['style']."' GROUP BY colour_url";
$result = $mysqli->query($sql);
$numRows = $result->num_rows;
if ($numRows != 0){
while ($rowS = $result->fetch_assoc()){
$aResults[] = $rowS['colour_url'];
}
$result->free();
foreach ($aResults as $k=>$v){
echo "<table><tr><td rowspan='2'><img title='' alt='' src='".$v."' /></td>";
$sql = "SELECT size, carton_price FROM tbl_clothing WHERE style = '".$row['style']."' AND colour_url = '".$v."'";
$result = $mysqli->query($sql);
$numRows = $result->num_rows;
if ($numRows != 0){
$aSizePrice = array();
while ($rowS = $result->fetch_assoc()){
$aSizePrice[$rowS['size']] = $rowS['carton_price'];
}
$sizes = "";
$prices = "";
foreach ($aSizePrice as $key=>$val){
$sizes .= "<td>".$key."</td>";
$prices .= "<td>".$val."</td>";
}
}
$result->free();
echo $sizes;
echo "<tr>".$prices."</tr>";
echo "</tr></table>";
}
}
?>
Any help would be a hugely appreciated, even just a point in the right direction, a different opinion or even a sarcastic comment will do at this point...
One thing i might recommend right off the bat, seperate your concerns. You are trying to get data right from the database into your view layer. Instead, get your data, compile it into memory, THEN, display it. It will make your problem easier to solve right off the start.
For example:
//Prepare the data receptacle
$data = array();
//Query to data to work with
$result = $mysqli->query("SELECT * FROM tbl_clothing WHERE style = '".$row['style']."'");
$numRows = $result->num_rows;
while ($rowS = $result->fetch_assoc()){
//Make sure our data can be stored correctly into our structure
if(!isset($data[$row['style']])){ $data[$row['style']] = array(); }
if(!isset($data[$row['style']][$rowS['colour_url'])){ $data[$row['style']][$rowS['colour_url'] = array(); }
if(!isset($data[$row['style']][$rowS['colour_url']['sizes'])){ $data[$row['style']][$rowS['colour_url']['sizes'] = array(); }
if(!isset($data[$row['style']][$rowS['colour_url']['prices'])){ $data[$row['style']][$rowS['colour_url']['prices'] = array(); }
//Store the price and size
$data[$row['style']][$rowS['colour_url']['sizes'][] = $rowS['size'];
$data[$row['style']][$rowS['colour_url']['prices'][] = $rowS['carton_price'];
}
//At this point we have our data, let's just show it
?>
<table>
<?php foreach($data as $style => $color_urls){ ?>
<?php foreach($color_urls as $color_url => $content){ ?>
<tr>
<td rowspan="2">
<img title="" alt="" src="<?php echo $colour_url; ?>" />
</td>
</tr>
<tr>
<?php foreach($content['sizes'] as $size){ ?>
<td><?php echo $size; ?></td>
<?php } ?>
</tr>
<tr>
<?php foreach($content['prices'] as $price){ ?>
<td><?php echo $prices; ?></td>
<?php } ?>
</tr>
<?php } ?>
<?php } ?>
</table>
This is just a quick draft, i might not have understood your question correctly, you'll have to fix the errors and the miscomprehensions yourself. At least you have a good start with this!
Well, let's start with your query. In your first query, you claim you're trying to get all of the colors for a given style. You can use the DISTINCT keyword for that
SELECT DISTINCT colour_url
FROM tbl_clothing
WHERE style = ?
But that's not what you're actually looking to get - you actually want all of the color/size combinations in your database for a given style, which you would likely want to select thusly:
SELECT colour_url, size, carton_price
FROM tbl_clothing
WHERE style = ?
Once you've done that, you want to parse it into a data structure. (you should be parameterizing your queries - I recommend the PDO library, so I'll show you how that would work).
<?php
$db = new PDO('connection', 'user', 'pass');
$query = $db->prepare('SELECT colour_url, size, carton_price
FROM tbl_clothing
WHERE style = :style');
$query->bindValue(':style', $row['style'], PDO::PARAM_STR);
$query->execute();
$results = $query->fetchAll(PDO::FETCH_ASSOC);
$clothes = array();
foreach($results as $result){
if(!isset($clothes[$result['colour_url']]))
$clothes[$result['colour_url']] = array();
$clothes[$result['colour_url']][$result['size']] = $result['carton_price'];
}
?>
Your results are now in a series of nested maps - from $clothes[$color], you get a map from size to price. $clothes[$color][$size] will net you the price of a specific color and size, and you can choose to print them that way:
<?php
foreach($clothes as $color => $prices) {
$sizeStr = '<td>' . implode('</td><td>', array_keys($prices)) . '</td>';
$priceStr = '<td>' . implode('</td><td>', $prices) . '</td>';
?><table>
<tr>
<td rowspan="2">
<img title="" alt="" src="<?=$color?>" />
</td>
<?= $sizeStr ?>
</tr>
<tr>
<?= $priceStr ?>
</tr>
</table><?php
}
?>
Your code now reads a lot closer to english, which will make it easier to debug, and easier to pas on to others.

how to give a link to execute this

$sql=mysql_query("SELECT * FROM feedback.subject WHERE branch='cse'");
$row = mysql_fetch_assoc($sql) or die("error : $sql" .mysql_error());
$data =array();
$n=mysql_num_rows($sql);
while($row = mysql_fetch_array($sql))
{
$query_result_array[]=$row;
}
for($i=0;$i<$n;$i++)
{
$subid=$query_result_array[$i]['subid'];
$bt =$query_result_array[$i]['batch'];
$y =$query_result_array[$i]['year'];
$s = $query_result_array[$i]['semister'];
$subname=$query_result_array[$i]['subname'];
$tid = $query_result_array[$i]['tid'];
$sql2=mysql_query("SELECT * FROM teacher WHERE teacher.tid='$tid'");
$row2 =mysql_fetch_array($sql2);
$tname= $row2['tname'];
echo "<table id='table'>";
echo "<tr>";
echo "<td>".$bt."</td>";
echo "<td>CSE</td>";
echo "<td>".$y."</td>";
echo "<td>".$s."</td>";
echo "<td style='width:150px'>".$subname."</td>";
echo "<td style='width:150px'>".$row2['tname']."</td>";
echo '<form methode="get">
<input type="hidden" name="report">
<input type="submit" value="report">
</form>';
echo "</tr>";
echo "</table>";
}
function handler($x,$y){
session_regenerate_id();
$_SESSION['SUBID']=$x;
$_SESSION['TID']=$y;
echo 'report';
}
if(isset($_GET["report'$i'"]))
{
handler($query_result_array[$i]['subid'], $query_result_array[$i]['tid']);
unset ($_GET["report"]);
}
}
this results a table like
BATCH | BRANCH | YEAR | SEMISTER | SUBJECT NAME | TEACHER NAME | ACTION |
-------------------------------------------------------------------------------
9 CSE 4 1 DBMS ABC REPORT
9 CSE 4 1 WT XYZ REPORT
-------------------------------------------------------------------------------
when i click the report of a row suppose ('ABC' teacher) i want to carry the details ('ABC' and 'DBMS') to further process. but it always carrying the details of last person in the loop(here 'XYZ' and 'WT'). how to get that? is there any alternate process through i can call the handler function for a particular row which carries that particular row details.
just loop through query result array and inside of it place an if which detects when name is what you are looking for, at that moment, fetch current $query_result_array[$i] into a var that you want to carry the data further and break the loop.
If you are fetching by position in the table, you do not even need loop you just go $specific_person_data = $query_result_array[$i]...
So this now contains all of data about the person at position $i in your data table.
Update for links:
Each persons data can be passed to another page through link like this:
linkadress.php*?var1=X&var2=Y&var3=Z...*
and fetched on the other end with $_POST['var1'], $_POST['var2'] etc.
make sure not to echo or return data directly, but on every post var use strip_tags for security precaution.
Also here is article of mine on the subject of sensitive data handling and soem basic security:
http://metaphorical-lab.com/blog/?p=443

Text Injection In Display

Ok, so I'm given a list of parts like so:
PartID CatID PartName
0 1 Part 1
1 2 Part 2
2 1 Part 3
3 3 Part 4
4 2 Part 5
5 2 Part 6
I'm using PHP to pull. How can I inject a blurb of text at each change in CatID, without having to run multiple loops?
So on page, I can display it like:
"BLURB OF TEXT"
Part 1
Part 3
"BLURB OF TEXT"
Part 2
Part 5
Part 6
"BLURB OF TEXT"
Part 4
Here's the code so far. I thought about putting in an assignment to = $row["CatID"], and checking to see if the variable == CatID, but it was always ==...
while($row = sqlsrv_fetch_array($qry, SQLSRV_FETCH_ASSOC)) {
echo $row["PartName"]
}
Put the ID in a variable that is outside the loop. That way you can check the previous ID and the current one. If the current one is not the same as the last one, echo some text:
$LastID = 0;
while($row = sqlsrv_fetch_array($qry, SQLSRV_FETCH_ASSOC)) {
echo $row["PartName"];
if($row["CatID"] > $LastID)
{
// ID changed!
echo "Insert Text!";
}
$LastID = $row["CatID"];
}
This, ofcourse, is assuming that the data is sorted ascending on CatID as your result that you want is showing.
I had my logic backwards.... grr, figures I get it figured out right after I ask for help...
if($cCat == $row["catID"]){
//echo 'nothing here';
}else{
echo '<a name="' . $row["PartCategory"] . '"></a>';
echo $this->GetPartCategories();
$cCat = $row["catID"];
}
is what works, , and above the while statement is a $cCat = '';
I was trying
if(!$cCat == $row["catID"]){
echo '<a name="' . $row["PartCategory"] . '"></a>';
echo $this->GetPartCategories();
$cCat = $row["catID"];
}
which for some reason did not work.
p.s. Already have an order by in my query. It orders by the catID, partSortOrder, then partName

How can I display this table correctly?

I am working on a very simple webshop, it should echo different products in a table of 2 <td> by 4 <tr> but now it only displays the different products downwards. Hopefully someone here can help me.
$result=mysql_query("select * from products");
while($row=mysql_fetch_array($result)) {
$artikel = '<div style="background-color:#E3E3E3;width:200px;height:200px;"><img style="padding-top:10px;padding-left:25px;width:150px;height:150px;" src="'.htmlspecialchars($row['picture']).'"><br><div align="center"><b>'.htmlspecialchars($row['name']).'</b><br><h6>€'.htmlspecialchars($row['price']).'</h6></div></div>';
echo '<table><tr><td>'.$artikel.'</td>';
echo '</table>';
}
Why would it display a table of 2 by 4?
You are putting every product in its own table, so the first thing to do, is move the table tags out of the loop and then you need to add logic to add a new row after every x products.
Although you don't seem to need a table as your div has fixed dimensions, so you can just get rid of the table and use css to get the grid you want.
If this is your entire code then you're missing a tr tag.
Could be a possible cause for your lay-out shifting.
Instead of using breaks, I'd recommend using multiple divs (or table lay-out if you're more comfortable with that) as breaks aren't always handled the same in all browsers.
Instead of creating new table for every records, you can use one row per record.
$result=mysql_query("select * from products");
if(mysql_num_rows($result) > 0){
echo '<table>';
while($row=mysql_fetch_array($result)) {
$artikel = '<div style="background-color:#E3E3E3;width:200px;height:200px;"><img style="padding-top:10px;padding-left:25px;width:150px;height:150px;" src="'.htmlspecialchars($row['picture']).'"><br><div align="center"><b>'.htmlspecialchars($row['name']).'</b><br><h6>€'.htmlspecialchars($row['price']).'</h6></div></div>';
echo '<tr><td>'.$artikel.'</td></tr>';
}
echo '</table>';
}

Echo each Category from a table into its own DIV

My problem seems complex to me, but im sure theres a simple way to do this.
Essentially, I have a treatments list. On the MYSQL table the list's items are broken up by category, title, description and price.
I need to echo out each category into a div each, sectioning them off. So, if the user has 4 catagories of items then I should have 4 divs with all the items from each category in each.
I cant call on a cataogory directly, because the category names are what ever the user sets them to.
Is there a way to do this? Possibly even a while inside a while with PHP?
#Kaaviar Table column names are in order - Category, Title, Description, Price
#sAc - This is the basic of what im using at the moment, but this just lists everything in order of Category.
<?php
include 'config.php';
$treatments = MySQL_query("SELECT * FROM treatments ORDER BY category") or die (MySQL_error('woops') );
while($list = MySQL_fetch_array($treatments)) {
echo $list['title'];
echo $list['description'];
echo $list['price'];
}
?>
#Luke - Your code returns nothing here on my end, with the necessary edits etc.
Thanks,
Warren
You can try the below, obviously you dont have to use the markup I have demo'ed.
$string = '<div><ul>';
$cat = '';
while ($row = mysql_fetch_assoc($result)) {
if ($row['category'] != $cat && !empty($cat)) {
$string .= '</ul></div><div><ul>';
}
$string .= '<li>' . $row['title'] . '</li>';
$cat = $row['category'];
}
$string .= '</ul></div>';
Hope it helps
Luke

Categories