spacepoet Posted December 2, 2012 Share Posted December 2, 2012 (edited) Hi: I am trying to figure out how to display a beginning UL tag and an ending UL tag only once when it is in a loop. This is what I have: <? $query = "SELECT id, myPageNav4, myPageURL, myButtonTitle, myTitle FROM myPageData WHERE myPageNav4='4' AND myPageActive='Yes' ORDER BY listorder"; $result = mysql_query($query); $num_rows = mysql_num_rows($result); for($j=0;$j<$num_rows;$j++) { $row = mysql_fetch_array($result); $id = $row['id']; $myPageNav4 = $row['myPageNav4']; $myPageURL = $row['myPageURL']; $myButtonTitle = $row['myButtonTitle']; $myTitle = $row['myTitle']; echo "<ul class='mm-footer-ul'>"; echo "<li class='mm-footer-ul-li'><a href='$id.$myPageURL.html' title='".$myTitle."'>".$myButtonTitle."</a></li>"; echo "</ul>"; } ?> The problem is that every LI is getting a set of UL tags: <ul> <li><a href="Page-One.html" title="Page One">Page One</a></li> </ul> <ul> <li><a href="Page-Two.html" title="Page Two">Page Two</a></li> </ul> Instead of: <ul> <li><a href="Page-One.html" title="Page One">Page One</a></li> <li><a href="Page-Two.html" title="Page Two">Page Two</a></li> </ul> I only want to display the data if myPageNav4 is "4" and myPageActive is "Yes", which it currently does. I want to keep the ULs inside the loop that checks that these two conditions are true, but will still write the UL list properly. How can I do this?? I am totally stumped and need some fresh eyes. Thanks! Edited December 2, 2012 by spacepoet Quote Link to comment https://forums.phpfreaks.com/topic/271496-displaying-ul-once-once-inside-a-loop-i-am-stumped/ Share on other sites More sharing options...
Christian F. Posted December 2, 2012 Share Posted December 2, 2012 Move the echo's that open and close it to outside of the loop. Quote Link to comment https://forums.phpfreaks.com/topic/271496-displaying-ul-once-once-inside-a-loop-i-am-stumped/#findComment-1396982 Share on other sites More sharing options...
spacepoet Posted December 2, 2012 Author Share Posted December 2, 2012 I have tried that .. the problem then is if the pages in that section are not active (myPageActive is not "Yes"), I get an empty set of ULs displaying: <ul class='mm-footer-ul'></ul> That is not semantically properly, either. I don't want that, either. Any other ideas .. ?? Quote Link to comment https://forums.phpfreaks.com/topic/271496-displaying-ul-once-once-inside-a-loop-i-am-stumped/#findComment-1396984 Share on other sites More sharing options...
spacepoet Posted December 2, 2012 Author Share Posted December 2, 2012 I should note that I have 4 sections like this for the top nav, middle nav, left nav, and footer (which this is). They are all mostly the same except for: myPageNav1 = top nav myPageNav2 = middle nav myPageNav3 = left nav myPageNav4 = footer nav Quote Link to comment https://forums.phpfreaks.com/topic/271496-displaying-ul-once-once-inside-a-loop-i-am-stumped/#findComment-1396986 Share on other sites More sharing options...
Christian F. Posted December 2, 2012 Share Posted December 2, 2012 (edited) Opening tag goes before the loop, closing tag after. Though, that said, I prefer to do it this way: // Define the template used to generate the inner content, and set the holding variable to be an empty string. $innerTemplate = "\t".'<li><a href="#" title="%s">%s</a></li>'."\n"; $innerContent = ''; // Loop through all of the items. foreach ($array as $item) { // Add the item's details to the template, and add the completed line to the end of the innerContent variable. $innerContent .= sprintf ($innerTemplate, htmlspecialchars ($item['title']), htmlspecialchars ($item['button'])); } // Finish the list, and add it to the output variable. $output = '<ul class="someclass">'.$innerContent."</ul>\n"; And then you just need to echo $output wherever you want the list. Edited December 2, 2012 by Christian F. Quote Link to comment https://forums.phpfreaks.com/topic/271496-displaying-ul-once-once-inside-a-loop-i-am-stumped/#findComment-1396988 Share on other sites More sharing options...
spacepoet Posted December 2, 2012 Author Share Posted December 2, 2012 Hi again. Thanks for the input. "Opening tag goes before the loop, closing tag after." Can you show me what you mean, based on my code .. ?? I am not sure I follow. Also, for what you posted, can you show me an example ..?? I kind of follow you but not exactly... The help is much appreciated - I thought I had programmed myself into a corner! Quote Link to comment https://forums.phpfreaks.com/topic/271496-displaying-ul-once-once-inside-a-loop-i-am-stumped/#findComment-1396991 Share on other sites More sharing options...
spacepoet Posted December 2, 2012 Author Share Posted December 2, 2012 (edited) Hi - OK, so I did get it to work! Which is good 'cause this was drivin' me nuts. Thanks much for helping me think in a different way. However, it seems a bit messy. I think the code could be cleaner. <? $query = "SELECT id, myPageNav4, myPageURL, myButtonTitle, myTitle FROM myPageData WHERE myPageNav4='4' AND myPageActive='Yes' ORDER BY listorder"; $result1 = mysql_query($query); $result2 = mysql_query($query); $num_rows = mysql_num_rows($result2); { $row1 = mysql_fetch_array($result1); $myPageNav4 = $row1['myPageNav4']; if ($myPageNav4 != "") { echo "<ul class='mm-footer-ul'>"; } for($j=0;$j<$num_rows;$j++) { $row2 = mysql_fetch_array($result2); $id = $row2['id']; $myPageURL = $row2['myPageURL']; $myButtonTitle = $row2['myButtonTitle']; $myTitle = $row2['myTitle']; echo "<li class='mm-footer-ul-li'><a href='$id.$myPageURL.html' title='".$myTitle."'>".$myButtonTitle."</a></li>"; } if ($myPageNav4 != "") { echo "</ul>"; } } ?> Is there a more streamlined way to do this, based on what I posted .. ?? Edited December 2, 2012 by spacepoet Quote Link to comment https://forums.phpfreaks.com/topic/271496-displaying-ul-once-once-inside-a-loop-i-am-stumped/#findComment-1397021 Share on other sites More sharing options...
DavidAM Posted December 2, 2012 Share Posted December 2, 2012 You are executing the query twice, now. Apparently so you can check to see if there is data returned? $sql = "SELECT ..."; $res = mysql_query($sql); if ($res) { if (mysql_num_rows($res)) { echo '<UL>'; while ($row = mysql_fetch_assoc($res)) { echo '<LI> ...</LI>'; } mysql_free_result($res); echo '</UL>'; } } Quote Link to comment https://forums.phpfreaks.com/topic/271496-displaying-ul-once-once-inside-a-loop-i-am-stumped/#findComment-1397024 Share on other sites More sharing options...
spacepoet Posted December 2, 2012 Author Share Posted December 2, 2012 Hi: The way I posted it is the only way I have been able to get it to work, but I do agree I should not be using a query twice. So, what you posted should do the trick for me (if I add my code I posted, or course), ?? Thanks much! Quote Link to comment https://forums.phpfreaks.com/topic/271496-displaying-ul-once-once-inside-a-loop-i-am-stumped/#findComment-1397025 Share on other sites More sharing options...
spacepoet Posted December 2, 2012 Author Share Posted December 2, 2012 I tried this: <? $sql = "SELECT id, myPageURL, myButtonTitle, myTitle FROM myPageData WHERE myPageNav4='4' AND myPageActive='Yes' ORDER BY listorder"; $res = mysql_query($sql); if ($res) { if (mysql_num_rows($res)) { echo "<ul class='mm-footer-ul'>"; while ($row = mysql_fetch_assoc($res)) { echo "<li class='mm-footer-ul-li'><a href='$id.$myPageURL.html' title='".$myTitle."'>".$myButtonTitle."</a></li>"; } mysql_free_result($res); echo "</ul>"; } } ?> But it is selecting records from the other areas of the site. I assume the way I posted is the only way to get it to work .. ?? I just want to learn to make my code cleaner and more efficient .. This is the whole page: <?php include("include/db.php"); $con = mysql_connect($db_host, $db_user, $db_password); mysql_select_db($db_table); $id = $_GET['id']; $myPageURL = ""; $myTitle = ""; $myDesc = ""; $myHeader = ""; $mySubHeader = ""; $myPageContent = ""; $myReadMore = ""; $myPageContentMore = ""; $myBannerContent = ""; $photo = ""; $continue = false; if(isset($_GET)) { if($id!="") { $query = "SELECT id, myTitle, myDesc, myHeader, mySubHeader, myPageContent, myReadMore, myPageContentMore, myBannerContent, photo_filename FROM myPageData WHERE id = $id"; $result = mysql_query($query); $num_rows = mysql_num_rows($result); if($num_rows>0) { $row = mysql_fetch_array($result); $continue = true; $myTitle = $row['myTitle']; $myDesc = $row['myDesc']; $myHeader = $row['myHeader']; $mySubHeader = $row['mySubHeader']; $myPageContent = $row['myPageContent']; $myReadMore = $row['myReadMore']; $myPageContentMore = $row['myPageContentMore']; $myBannerContent = $row['myBannerContent']; $photo = $row['photo_filename']; } } } if(!$continue) { header("location:1.Homepage.html"); } ?> <!DOCTYPE html> <html lang="en"> <head> <meta name="description" content="<? echo $myDesc; ?>" /> <title><? echo $myTitle; ?></title> </head> <body> /* TOP NAVIGATION */ <? $query = "SELECT id, myPageNav1, myPageURL, myButtonTitle, myTitle FROM myPageData WHERE myPageNav1='1' AND myPageActive='Yes' ORDER BY listorder"; $result1 = mysql_query($query); $result2 = mysql_query($query); $num_rows = mysql_num_rows($result2); { $row1 = mysql_fetch_array($result1); $myPageNav1 = $row1['myPageNav1']; if ($myPageNav1 != "") { echo "<ul class='mm-side-ul'>"; } for($j=0;$j<$num_rows;$j++) { $row2 = mysql_fetch_array($result2); $id = $row2['id']; $myPageURL = $row2['myPageURL']; $myButtonTitle = $row2['myButtonTitle']; $myTitle = $row2['myTitle']; echo "<li class='mm-side-ul-li'><a href='$id.$myPageURL.html' title='".$myTitle."'>".$myButtonTitle."</a></li>"; } if ($myPageNav1 != "") { echo "</ul>"; } } ?> <header class="mm-header mm-replace"> ... </header> <div class="content-container"> <article class="mm-article"> /* LEFT NAVIGATION */ <? $query = "SELECT id, myPageNav3, myPageURL, myButtonTitle, myTitle FROM myPageData WHERE myPageNav3='3' AND myPageActive='Yes' ORDER BY listorder"; $result1 = mysql_query($query); $result2 = mysql_query($query); $num_rows = mysql_num_rows($result2); { $row1 = mysql_fetch_array($result1); $myPageNav3 = $row1['myPageNav3']; if ($myPageNav3 != "") { echo "<ul class='mm-side-ul'>"; } for($j=0;$j<$num_rows;$j++) { $row2 = mysql_fetch_array($result2); $id = $row2['id']; $myPageURL = $row2['myPageURL']; $myButtonTitle = $row2['myButtonTitle']; $myTitle = $row2['myTitle']; echo "<li class='mm-side-ul-li'><a href='$id.$myPageURL.html' title='".$myTitle."'>".$myButtonTitle."</a></li>"; } if ($myPageNav3 != "") { echo "</ul>"; } } ?> </article> </div> <footer class="mm-footer"> /* FOOTER NAVIGATION */ <? $query = "SELECT id, myPageNav4, myPageURL, myButtonTitle, myTitle FROM myPageData WHERE myPageNav4='4' AND myPageActive='Yes' ORDER BY listorder"; $result1 = mysql_query($query); $result2 = mysql_query($query); $num_rows = mysql_num_rows($result2); { $row1 = mysql_fetch_array($result1); $myPageNav4 = $row1['myPageNav4']; if ($myPageNav4 != "") { echo "<ul class='mm-footer-ul'>"; } for($j=0;$j<$num_rows;$j++) { $row2 = mysql_fetch_array($result2); $id = $row2['id']; $myPageURL = $row2['myPageURL']; $myButtonTitle = $row2['myButtonTitle']; $myTitle = $row2['myTitle']; echo "<li class='mm-footer-ul-li'><a href='$id.$myPageURL.html' title='".$myTitle."'>".$myButtonTitle."</a></li>"; } if ($myPageNav4 != "") { echo "</ul>"; } } ?> </footer> </body> </html> - All the records come from 1 table - myPageData. - I allow the user to check 1 of 3 areas to assign the menu area (myPageNav1, myPageNav2, myPageNav3) - I also allow the user to check a box (myPageActive); if it is check it equals "Yes" and the page displays Any ideas on how to make this code better .. ?? The way I posted it is the only way I have been able to get it to function properly .. Thanks. Quote Link to comment https://forums.phpfreaks.com/topic/271496-displaying-ul-once-once-inside-a-loop-i-am-stumped/#findComment-1397032 Share on other sites More sharing options...
DavidAM Posted December 3, 2012 Share Posted December 3, 2012 (edited) I tried this: ... But it is selecting records from the other areas of the site. I assume the way I posted is the only way to get it to work .. ?? I don't see how it is returning any different results. It is exactly the same query, and basically the same process. We just changed the conditions for entering the loop. The code ... Oh, I see. I had left out the assignment statements that were getting the data from $row2. Those need to be in there. I just want to learn to make my code cleaner and more efficient .. ... Any ideas on how to make this code better .. ?? All of those navigation sections look like exactly the same code, except for the selection criteria. Anytime you have code repeated, you can improve it by turning it into a function. For instance, add this function to the page (at the bottom is fine): function pageNavUL($piSection) { $column = 'myPageNav' . $piSection; $out = ''; $sql = "SELECT id, myPageURL, myButtonTitle, myTitle FROM myPageData WHERE $column='$piSection' AND myPageActive='Yes' ORDER BY listorder"; $res = mysql_query($sql); if ($res) { if (mysql_num_rows($res)) { $out .= "<ul class='mm-footer-ul'>"; while ($row = mysql_fetch_assoc($res)) { $id = $row2['id']; $myPageURL = $row2['myPageURL']; $myButtonTitle = $row2['myButtonTitle']; $myTitle = $row2['myTitle']; $out .= "<li class='mm-footer-ul-li'><a href='$id.$myPageURL.html' title='".$myTitle."'>".$myButtonTitle."</a></li>"; } mysql_free_result($res); $out .= "</ul>"; } } return $out; } Then you can replace each of the NAV sections with something like this: /* TOP NAVIGATION */ <?php echo $pageNavUL(1); ?> <header class="mm-header mm-replace"> [edit]Also, get in the habit of using FULL PHP TAGS <?php. The short ones can create problems for you in the future.[/edit] Edited December 3, 2012 by DavidAM Quote Link to comment https://forums.phpfreaks.com/topic/271496-displaying-ul-once-once-inside-a-loop-i-am-stumped/#findComment-1397056 Share on other sites More sharing options...
PFMaBiSmAd Posted December 3, 2012 Share Posted December 3, 2012 If you really want to simplify your code, you need to - 1) Eliminate the four myPageNav1,2,3,4 columns, and have just one 'type' column that holds the correct 1,2,3,4 value. 2) Execute one query that gets all the rows you want in the order that you want them. You would order by the 'type' column and the listorder column. 3) loop over the rows the query retrieves and build each navigation section in a different php variable (actually an array, using the type as the array index so that the code will be universal.) 4) Simply echo the appropriate array section where you want it in the html markup on your page. Quote Link to comment https://forums.phpfreaks.com/topic/271496-displaying-ul-once-once-inside-a-loop-i-am-stumped/#findComment-1397063 Share on other sites More sharing options...
PFMaBiSmAd Posted December 3, 2012 Share Posted December 3, 2012 Here's (untested) code that does what I suggested above - <?php // build navigation // use an array to map your 'type' number to the css class name $map = array(1=>'top',2=>'middle',3=>'side',4=>'footer'); // your posted code used 'side' for #1 and #3, which I doubt is what it really is $query = "SELECT id, type, myPageURL, myButtonTitle, myTitle FROM myPageData WHERE myPageActive='Yes' ORDER BY type,listorder"; $result = mysql_query($query); $navigation = array(); if(mysql_num_rows($result) > 0){ $last_type = null; while($row = mysql_fetch_assoc($result)){ $type = $row['type']; // copy to scaler variable, used several times if($last_type != $type){ // the type changed, either a new one or the first one if($last_type != null){ // not the first one, close out the previous section here... $navigation[$last_type] .= "</ul>"; } // start a new section here... $navigation[$type] = "<ul class='mm-{$map[$type]}-ul'>"; // remember the new type $last_type = $type; } // output (build) the data under each section here... $id = $row['id']; $myPageURL = $row['myPageURL']; $myButtonTitle = $row['myButtonTitle']; $myTitle = $row['myTitle']; $navigation[$type] .= "<li class='mm-{$map[$type]}-ul-li'><a href='$id.$myPageURL.html' title='".$myTitle."'>".$myButtonTitle."</a></li>"; } // close out the last section, if any, here... if($last_type != null){ $navigation[$last_type] .= "</ul>"; } } You would use the result of the above code by echoing the correct element of the $navigation array where you want it - <?php /* TOP NAVIGATION */ echo isset($navigation[1]) ? $navigation[1] : ''; ?> <?php /* LEFT NAVIGATION */ echo isset($navigation[3]) ? $navigation[3] : ''; ?> <?php /* FOOTER NAVIGATION */ echo isset($navigation[4]) ? $navigation[4] : ''; ?> There's another benefit of reducing all the repetitive code, you make less mistakes when copy/pasting/over-typing it for each section. Also, any markup/formating appears only once so you only have one place to change when you want to modify the style on your page. Quote Link to comment https://forums.phpfreaks.com/topic/271496-displaying-ul-once-once-inside-a-loop-i-am-stumped/#findComment-1397066 Share on other sites More sharing options...
PFMaBiSmAd Posted December 3, 2012 Share Posted December 3, 2012 I was going to try and get the example code posted above to work with your existing table definition, but I decided that would be too much work. You need to fix your database design to be able to use code like that. To avoid repeating the actual data (myPageURL, myButtonTitle, myTitle) you should actually have one more table the Relates (the R in RDBMS) the menu choices with the actual data for the menu item. Quote Link to comment https://forums.phpfreaks.com/topic/271496-displaying-ul-once-once-inside-a-loop-i-am-stumped/#findComment-1397188 Share on other sites More sharing options...
spacepoet Posted December 3, 2012 Author Share Posted December 3, 2012 Hi everyone: Thanks very much for the input and coding help! I appreciate it. @PFMaBiSmAd: Thanks for posting that code. I was going to try to add it to my page and see how I make out, but I Just noticed your post right under it. Question: will the code not work until I revise my database design? I need to move forward to finish this project, but I also want to work on the page to make the code "better" as per your proposed idea. Which I can do on another server. Let me know. Thanks! Quote Link to comment https://forums.phpfreaks.com/topic/271496-displaying-ul-once-once-inside-a-loop-i-am-stumped/#findComment-1397343 Share on other sites More sharing options...
spacepoet Posted December 4, 2012 Author Share Posted December 4, 2012 (edited) Wait, I think you mean instead of having 4 fields named myPagNav1, myPagNav2, myPagNav3, and myPagNav4 in the database I should instead have 1 field named myPagNav (or as you listed it "type") and the code should then work, right? I originally had it this way (1 field with 4 radio button options), but since it was not working I changed to 4 fields selectable by checkboxes. I can easily change it back if you think that is all I need to do. Please confirm. Thanks again. Edited December 4, 2012 by spacepoet Quote Link to comment https://forums.phpfreaks.com/topic/271496-displaying-ul-once-once-inside-a-loop-i-am-stumped/#findComment-1397346 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.