tadarank afiliados

07 fevereiro, 2008

Fazer um menu com vários níveis. BD + PHP + JS + CSS

Ae pessoal,
Há um tempo eu tinha criado um esquema e função PHP pra gerar um UL-LI para fazer um menu tipo pai e filhos, sendo que a quantidade de filhos e netos poderia ser infinita.
Hoje deu vontade de sair um pouco do javascript de sempre e postar essa parada aqui no blog. Desde a organização da tabela no Banco de Dados, função PHP pra gerar os UL-LI e finalizando com links pra estilizar este menu UL-LI.
Lá vai:
1) Para o menu (pai e filhos) será necessário apenas 1 tabela com o nome de 'menus'. Só executar a seguinte SQL no Banco de dados:
CREATE TABLE `menus` (
`id` tinyint(3) unsigned NOT NULL auto_increment,
`pai_id` tinyint(3) unsigned NOT NULL default '0',
`ordem` tinyint(3) unsigned NOT NULL default '0',
`visivel` tinyint(3) unsigned NOT NULL default '1',
`nome` varchar(30) NOT NULL default '',
`link` varchar(150) default NULL,
PRIMARY KEY (`id`),
KEY `pai_id` (`pai_id`,`ordem`,`visivel`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT
O SQL acima manda criar uma tabela chamada 'menus' onde o truque está no campo pai_id.
Em cada registro, o campo pai_id irá apontar para o ID de outro registro na mesma tabela, indicando que ele é o seu pai. Se a entrada não tiver pai, o campo pai_id deve ficar com 0 (zero).
Image Hosted by ImageShack.us - "Ó PÓOOOOI!!"

2) Preencha sua tabela lembrando de colocar visivel=1 para os menus que quer que sejam visíveis e colocando a ordem de cada menu. O campo pai_id indica qual o ID do menu pai, se ele for um menu principal (pai) sem outro pai, este campo deve ficar com '0'.
Exemplo pra fazer o submenu:
comidas
- arroz
- feijao
guloseimas
- chocolate
- maquindonalds
---- sanduiche porco
---- sanduiche pequeno
Teremos:
comidas (pai_id=0)
- arroz (pai_id = id do 'comidas')
- feijao (pai_id = id do 'comidas')
guloseimas (pai_id=0)
- chocolate (pai_id = id do 'guloseimas')
- maquindonalds (pai_id = id do 'guloseimas')
---- sanduiche porco (pai_id = id do 'maquindonalds')
---- sanduiche pequeno (pai_id = id do 'maquindonalds')
3) Adicione a seguinte função à sua biblioteca de funções (você já tem que estar conectado ao bd antes de usar esta função né?):
function gera_menu($cod_ul_pai,$tabs,$id_do_pai){
    //gera um menu ul com submenus
    //by Micox - elmicox.blogspot.com - forum.ievolutionweb.com
    //exemplo: gera_menu("<ul>","    ",0)
    $recc = mysql_query("SELECT * FROM menus WHERE pai_id=$id_do_pai AND visivel=1 ORDER BY ordem");
    $ret = $cod_ul_pai."\r\n";
    if($recc==true){
        while($linha = mysql_fetch_array($recc,MYSQL_ASSOC)){
            if(isset($linha['link'])){
                $href = $linha['link'];
            }else{
                $href = '';
            }
            $ret .= $tabs."    <li><a href='$href'>".htmlentities($linha['nome'])."</a>";
            //testando se tem filhos
                $recfilho = mysql_query("SELECT * FROM menus WHERE pai_id=$linha[id] AND visivel=1 ORDER BY ordem");
                if(mysql_num_rows($recfilho)>0){
                    $ret .= "\r\n".$tabs."        ".gera_menu("<ul>",$tabs."        ",$linha['id'])."    ".$tabs;
                }
            //fim filhos
            $ret .= "</li>\r\n";
        }
        mysql_free_result($recc);
    }
    $ret .= $tabs."</ul>\r\n";
    return $ret;
}
4) Chame a função onde vc quer que gere o menu:
<?php echo gera_menu("<ul>","        ",0) ?>
5) Isso aí irá gerar um menu como este exemplo:
<ul>
  <li><a href='produtos.php?text=3'>Produtos e Serviços</a>
    <ul>
      <li><a href='produtos.php?Gravadores_Monolinha&cat=1&text=14'>Gravadores Monolinha</a></li>
      <li><a href='produtos.php?Gravadores_Multilinha&cat=2&text=15'>Gravadores Multilinha</a></li>
      <li><a href='produtos.php?Outros_produtos&cat=3&text=16'>Outros produtos</a></li>
    </ul>
  </li>
  <li><a href='conteudo.php?Revendas&text=4'>Revendas</a>
    <ul>
      <li><a href='conteudo.php?Brasil&text=17'>Brasil</a></li>
      <li><a href='conteudo.php?Internacional&text=18'>Internacional</a></li>
      <li><a href='conteudo.php?Seja_um_revendedor&text=19'>Seja um revendedor</a></li>
    </ul>
  </li>
  <li><a href='conteudo.php?Clientes&text=5'>Clientes</a></li>
  <li><a href='conteudo.php?Suporte&text=6'>Suporte</a></li>
