Making A List Using PHP And NestedSortable - php

I'm attempting to make my own CMS and one thing I wanted to do was make it so I could reorder and change the navigation elements in the CMS. I found a plugin called NestedSortable that let me do this. I used it and had a lot of trouble with it, so I got my expert PHP friend to help me do it. She sat down, struggled for a bit and then got it to work.
Well, the idiot I was, when I got home later that day I sat down, took my local copy, added a something to it and uploaded it to the server... not realizing I had forgotten to download the newer version! So poof, all my friend's work is gone and I'm stuck with a navigation adjustment that doesn't work.
I lost the index.php (that displays it on the page) file but I saved the nav_adjust.php (that inputs it into the database). All I want is to be able to re-order the navigation and send it to the database to be displayed correctly on refresh. The information is send to nav_adjust.php when the submit button is pressed.
The only limitation is that the navigation can only have 3 levels to it (primary, child and grandchild). My navigation looks like when they're all primary. I have alerted back the echo for all the images so you can see what nav_adust.php is doing:
(Please note the array values.)
This is as if there was one child on a parent:
This is as if there was two grandchildren on a child:
And this is mixed:
My index.php file, which doesn't work anymore, looks like this:
<form method="post" action="nav_adjust.php"> <!--This form posts to nav_adjust.php-->
<ol id="pageList">
<?php
$nav = mysql_query("SELECT * FROM `".$name['Website']);
$num = 0;
while( $col_nav = mysql_fetch_assoc($nav) ){
if ($col_nav['orderId'] != 0) {
echo "<li id='list_".$col_nav['id']."'>
<div>Example Title</div>";
} else {
echo "<ol>
<li id='list_".$col_nav['id']."'>
<div><h1>Example Title</div>";
</li>
</ol>\n";
}
echo "</li>\n";
++$num;
}
?>
</ol>
<button type='submit'>Update</button>
</form>
<script>
$(document).ready(function(){
$('#pageList').nestedSortable({
/*option that don't matter*/
});
$("button").on('click', function(event){
serialized = $('ol#pageList').nestedSortable('serialize');
$.post( "nav_adjust.php", serialized, function( data ) {
alert( data );
});
return false;
});
});
</script>
Again, the above code doesn't work. Instead of making a list item look like this:
<ol>
<li>
<ol>
<li></li>
...
</ol>
</li>
...
</ol>
It makes it look like this (note the closed li tag before the ol):
<ol>
<li></li>
<ol>
<li></li>
</ol>
...
</ol>
And this is the nav_adjust.php that my friend did for me which works beautifully if given the right information from index.php
$list = $_POST['list'];
$num = 1;
foreach ($list as $key => $value ) {
if ($value == "null") {
//$value = $num;
mysql_query("UPDATE `myTable` SET orderId=".$num.", parent='null' WHERE id=".$key."");
$text .= "UPDATE `myTable` SET orderId=".$num.", parent='null' WHERE id=".$key."\n\n";
} else {
$query = "UPDATE `myTable` SET orderId=". $num .", parent=".$value;
$text .= "UPDATE `myTable` SET orderId=". $num .", parent=".$value."\n\n";
$var = $list[$value];
if ( $var != null && $list[$var] != null ) {
$query .= ", grandchild = 1";
}
$query .= " WHERE id=".$key;
mysql_query($query);
}
$num++;
}
echo "Content is below\n";
print_r( $_POST['list']);
echo $text;
So, as a recap, I have a navigation that submits serialized data from index.php to nav_adjust.php which then submits it into a database (and echos it back so I know what I did). Then index.php, upon refresh, should keep the list items in place, with all children as children and such. But I overwrite index.php and have no idea how my friend did it.
My table fields are (before I forget):
id, title, orderId (parent), parent (child) and grandchild.
I was meaning to change the names of orderId and parent to make it less confusing but I never did :(
If somebody could help me, I'd be so very thankful.
If there is any other information I can give you, please ask!

After hours of struggling, I had the genius idea of asking GoDaddy if they backed up files and directories, and they did! So I got my file back. For anybody interested, the code missing on index.php looked like this (where $name['website'] is 'myTable'):
$parents = mysql_query("SELECT * FROM `".$name['Website']."` WHERE parent = 0 ORDER BY `orderId` ASC");
while($parent = mysql_fetch_array($parents)){
echo "<li id='list_".$parent['id']."'>
<div>
<span class='disclose'>
<span></span>
</span>
<span class='title'>
<a href='mod.php?id=".$parent['id']."'>".stripslashes($parent['page'])."</a>
</span>
</div>";
// Get chil elements
$children = mysql_query("SELECT * FROM `".$name['Website']."` WHERE parent = " . $parent['id'] . " ORDER BY `orderId` ASC") or die(mysql_error());
while($child = mysql_fetch_array($children)){
echo "<ol>
<li id='list_".$child['id']."'>
<div>
<span class='disclose'>
<span></span>
</span>
<span class='title'>
<a href='mod.php?id=".$child['id']."'>".stripslashes($child['page'])."</a>
</span>
</div>";
# Get grandchild elements
# (Please consider making an recursive function or so out of this if you plan to have grand grand children etc.,
# Because if you create new whiles manually for every instance, this is gonna look pretty darn ugly.
# Also, it makes it impossible to have an unknown depth.)
$grandchildren = mysql_query("SELECT * FROM `".$name['Website']."` WHERE parent = " . $child['id'] . " AND grandchild = 1 ORDER BY `orderId` ASC");
while($grandchild = mysql_fetch_array($grandchildren)){
echo "<ol>
<li id='list_".$grandchild['id']."'>
<div>
<span class='disclose'>
<span></span>
</span>
<span class='title'>
<a href='mod.php?id=".$grandchild['id']."'>".stripslashes($grandchild['page'])."</a>
</span>
</div>
</li>
</ol>\n";
}
// Close child
echo "</li>
</ol>\n";
}
// Close parent
echo "</li>\n";
}
?>

Related

jQuery Effects in PHP While Loop

Ok I have a list of featured paintings to show on the Index.
I am displaying them using a while loop to get the details from the database.
I want to create a jQuery effect for when the user hovers over the image, the div of that picture appears.
The problem is is that if i were to hover on the first one, the first one's div is ok, but if i were to hover and leave the second one, it would affect the first one. Code below:
Script
<script>
$(document).ready(function(){
$("#featuredImage img").hover(function(){
$("#details").fadeOut();
});
});
</script>
PHP While
<ul id="featured">
<?php
$result = mysqli_query($con,"SELECT * FROM paintings WHERE featured=1");
while($row = mysqli_fetch_array($result))
{
$id = $row['id'];
$name = $row['name'];
$desc = $row['longDesc'];
$cost = $row['cost'];
$qty = $row['quantity'];
$img = $row['imageFilename'];
$type = $row['type'];
echo "
<li id='featuredImage'>
<div id='featuredImage'><div id='details'>$name</div><img src='/$img'></div>
</li>";
}
?>
</ul>
Try this:
$(document).ready(function(){
$(".featuredImage img").hover(function(){
$(this).siblings(".imgDetails").fadeOut();
});
});
ID's are meant to be unique, use classes instead to match my code above... something like this:
<li class='imageWrap'>
<div class='featuredImage'><div class='imgDetails'>$name</div><img src='/$img'></div>
</li>
Demonstration: http://jsfiddle.net/UHXqd/
What your trying to do is easy to achieve:
Basically change $("#details").fadeOut(); to $(this).siblings("#details").fadeOut();.
But there are other things wrong with your code too:
You have multiple domElements with the same ID, what is quite unfortunate, IDs should be unique.
My advice: change the echo to
<li class='imageContainer'>
<div class='featuredImage'><div class='details'>$name</div><img src='/$img'></div>
</li>
And from here on dont use the '#' in the selectors, use the '.' to select classes, not ids.
$(".featuredImage img").hover(function(){
$(this).siblings(".details").fadeOut();
});
You should use siblings() because the details-div is on the same level as the image.

Need help in creating dynamic menu

I am developing a website using PHP and this is the 1st time I am trying a dynamic menu.
What I am doing is I have created a table for pages.
The table structure is as follows:
____________________________________________________________________________
|page_id|title|url|content|menu_title|show_on_navuigation|is_sub|parent_page|
|_______|_____|___|_______|__________|___________________|______|___________|
Here is_sub indicates whether it is a dropdown menu of some main menu. and parent_page is the main menu of the sub menu.
Now, what I want is, like
I have created 2 parent pages:
About Us and Test
and 2 sub menu's: Test aboutus and testsub,
Test aboutus is sub of About Us and testsub is sub of test.
How actually should the query and the loop, so that the menu renders perfectly.
Thanks in advance.
This is my menu structure:
<ul>
<li class='has-sub'><a href='#'><span>About Us</span></a>
<ul>
<li><a href='corporateprofile'><span>Corporate Profile</span></a></li>
<li class='last'><a href='visionandmission'><span>Vision & Mission</span></a></li>
</ul>
</li>
<li class='has-sub'><a href='#'><span>Business Services</span></a>
<ul>
<li><a href='recruitment'><span>Recruitment</span></a></li>
<li><a href='training'><span>Training</span></a></li>
<li><a href='executivesearch'><span>Executive Search</span></a></li>
<li><a href='payroll'><span>Payroll</span></a></li>
<li class='last'><a href='backgroundverification'><span>Background Verification</span></a></li>
</ul>
</li>
<li class='has-sub'><a href='#'><span>Employers</span></a>
<ul>
<li><a href='enquiry'><span>Enquiry</span></a></li>
<li><a href='jobdescription'><span>Job Description</span></a></li>
<li><a href='employercontract'><span>Employer Contract</span></a></li>
<li class='last'><a href='feedback'><span>Feedback</span></a></li>
</ul>
</li>
<li class='has-sub'><a href='javascript:;'><span>Job Seeker</span></a>
<ul>
<li><a href='applyforjob'><span>Apply For Job/Register</span></a></li>
<li><a href='careertips'><span>Career Tips</span></a></li>
<li><a href='interview Questions'><span>Interview Questions</span></a></li>
<li><a href='interviewprocess'><span>Interview Process</span></a></li>
<li class='last'><a href='corporatedress'><span>Corporate Dress</span></a></li>
</ul>
</li>
<li class='has-sub'><a href='#'><span>Franchise</span></a>
<ul>
<li class='last'><a href='#'><span>Franchise Enquiry Form</span></a></li>
</ul>
</li>
<li class='last'><a href='#'><span>Contact us</span></a></li>
</ul>
<?php
function displayMenu($parent_page_id) {
$sql = "SELECT * FROM `pages` WHERE `parent_page` = '$parent_page_id'"; // sql
$result = mysql_query($sql);
if( mysql_num_rows($result) === 0 ) { // mysql_num_rows() is deprecated, but you are using mysql extension so that's why I show it here
return true; // exit function
} // else, continue to rest of function
echo '<ul>';
while($row = mysql_fetch_assoc($result)) { // deprecated mysql php function here for simplicity
echo '<li>' . $result['menu_title'] . ''; // no closing </li> yet
displayMenu($row['page_id']); // this is the recursive part
echo '</li>'; // close the <li> from before the recursion
}
echo '</ul>';
}
$get_base_menu = mysql_query("SELECT * FROM pages WHERE parent_page = 0");
while($fetch_base_menu = mysql_fetch_array($get_base_menu))
{
$parent_page_id = $fetch_base_menu['page_id'];
displayMenu($parent_page_id);
}
?>
I highly suggest trying to get away from using an Adjacency List model and move toward a much easier to manage solution, such as a nested set. Using an MPTT type solution should help you manage your hierarchical data much easier. Using an Adjacency List model you are limited at a certain point.
I'd suggest looking into using something along the lines of Zebra_MPTT, or some other form of MPTT library. Please checkout this article on Managing Hierarchical data in MySQL.
I think the simplest thing for you to code will be something like this recursive function. All you have to do is put it on your page and make sure you have parent_page_id = 0 for the base level menu items. (I'm using parent_page_id instead of parent_page because I assume that is what you mean and it is more clear for the answer.)
Calling the function with an argument of "0" should give you the full menu tree.
$trace = array();
function displayMenu($parent_page_id) {
$sql = "SELECT * FROM `tbl_menu` WHERE `parent_page_id` = $parent_page_id"; // sql
$result = mysql_query($sql);
if( mysql_num_rows($result) === 0 ) { // mysql_num_rows() is deprecated, but you are using mysql extension so that's why I show it here
$trace[] = "Page_id $parent_page_id has no children";
return true; // exit function
} // else, continue to rest of function
echo '<ul>';
while($row = mysql_fetch_assoc($result)) { // deprecated mysql php function here for simplicity
$trace[] = "Entered while loop for page_id = $parent_page_id"; // not an error, just tracking
echo '<li>' . $row['menu_title'] . ''; // no closing </li> yet
displayMenu($row['page_id']); // this is the recursive part
echo '</li>'; // close the <li> from before the recursion
}
echo '</ul>';
}
displayMenu(0); // call function for base level
var_dump($trace);
More info:
I have researched the topic before and had a nice link to a page on mysql.com with an in-depth exploration of hierarchical relational database structures. But when I checked, the link was broken!
But, I think I found it on another site, here:
http://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/

Group by first letter, alphabetically, best way?

Here is my code:
<div class="widgeter-content no-padding">
<ul id="contacts">
<?php
while ($r = mysql_fetch_array($q)){
$currentletter = substr($name,0,1);
if ($currentletter != $lastletter){
?>
<!-- start li data group for specific alphabetic letter -->
<li data-group="<?=$currentletter;?>">
<a class="title"><?=strtoupper($currentletter);?></a>
<?
}
?>
<ul>
<li>
<a href="#">
<span><?=$name;?></span>
</a>
</li>
</ul>
<?
if ($currentletter != $lastletter){
?>
</li>
<!-- end data group (not currently working, ends on first result) -->
<?
}
$lastletter = $currentletter;
}
?>
</ul>
</div>
What I am trying to do:
A:
Alfred
Annie
B:
Bob
Billy
As you can see, the data is wrapped in an li data group.
The first part of the code works perfectly, but the last part (where I'm trying to put the closing li tag before the end comment, shows after the first result of each loop, where it needs to show at the END of each letters results).
What would be the best way to do this? I'm sure its quite obvious what I'm trying to achieve but I can't think of a logical way to get the code structuring how I want it to.
Thank you
$res = array();
while ($r = mysql_fetch_array($q)){
$currentletter = substr($name,0,1);
$res[$currentletter][] = $name;
}
foreach($res as $key=>$val){
/// here you add your li
/// here $key will give you letter and $val will give you name
echo $key;
foreach($val as $reqvals){
echo $reqvals;
echo "<br>";
}
}
What would be the best way to do this?
If you are fetching row from the database why can not rather GROUP BY there and get the records. That's the preferred way of doing it.
Assuming that the column name is first_name
group by substr(first_name,1,1)

querying in hierarchical data-structure in database and displaying results

I thought to implement advanced commenting system in my website using PHP-MySql. I finally settled for a 3-level comment-reply system for this purpose.
Well, for that purpose I came across this article to implement the data-structure of the SQL database.
I planned to use nested set mdoel for the feature I want to use. The structure of the comments are like this-
<ul>
<li>Parent comment</li>
<ul>
<li>First reply of parent comment</li>
<ul>
<li>reply of the previous reply</li>
<ul>
<li>reply of the previous reply</li>
<li>another reply of the previous reply</li>
</ul>
<li>another reply of the previous comment</li>
</ul>
<li>second reply of the parent comment</li>
</ul>
</ul>
For this type of structure, I have been playing around with PHP to show the query detecting the parents and its child uniquely(for fetching user details associated with each comment) and produce the output in the manner if shown above. Do anyone have idea how to do it. Please help me out.
EDIT :
I have a seperate user table in SQL linked to the comment table as user.id=comment.id. So considering this, what would be the recommended approach to detect user activity for each comment? I mean, for ex- I want to fetch user name and email for a sub-comment of parent comment 2. Hoow could it be done?
Use the query from "Finding the Depth of the Nodes", and this PHP code will create the nested lists.
$cur_depth = -1;
while ($row = mysqli_fetch_assoc($query)) { // Loop through results of query
if ($row['depth'] > $cur_depth) {
echo "<ul>\n";
$cur_depth = $row['depth'];
}
else while ($cur_depth > $row['depth']) {
echo "</ul>\n";
$cur_depth--;
}
echo "<li>" . $row['comment'] . "</li>\n";
}
while ($cur_depth > -1) {
echo "</ul>\n";
$cur_depth--;
}

displaying records from mysql in ul and li format with php

i want to display the mysql's fetched results with php and html in unordered list and list format as like http://www.miniclip.com/games/en/. you can see in the all games categories in the footer in alphabetical order. the same requirement i do have. i guess i have written the logic its working fine. but i am unable to represent it properly. you can see in the following link above the footer. http://www.playtoongames.com/play1...
code:
<?php
$gameQuery = mysql_query ("SELECT name, LEFT(name, 1) AS first_char FROM games WHERE UPPER(name) BETWEEN 'A' AND 'Z' OR name BETWEEN '0' AND '9' ORDER BY name");
$current_char = '';
while ($gameRow = mysql_fetch_assoc($gameQuery)){
if ($_SESSION['lang'] == 'fr'){
$description = $gameRow['description_fr'];
}else{
$description = $gameRow['description'];
}
?>
<div style='float:left' title="<img src='<?php echo $gameRow['sitePath'];?>games/images/<?php echo $gameRow['img_100x75'];?>' width='230' height='112' class='thumb' alt='<?php echo $gameRow['name'];?>'/>" class='tooltip'>
<ul>
<li>
<a href='<?php echo $gameRow['sitePath'];?>play/<?php echo str_replace(' ','_',$gameRow['name']);?>'><?php echo $gameRow['name'];?></a>
</li>
</ul>
</div>
can anybody look into this...
Regards,
sam.
On the Playtoons site, each <li> is in its' own individual <ul> - this means you're creating a new list for each item:
<ul>
<li>13 More Days</li>
</ul>
<ul>
<li>A Bikers Heaven</li>
</ul>
What you should be doing is using one <ul> which contains all the items as <li>s:
<ul>
<li>13 More Days</li>
<li>A Bikers Heaven</li>
</ul>
Well, I think the key is that there are 6 columns, which just means you'll need to break your array into 6 different parts.
Here's some psuedocode:
$pArr = $from_sql_array; // I'll let you take care of that.
$itmCount = count($pArr);
$itmsPerCol = ceil($itmCount / 6.0);
for ($ii=0; $ii < 6; $ii++)
{
$pCol = array_slice($pArr, $itmsPerCol * $ii, $itmsPerCol);
echo '<ul class="floatleft"><li>'.implode("</li>\n<li>",$pCol).'</li></ul>';
}

Categories