...

View Full Version : can I repeat a region but sorted by a variable



rgEffects
08-20-2012, 07:53 AM
I'm building a list for a menu system using php a database table called content and the standard repeat region behavior. I've done this many times before. My "contentRS" table looks like this:


id link class
1 page_01 red
2 page_02 green
3 page_03 red
4 page_04 blue
5 page_05 green
6 page_06 red

I want to generate a list but only show that list when the class = red. Hiding the list when the class does not equal red is easy. Limiting the list to only records with a class = red is the problem.

I've set up the following code:

<?php do { ?>
<?php if ($row_contentRS['class'] == "red") {
echo "<li>" .$row_contentRS['class'] . "</li>";
} ?>
<?php } while ($row_contentRS = mysql_fetch_assoc($row_contentRS)); ?>

The first part works just fine. The list only shows up when one of the class values = red. The repeat region, however, repeats all of the links so I end up with this: (as expected)

page_01
page_02
page_03
page_04
page_05
page_06

What I want is this:

page_01
page_03
page_06

I can modify the contentRS by editing the query so the RS only reveals the records with a class of "red" by modifying the record set with the following statement:

SELECT *
FROM content
WHERE class = 'red'

This solves my problem, except that I have 90 different class variables now and I will end up with a bunch more. I don't want to have to create a different record set for each. I already know how to reuse the repeat region. What I'd like to do is figure a way embed the query where statement into the repeat region command so only the red class would show up in the list, then reuse the statement with each of the different variables to create a drop down menu with each class listed in the menu bar.

If I can figure this out setting up all 90 classes will be simple copy and paste then typing in a new class value instead of creating 90+ record sets for my menu.

If someone has any ideas I'd appreciate it very much. I may be barking up the wrong tree.

firepages
08-21-2012, 12:52 AM
I am not getting what you mean by `repeat region` sorry ?
but you could....


while ($row_contentRS = mysql_fetch_assoc($row_contentRS)){
$lists[$row_contentRS['class']][]='<li>'.$row_contentRS['link'].'</li>';
}
echo implode("\n",$lists['red']);
//then
echo implode("\n",$lists['blue']);
//etc


is that what you mean ?

rgEffects
08-21-2012, 06:16 PM
Thanks for the reply. The code isn't producing any results so there may be a typo someplace. I'm doing some more research.

Thanks again.

Fou-Lu
08-21-2012, 06:32 PM
The same error exists in your original code:


while ($row_contentRS = mysql_fetch_assoc($row_contentRS));

Regardless of where you pull a while loop either in a do/while or in a while, this overwrites the value of $row_contentRS, so you cannot fetch from it again (assuming $row_contentRS is a resultset). Change the assignment to a different variable name.

I'm confused on what you are talking about here as well. Simply pulling with a where condition will only produce the results matching that where condition. In this case, where class is red.

Results sets can be reset by calling the seek method. Put it back to row 0, and it will start again. Alternatively, fetch it in an array and each time a foreach is called it automatically calls a reset() on the array.

If you were to need all classes at the same time, you can fetch everything into an array and then use an array_filter to show only what you need. That doesn't seem to be the case here, but just in case you need to make use of it in the future I thought it would be best to mention. This is similar to what firepages has here:


function filterByClassRed($record)
{
return isset($record['class']) ? $record['class'] == 'red' : false;
}

$aRecords = array();
while ($row = mysql_fetch_assoc($row_contentRS))
{
$aRecords[] = $row;
}

$redOnly = array_filter($aRecords, 'filterByClassRed');

But that's only useful if you need to make use of any / multiple class values at a time.

rgEffects
08-23-2012, 02:55 AM
Maybe this explanation will help you help me.

I'm creating a menu using a list from a table structure that looks like this: (simplified)
id link class
1 Page_01 red
2 Page_02 green
3 Page_03 red
4 Page_04 blue
5 Page_05 green
6 Page_06 red

Each day or so a new page is put up with a different class. The finished menu structure is supposed to look like this:

<ul><li>Red Class:
<ul><li>Page_01</li>
<li>Page_03</li>
<li>Page_06</li></ui>
</li>
<ul><li>Green Class:
<li>Page_02</li>
<li>Page_05</li></ui>
</li>
<ul><li>Blue Class:
<li>Page_04</li></ui>
</li></ul>

I can easily do this by creating a simple if statement to echo the Class List and then using a separate record set for each page list by filtering the records by a WHEN class = (the selected color), then adding this PHP code for each page class:


<?php do { ?>
<?php if ($row_contentRedRS['class'] == "red") {
echo "<li>" .$row_contentRedRS['class'] . "</li>";
} ?>
<?php } while ($row_contentRedRS = mysql_fetch_assoc($row_contentRedRS)); ?>

What I'd like to do is set up a single record set that just pulls down all records and sorts them and then filter the results so that each <li>Page #</li> could be sorted by class. I have everything working except the class. No matter what method I've tried I end up with all of the pages being displayed in each list (after clearing the while / fetch query) or no records being displayed with the suggestion made by firepages.

I'm going to try and work with Fou-Lu's suggestion this evening. I'll try the array first. The prototype page with 90+ record sets is quite slow to load and maintenance will be a real nightmare.

Fou-Lu
08-23-2012, 06:25 PM
You're still overwriting the variables.
For simplicity, I'd simply use filters, although it does mean you have to explicitly write the functions for it since they do not accept any user parameters. This method means you select all of the records from the dataset into an array and use that in PHP. There are literally a dozen ways to do this exact task, from manual iterations of the resultsets, to splitting into parts and iterating, to combining and using recursion, etc etc.
What I'll do is combine the entire recordset into a flat array, then filter them by class colour, and then iterate each one to build the list inline. If it always uses only the three colours, then this is fine. If it uses more colours, then you do not want to do this and a better solution is to create a multidimensional array like firepages has, and then use recursion to build the list.


function filterByCriteria($record, $colour)
{
return isset($record['class']) ? strtolower($record['class']) == strtolower($colour) : false;
}

function filterByClassRed($record)
{
return filterByCriteria($record, 'red');
}

function filterByClassBlue($record)
{
return filterByCriteria($record, 'blue');
}

function filterByClassGreen($record)
{
return filterByCriteria($record, 'green');
}


$aRecords = array();
$sQry = 'SELECT id, link, class FROM yourtable';
if ($qry = mysql_query($sQry))
{
while ($row = mysql_fetch_assoc($qry))
{
$aRecords[] = $row;
}
}

$aRedClasses = array_filter($aRecords, 'filterByClassRed');
$aGreenClasses = array_filter($aRecords, 'filterByClassGreen');
$aBlueClasses = array_filter($aRecords, 'filterByClassBlue');

print('<ul>');
if (count($aRedClasses) > 0)
{
print('<li>Red Class:<ul>');
foreach ($aRedClasses AS $item)
{
printf('<li>%s</li>', $item['link']);
}
print('</ul></li>');
}

if (count($aGreenClasses) > 0)
{
print('<li>Green Class:<ul>');
foreach ($aGreenClasses AS $item)
{
printf('<li>%s</li>', $item['link']);
}
print('</ul></li>');
}

if (count($aBlueClasses) > 0)
{
print('<li>Blue Class:<ul>');
foreach ($aBlueClasses AS $item)
{
printf('<li>%s</li>', $item['link']);
}
print('</ul></li>');
}
print '</ul>';


As a test I removed the query and used this:


$aRecords[] = array('id' => 1, 'link' => 'Page_01', 'class' => 'red');
$aRecords[] = array('id' => 2, 'link' => 'Page_02', 'class' => 'green');
$aRecords[] = array('id' => 3, 'link' => 'Page_03', 'class' => 'red');
$aRecords[] = array('id' => 4, 'link' => 'Page_04', 'class' => 'blue');
$aRecords[] = array('id' => 5, 'link' => 'Page_05', 'class' => 'green');
$aRecords[] = array('id' => 6, 'link' => 'Page_06', 'class' => 'red');


Which gave the results of:


<ul>
<li>Red Class:<ul>
<li>Page_01</li>
<li>Page_03</li>
<li>Page_06</li>
</ul></li>
<li>Green Class:<ul>
<li>Page_02</li>
<li>Page_05</li>
</ul></li>
<li>Blue Class:<ul>
<li>Page_04</li>
</ul></li>
</ul>

rgEffects
08-23-2012, 07:03 PM
Thank you so much. I see the error of my ways. You have saved me a lot of time.



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum