2013-06-19 50 views
2
<?php 
// Select all entries from the menu table 
$sql1 = $pardConfig->prepare("SELECT id, menu_title, menu_link, parent FROM pard_menu ORDER BY parent, sort, menu_title"); 
// Create a multidimensional array to conatin a list of items and parents 
$sql1->execute(); 

$menu = array(
    'items' => array(), 
    'parents' => array() 
); 
// Builds the array lists with data from the menu table 
while ($items = $sql1->fetch()) { 
    // Creates entry into items array with current menu item id ie. $menu['items'][1] 
    $menu['items'][$items['id']]   = $items; 
    // Creates entry into parents array. Parents array contains a list of all items with children 
    $menu['parents'][$items['parent']][] = $items['id']; 
} 


// Menu builder function, parentId 0 is the root 
function buildMenu($pardConfig, $parent, $menu) 
{ 
    $html = ""; 
    if (isset($menu['parents'][$parent])) { 
     $html .= " 
<ul>\n"; 
     foreach ($menu['parents'][$parent] as $itemId) { 
      if (!isset($menu['parents'][$itemId])) { 
       $html .= "<li>\n <a href='" . $menu['items'][$itemId]['menu_link'] . "'>" . $menu['items'][$itemId]['menu_title'] . "</a>\n</li> \n"; 
      } 
      if (isset($menu['parents'][$itemId])) { 
       $html .= " 
<li>\n <a href='" . $menu['items'][$itemId]['menu_link'] . "'>" . $menu['items'][$itemId]['menu_title'] . "</a> \n"; 
       $html .= buildMenu($pardConfig, $itemId, $menu); 
       $html .= "</li> \n"; 
      } 
     } 
     $html .= "</ul> \n"; 
    } 
    return $html; 
} 
echo buildMenu($pardConfig, 0, $menu); 

?> 

上面的代碼是一個包含PHP代碼來創建具有多級子menus.I動態菜單已預定義了類此...分類動態菜單添加特定類PHP的

  1. ul(第一UL)我有.nav
  2. 對於其中具有第一級子菜單任何li我有 .dropdown類鋰
  3. 此外,對於第二步驟i具有.dropdown-menuul elemnts 它具有作爲li
  4. 父元素,我有一個.dropdown-submenu類3級子菜單

所以我想修改我的代碼添加這些4個setps呢?任何幫助,將不勝感激 ?

我將使用bootsramp菜單API此

TAKE A LOOK @ THIS

這種方法我用jQuery做這樣bellow.but這不是很好的100%..

$(".nav-collapse").find("ul").first().addClass("nav"); 
    $(".nav-collapse").find("li").has("ul").addClass("nav"); 
    $(".nav").find("li:has(ul) a").attr("data-toggle", "dropdown"); 
    $('ul').filter(function() { 
     return $(this).parent().is('li') 
    }).addClass('dropdown-menu'); 
    $(".nav").find("li ul li").addClass("dropdown-submenu"); 
    $('.dropdown-toggle').dropdown(); 
    }); 
+2

那麼究竟什麼是你與你的代碼有問題嗎? –

+0

需要這樣的類添加到。它是很難做到這一點對我來說 – underscore

回答

4

你」通過不使用對象來表示菜單元素,使自己的代碼變得很難。正因爲如此,而且因爲你有效地建設的同時菜單結構渲染它,你的代碼是難以閱讀,以及很難想到,這就是爲什麼你發現很難讓它做你想要什麼。

重構代碼使用類的菜單元素完全菜單的建築從它的渲染,以及可以更容易地把明確的功能來決定如何將其呈現分離。

class MenuElement { 

    var $parent = null; 
    var $children = array(); 

    var $menuTitle; 
    var $menuLink; 

    function __construct($parent, $menuTitle, $menuLink){ 
     $this->parent = $parent; 
     $this->menuTitle = $menuTitle; 
     $this->menuLink = $menuLink; 
    } 

    function hasParent(){ 
     if ($this->parent) { 
      return true; 
     } 
     return false; 
    } 

    function addChild($child){ 
     $this->children[] = $child; 
    } 

    function hasChildren(){ 
     return count($children); 
    }  

    function hasGrandParent(){ 
     if ($this->parent) { 
      return $this->parent->hasParent(); 
     } 
     return false; 
    } 

    function render() { 
     $navClass = ''; 
     $ulClass = ''; 
     $liClass = ''; 

     if ($this->parent == false) { 
      //For main ul (First Ul) i have .nav class 
      $navClass = 'nav'; 
     } 

     if (count($this->children)){ 
      //For any li where has first level sub menus i have .dropdown class for li 
      $liClass = 'dropdown'; 
     } 


     if($this->parent) { 
      //Additionally for 2nd step i have .dropdown-menu class for 
      //ul elemnts which it has a parent element as a li 
      $ulClass = 'dropdown-menu'; 
     } 
     if ($this->hasGrandParent() == true){ 
      //And i have a .dropdown-submenu class for 3rd level sub menus 
      $ulClass = 'dropdown-submenu'; 
      //$ulClass .= ' dropdown-submenu'; if you wanted both classes 
     } 

     $output = "<ul class='$navClass'>"; 
     $output .= "<li class='$liClass'>"; 
     $output .= "<a href='".$this->menuLink."'>".$this->menuTitle."</a>"; 

     foreach ($this->children as $child) { 
      $output .= $child->render(); 
     } 

     $output .= "</li>"; 
     $output .= '</ul>'; 

     return $output; 
    } 
} 


//Builds a menu and returns the root element of it. 
function buildMenu(){ 
    $rootElement = null; 
    // Select all entries from the menu table 
    $sql1 = $pardConfig->prepare("SELECT id, menu_title, menu_link, parent FROM pard_menu ORDER BY parent, sort, menu_title"); 
    // Create a multidimensional array to conatin a list of items and parents 
    $sql1->execute(); 

    $menuElements = array(); 

    while ($items = $sql1->fetch()) { 
     $parent = null; 

     $parentID = $items['parent']; 

     if ($parentID) { 
      if(array_key_exists($parentID, $menuElements) == true) { 
       $parent = $menuElements[$parentID]; 
      } 
      else{ 
       throw \Exception("Tried to reference parent which doesn't exist"); 
      } 
     } 

     $id = $items['id']; 
     $menuElements[$id] = new MenuElement($parent, $items['menu_title'], $items['menu_link']); 

     if ($id == 0) { 
      $rootElement = $menuElements[$id]; 
     } 

     if ($parent) { 
      $parent->addChild($menuElements[$id]); 
     } 
    } 

    if ($rootElement == null) { 
     throw Exception("Root element not found, menu is borked"); 
    } 

    //TODO - you may prefer to return $menuElements 
    return $rootElement; 
} 


$menu = buildMenu(); 
$output = $rootElement->render(); 
echo $output; 

順便說一句,這是在一個地方仍然不好的代碼,因爲它混合從數據庫檢索菜單與建設它。最好將它們分開,以便您可以根據所需數據源動態構建菜單。

此外,表中的parent的列名將更好,因爲它可以防止$ parentID變量(它是一個ID)和$ parent變量(它是一個對象)之間的混淆。

而且沒有我還沒有調試這一點 - 答案是隻是爲了顯示它如何做。

+0

它有很多錯誤的 – underscore

+4

@Samithaఠ_ఠ的PHP:一點不給他答案複製原樣,而是要了解如何解決您的問題。 – Lepidosteus

+0

@Samithaఠ_ఠ現在已經修復了兩個錯別字。是的,該代碼顯示瞭如何做到這一點,而不是生產就緒的代碼片段。 – Danack