SitePoint Sponsor

User Tag List

Results 1 to 5 of 5
  1. #1
    SitePoint Member
    Join Date
    Dec 2004
    Location
    Beaufort, SC
    Posts
    3
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Category/Sub-Category

    Hello to all my fellow PHP friends,

    I'm embarking on yet another trecherous adventure. This time Categories,
    Sub-Categories and Sub-Sub Categories..

    This is for a shopping cart module where the admin can create categories,
    sub-categories, and sub-sub categories and then place in a certain sub-sub
    category. This is a two fold question, first I will draw an example display
    of what I am trying to accomplish.

    Example:

    Code:
    Main Category
             |
              ---> Sub Category
                            |
                             ---> Sub-Sub Category
                                                  |
                                                  ---> Product
    Main Category2
             |
             ---> Sub Category2
                            |
                            ---> Sub-Sub Category2
                                                 |
                                                 ---> Product2
    Question 1:
    Admin needs to be able to create new sub categories and assign them to a
    main category and be able to create a sub-sub category to assign to a sub
    category and then a product to assign to a sub-sub category. When adding a
    new product the admin needs to select a main category which then creates a
    dropdown box for a subcategory, which then (IF admin chooses) create a
    dropdown box for a sub-sub category. Any ideas on how to create a function
    to handle this? I've seen lots of unstable javascript code to do this (not
    to mention difficult to manage)

    Question 2:
    When displaying the category/sub/sub-sub category listing to the viewers,
    whats the best way to handle the output?


    Thanks in advance for all your help,

    Tony Devlin
    Last edited by tdevlin; Dec 3, 2004 at 10:14. Reason: didn't fill out title completely.

  2. #2
    SitePoint Wizard
    Join Date
    Oct 2001
    Posts
    2,686
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Hi Tony.
    Welcome to SitePoint Forums.

    SitePoint has an article called Storing Hierarchical Data in a Database.
    That article explains both the The Adjacency List Model and the Modified Preorder Tree Traversal. Two different ways of storing hierarchical data.

    As for the admin section and adding a new product (or category) I would have made a sloution with only one dropdown. But that dropdown will be laying out the tree structure that you already have. For an example see the "Forum Jump" drop down on the bottom of this page.
    When having that dropdown you only choose the option you want the new product to be an descendant of. Then you know the path all the way to the main category. Did you get that?

    -Helge

    Off Topic:

    I moved your thread to the PHP forum as it's better suited here.

  3. #3
    SitePoint Member
    Join Date
    Dec 2004
    Location
    Beaufort, SC
    Posts
    3
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thanks for the headsup Helge, I thought this was an "advanced" thing because I didnt' know how to do it. =) ..

    Thank you for moving the post, sorry for posting in wrong thread. Thank you for the link. And Thanks for the welcome.

    Regards,
    Tony Devlin

  4. #4
    SitePoint Wizard
    Join Date
    Oct 2001
    Posts
    2,686
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    No worries Tony.

    Did you understand my explanation on how to select category when adding a new product.

    Also the The Adjacency List Model is easier to understand at first. It's just a table where you define the parent to the current category. This method is more database intensiv because it requires a recursive function that query the db on each iteration.

    The Modified Preorder Tree Traversal only require on database query to get the tree, but the logic behind it is more advanced.

    -Helge

  5. #5
    SitePoint Member
    Join Date
    Dec 2004
    Location
    Beaufort, SC
    Posts
    3
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I understood what you meant about how to select the category when adding a new product. Still trying to understand implementation of that solution.

    I've read both the Adjancency List and the PreOrder Tree List and think the second would by far out perform the first. I just get lost in the logic and have trouble following it.

    For instance both cases doesn't allow for sorting, IE: Admin needs ability to sort category/subcategory on public viewing how he/she wishes. If I use the PreOrder style I can't create a sort field to order by, becuase order by is already being used for lft .

    I knew it was not an easy task but did not think it was as complicated as some of these people talking on the forums about the category/subcategory subject make it seem.

    Perhaps I am overthinking my problem and because of that can not see the result right in front of me. I get that way sometimes. But I'll continue to play with the Adjancency List and the PreOrder List, hopefully I can make heads or tails from one of them to get it to work.

    Currently here's what I do but it only supports main category / subcategory effectively, not sub-sub category or further.
    PHP Code:
              // information for processing category/subcategory matching and displaying.
                function db_result_to_array($result)
                {
                   $res_array = array();
                   for ($count=0; $row = @mysql_fetch_array($result); $count++)
                     $res_array[$count] = $row;
                  return $res_array;
                }
                
                function get_maincategories()
                {
                   // query database for a list of categories
                   $query = "select id, name from category_main where status='Active' order by sort ASC"; 
                   $result = @mysql_query($query);
                      if (!$result)
                     return false;
                       $num_cats = @mysql_num_rows($result);
                   if ($num_cats ==0)
                     return false;  
                   $result = $this->db_result_to_array($result);
                   return $result; 
                }
                
                function display_maincategories($cat_array)
                {
                  if (!is_array($cat_array))
                    {
                        //no main category
                     return;
                    }
                  foreach ($cat_array as $row)
                  {
                     ?>
                        <div>
                        <h2 class='category'><?=$row['name'];?></h2></div>
                     <?
                        $subcat_array 
    $this->get_subcategories($row['id']);
                      
    $this->display_subcategories($subcat_array);
                    }    
                }
                
                function 
    get_subcategories($id)
                {
                    
    // query database for a list of categories
                   
    $query "select id, cat_name from category where maincat = $id AND status='Active' order by sort_order ASC"
                   
    $result = @mysql_query($query);
                       if (!
    $result)
                         return 
    false;
                           
    $num_subcats = @mysql_num_rows($result);
                       if (
    $num_subcats ==0)
                      return 
    false;      
                       
    $result $this->db_result_to_array($result);
                       return 
    $result
                }
                
                function 
    display_subcategories($subcat_array)
                {
                  if (!
    is_array($subcat_array))
                  {
                     
    //echo 'No sub categories<br />';
                     
    return;
                  }
                  foreach (
    $subcat_array as $row)
                  {
                    
    ?>
                    <div>
                        <a class="main" href="shop/index.php?catid=<?=$row['id'];?>"><?=$row['cat_name'];?></a>
                    </div>                
                    <?
                  
    }    
                }
    Thats the call to display the category/subcategory on the public visual side.

    The database just has a subcategory and maincategory table with a field on subcategory called maincat which matches the id of the maincategory field ID. Works "okay" on a single node, but as you can tell becomes unbearable and unmanageable on multiple nodes/subs/.

    My Javascript I use to display the category/subcategory on the admin page is also VERY limited and quite cumbersome.

    Code:
    			<tr>
    			 <td width="200">Main Category</td>
    			 <td align="left"><select name=catid style="width: 200px;" onchange="categoryselected(this);">
    			  <?
    				$query = "SELECT category_main.name,category.maincat,category.id,category.cat_name FROM category,category_main WHERE category.maincat=category_main.id ORDER BY sort";
    				$result = @mysql_query($query);
    				$sJavaScript = "function categoryselected(elem){\n for (var i = document.f1.category.options.length; i >= 0; i--){ \n document.f1.category.options[i] = null;\n"; 
            // loop through the database.. 
         		$sLastCategory="";
    				$sLastMainCat = ""; 
    				?>
            <option value="#" selected>Please Select Category</option> 
    				<?     
    				    while ( $row = mysql_fetch_object($result)) 
            		{ 
                		// is this a repeat category? 
                    If($sLastCategory == $row->name){
    								 //if yes, do nothing.
                    $sLastCategory = $row->name;
    								$sLastMainCat = $row->maincat; 								 
    								} else {
                    // if no, add the entry to the category listbox 
                    $sLastCategory = $row->name;
    								$sLastMainCat = $row->maincat;
                    echo "\n<option value='".$row->maincat."'>".$row->name."</option>";
                     // and add a new section to the javascript...
                    $sJavaScript = $sJavaScript."}\n"."if (elem.options[elem.selectedIndex].value==".$row->maincat."){\n";
                }
    		            // and add a new sub category to the javascript
                    $sJavaScript = $sJavaScript."document.f1.category.options[document.f1.category.options.length] = new Option('".addslashes($row->cat_name)."','".$row->id."');\n";
            } 
    			  ?>
    			 </td>
    			</tr>			
          <tr>
            <td width="200">Sub Category</td>
            <td align="left">
    				<select name="category" style="width: 200px;">
    				<option value="#" selected>[no sub category selected]</option>
    				</select>
    				<?$sJavaScript = $sJavaScript."\n}\n}\n"; ?> 
        		<SCRIPT LANGUAGE="JavaScript"><?=$sJavaScript;?></SCRIPT>
    				</td>
          </tr>
    Obviously I'm trying to make it so I can add MainCats, SubCats, and Sub-SubCats without soo much hassle and then be able to display that visually to both the admin and the public users easily. Possibly even be able to breadcrumb it for navigational purposes.

    If you have any comments on any of that or helpful information to my problem, by all means please let me know.

    Thanks again for the help and the inquiry.

    Regards,
    Tony Devlin
    Last edited by tdevlin; Dec 3, 2004 at 16:22. Reason: changed some words around


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •