Create infinite menu with PHP + CSS + JS

4

I have a menu (vertical) that works as an accordion, this in turn, needs to open the "children" unlimited (my problem is solved, and I can not), since it will be a menu for a store. p>

As follows:

-CATEGORIA PAI

- CATEGORIA FILHO

- CATEGORIA FILHO

   - CATEGORIA PAI

   - CATEGORIA PAI

      - CATEGORIA FILHO

      - CATEGORIA FILHO

         -CATEGORIA PAI

           - CATEGORIA FILHO

           - CATEGORIA FILHO

And for the auto and forward ...

But I'm not getting that feat ...

So, if you can, could you give me some help in this situation?

From now on I am immensely grateful.

This is my JS code (taken from NET):

// Evento de clique do elemento: ul#menu li.parent > a
$('ul#menu li.parent > a').click(function() {
// Expande ou retrai o elemento ul.sub-menu dentro do elemento pai (ul#menu li.parent)
  $('ul.sub-menu', $(this).parent()).slideToggle('fast', function() {
  // Depois de expandir ou retrair, troca a classe 'aberto' do <a> clicado       
  $(this).parent().toggleClass('aberto');
  });
return false;
  });

PHP:

public static function getHtmlMenu($menu){
        $return = '';
        foreach($menu as $m){
            $class = ($m['NIVEL'] == '0') ? 'parent' : '';
            $return .= '<li class="'.$class.'"><a href="'.SITEURL.'produtos/'.$m['ID'].'/'.$m['ALIAS'].'" title="'.$m['TITULO'].'">'.$m['TITULO'].'</a>'.PHP_EOL;
                if(sizeof($m['SUB']) > 0){
                    $return .= '<ul class="sub-menu">'.PHP_EOL;
                        $return .= self::getHtmlMenu($m['SUB']);
                    $return .= '</ul>'.PHP_EOL;
                }
            $return .= '</li>'.PHP_EOL;
        }
        return $return;
    }

CSS:

.parent > a {
    background: url("../images/menul.png") no-repeat scroll 0 0 rgba(0, 0, 0, 0);
    color: #052754;
    display: block;
    font-size: 10.3px;
    font-weight: bold;
    height: 21px;
    padding: 5px 5px 0;
    text-transform: uppercase;
}

ul ul {
    display: none;
}

.sub-menu > li {
    background: none repeat scroll 0 0 #FFFFFF;
    height: 21px;
    overflow: hidden;
    padding: 1px 0;
    width: 243px !important;
}

.sub-menu a {
    background: none repeat scroll 0 0 #FFFFFF;
    border: 1px solid #CCCCCC;
    color: #052754;
    display: block;
    font-size: 12px;
    padding: 3px 0 3px 10px;
    text-transform: uppercase;
}

I really forgot to report my problem. What happens is that this menu goes down only to the 2nd level, and I would like it to be "infinite". That is, if there are sub-menus it still works on JS and CSS.

As for the order of the list, it is right ... Running within PHP is as follows:

 <ul><li><!--repete o <ul> anterior caso tenha novos "subs"--></li></ul>
    
asked by anonymous 28.02.2014 / 15:43

4 answers

2

The problem is in Javascript. You need to run the same function for all navigation elements, not only for the parent and their direct descendants.

// Evento de clique do elemento: ul#menu li > a (todos os itens do menu)
$('ul#menu li > a').click(function() {
  // Expande ou retrai o <ul.submenu> irmão do <a> clicado
  $(this).siblings('.sub-menu').slideToggle('fast', function() {
    // Depois de expandir ou retrair, troca a classe 'aberto' do <a> clicado       
    $(this).siblings('a').toggleClass('aberto');
  });
  return false;
});

PS: The code of your fiddle is changing the ul's by li's.

    
28.02.2014 / 17:29
0

The problem is in your CSS and Jquery.

Removing the ul ul {display: none;} property displays the submenu.

    
28.02.2014 / 16:53
0
<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>Menu - Infinito</title>
  <link rel="stylesheet" href="http://code.jquery.com/ui/1.10.4/themes/smoothness/jquery-ui.css">
  <script src="http://code.jquery.com/jquery-1.9.1.js"></script><scriptsrc="http://code.jquery.com/ui/1.10.4/jquery-ui.js"></script>
  <script>
  $(function() {
    $( "#menu" ).menu();
  });
  </script>
  <style>
  .ui-menu { width: 150px; }
  </style>
</head>
<body>