</ul>
6) Pronto, agora é só estilizar com algum tutorial de menu, treemenu (menu em árvore), menu drop down horizontal, vertical, etc.
Té. Dúvidas, pergunta lá no fórum :) Gostou da dica acima? Então clica nos botões de compartilhamento abaixo e me ajude a dica a subir no Google.

22 comentários:

  1. Show de bola esse menu, muito bom mesmo.

    Ta rolando uma promoção lá no meu blog, se tiver afim entra lá.

    ResponderExcluir
  2. grande micox! Respondi lá teu comment! O script foi de uso pessoal, por isso não fiz maiores firulas para segurança.

    Vlw pela visita e pelo comentário! :)

    ResponderExcluir
  3. Nairon, parabéns...
    Com esse sistema de criação de menu, pude tirar uma nuvem que estava em minhas ideias.
    Seu nome será adicionado ao meu projeto como colaborador.
    Vou adaptar para minha realidade e quando tiver algo mais refinado posso te mandar.

    Att.

    Marcos

    ResponderExcluir
  4. Opa, valeu os elogios ae.
    Não se esqueça que eu amo links heim hahehaehe.

    Depois me diga qualé o projeto.
    té.

    ResponderExcluir
  5. ei micox. achei muito bacana seu artigo.
    baseado nele, escrevi um identico mais usando sql e mssql.
    abraço fera.

    ResponderExcluir
  6. opa esqueci do link
    http://blog.guilhermesilva.net/?p=9


    xD
    vlw

    ResponderExcluir
  7. Gostei das Informações, criação e desenvolvimento do Site!!!!

    ResponderExcluir
  8. Marcelo Pessoa01 junho, 2009 13:32

    Ola na consegui no caso criar os submenus q seriam os filho como faço pra criar ta tabla sql

    ResponderExcluir
  9. Nossa...era de algo assim que eu precisava, mas ja tenho pronto o esquema de cadastro, edição e exclusão com duas tabelas, uma para categoria e outra para subcategoria.

    Não consigo criar algo assim..rs
    Teria como me ajudar a adaptar para o meu?

    minhas tabelas são as seguintes:

    INSERT INTO `teste_menu` (`id_categoria`, `categoria`) VALUES
    (1, 'Seriados'),
    (2, 'Novelas');

    INSERT INTO `teste_submenu` (`id_subcategoria`, `id_categoria`, `subcategoria`) VALUES
    (1, 2, '7 Pecados'),
    (2, 1, 'Dr. House'),
    (3, 1, 'CSI Miami'),
    (4, 1, 'Os Simpsons'),
    (5, 1, '24 Horas'),
    (6, 2, 'Caminho das Indias');

    Estou selecionando a tabela da seguinte forma:

    SELECT s.id_subcategoria, s.id_categoria, s.subcategoria, c.categoria FROM teste_submenu AS s INNER JOIN teste_menu AS c ON s.id_categoria = c.id_categoria ORDER BY s.id_subcategoria DESC


    Por favor se poder me ajudar eu agradeço muito!! meu chefe quer me matar e não consigo terminar isso..rs

    ResponderExcluir
  10. Cara, só uma dúvida, esse menu é infinito?

    posso colocar varias dimensões?

    Pois, pelo que pude entender ele vai somente 2 dimensões.

    Abraço.

    ResponderExcluir
  11. Cara sei que o post e um pouco antigo mas encontrei um errinho.. ele deix ao link para os itens que possuem sub-menus:

    Alterei para:
    if(isset($linha['id'])){
    $href = 'conteudo.php?id='.$linha['id'];
    }else{
    $href = '#';
    }

    e mesmo assim ele exibe o link

    ResponderExcluir
  12. Cara, acho que vc se refere a esta parte aqui né?

    if(isset($linha['link'])){
    $href = $linha['link'];
    }else{
    $href = '';
    }

    Eu deixei assim pois, mesmo menus pai (que tem submenus) podem ter links. Muitas pessoas gostam assim, inclusive eu. O visitante pode escolher direto pro sub-menu ou então CLICAR também no menu pai.

    ResponderExcluir
  13. Exatamente essa parte... (é que postei o codigo que já estava alterando aqui) Achei que esse ELSE era pra tirar o link caso fosse uma categoria pai...

    Vou tentar fazer essa verificação na linha que exibe o link abraços e obrigado pela resposta

    ResponderExcluir
  14. Isso. Este ELSE não é pra pai's e sim pra qualquer menu que não tenha link definido. Às vezes um sub-menu pode não ter link (o cara pode querer só dar um aviso) OU, às vezes, um pai pode ter um link também heheh.

    ResponderExcluir
  15. ahn sim.. agora saquei a lógica...
    Vou incluir o link direto no banco então...

    Valeu abraços

    ResponderExcluir
  16. Tive o erro "Warning: mysql_free_result() expects parameter 1 to be resource, boolean given in" por onde eu começo a procurar o erro?

    Att.

    ResponderExcluir
  17. Pela linha do onde tem o mysql_free_result, provavelmente seu sql não tá retornando nada. Sobe o mysql_free_result pra dentro do if (aliás, eu deveria ter feito isso. vou corrigir e fazer agora hehe)

    ResponderExcluir
  18. Obrigado. Tudo certo agora =D

    ResponderExcluir

Resultado! Concursos