<ul id="menu">
  <li class="ui-state-disabled"><a href="#">Aberdeen</a></li>
  <li><a href="#">Home</a></li>
  <li><a href="#">Adamsville</a></li>
  <li><a href="#">Addyston</a></li>
  <li>
    <a href="#">Delphi</a>
    <ul>
      <li class="ui-state-disabled"><a href="#">Ada</a></li>
      <li><a href="#">Saarland</a></li>
      <li><a href="#">Salzburg</a></li>
    </ul>
  </li>
  <li><a href="#">Saarland</a></li>
  <li>
    <a href="#">Salzburg</a>
    <ul>
      <li>
        <a href="#">Delphi</a>
        <ul>
          <li><a href="#">Ada</a></li>
          <li><a href="#">Saarland</a></li>
          <li><a href="#">Salzburg</a></li>
        </ul>
      </li>
      <li>
        <a href="#">Delphi</a>
        <ul>
          <li><a href="#">Ada</a></li>
          <li><a href="#">Saarland</a></li>
          <li><a href="#">Salzburg</a></li>
        </ul>
      </li>
      <li><a href="#">Perch</a></li>
    </ul>
  </li>
  <li class="ui-state-disabled"><a href="#">Amesville</a></li>
</ul>
</body>
</html>

Here is a code that can show you some things.

Source: link

    
09.03.2014 / 16:44
0

How to make an infinite menu in a simple way:

class MenuInfinito
{

    public  function imprimeMenuInfinito( array $menuTotal , $idPai = 0, $nivel = 0 )
    {
      $menu = "";
        // abrimos a ul do menu principal
        $menu.= str_repeat( "\t" , $nivel ),'<ul class="dropdown">',PHP_EOL;
        // itera o array de acordo com o idPai passado como parâmetro na função
        if (count($menuTotal[$idPai])) {
           foreach( $menuTotal[$idPai] as $idMenu => $menuItem) {
            // imprime o item do menu
            $menu.= str_repeat( "\t" , $nivel + 1 ),'<li '.$menuItem['classe'].'><a href="',$menuItem['link'],'">',$menuItem['name'],'</a>',PHP_EOL;
            // se o menu desta iteração tiver submenus, chama novamente a função
            if( isset( $menuTotal[$idMenu] ) ) $this->imprimeMenuInfinito( $menuTotal , $idMenu , $nivel + 2);
            // fecha o li do item do menu
            $menu.= str_repeat( "\t" , $nivel + 1 ),'</li>',PHP_EOL;
           }
        }
        // fecha o ul do menu principal
        $menu.= str_repeat( "\t" , $nivel ),'</ul>',PHP_EOL;
    } 
     return $menu;
}

EXAMPLE TABLE:

CREATE TABLE 'tab_categorias' (
  'id_categoria' int(11) NOT NULL AUTO_INCREMENT,
  'id_pai' int(11) NOT NULL DEFAULT '0',
  'categoria' varchar(255) DEFAULT NULL,
  'slug' varchar(50) DEFAULT NULL,
  'permissao' tinyint(3) NOT NULL DEFAULT '1' COMMENT '1 - ativo, 0 - inativo',
  'ordem' int(11) NOT NULL DEFAULT '1',
  'url' varchar(255) DEFAULT NULL,
  'classe' varchar(255) DEFAULT NULL,
  'menu' tinyint(3) NOT NULL DEFAULT '0' COMMENT '0 - nenhum, 1 - topo, 2 - rodape, 3 - topo e rodape',
  PRIMARY KEY ('id_categoria')
) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=latin1 COMMENT='tabela de categorias';

Sample SQL:

$sql = "SELECT cat.*,
               cat.categoria AS menuNome,
               cat.id_categoria AS menuId,
               cat.id_pai AS menuIdPai 
        FROM   tab_categorias cat 
        WHERE  cat.permissao=1 
        AND    (cat.menu=1 or cat.menu=3) 
        ORDER BY cat.id_pai ASC, 
                 cat.ordem ASC,
                 cat.categoria ASC, 
                 cat.id_categoria DESC,
                 cat.slug ASC";

Sample list:

$menuItens = array();
while($row = $conn->query($sql)) {
    $id_cat = $row['menuId'];
      if ($row['slug']!='') {
         $url_link=$row['slug'];
      } else {
         $url_link =$row['url'] 
      }
     $classe " class='item_{$row['menuId']}'"; 

     $menuItens[$row['menuIdPai']][$row['menuId']] = array(
         'link' => $url_link,
         'name' => $row['menuNome'],
         'classe' => $classe
     );
}
$menu = new MenuInfinito();
echo $menu->imprimeMenuInfinito($menuItens);
    
05.04.2018 / 23:42