Como Criar um Menu Treeview Dinâmico com PHP

Nesse Tutorial, vou te mostrar como Como Criar um Menu Treeview Dinâmico com PHP, ou seja, um daqueles modelos que exibe uma árvore como os diretórios do Windows.

Em outras palavras, vamos criar uma estrutura dinâmica – porque vem do banco de dados – que vai mostrar um menu em vários níveis.

E, talvez o ponto forte desse tutorial e disso que vamos criar, porque você poderá ter infinitos níveis, trazendo registros direto do MySQL.

Agora, mesmo sendo um script para criação de menus, nada impede você de utilizá-lo para criar um estrutura em níveis, seja de categorias, genealogia ou qualquer outra coisa que tenha itens e sub-itens.

Então vamos codar!

Passo 1: Criação da Tabela MySQL

Vamos criar uma tabela de menu com 5 colunas:

  • id – que será único e auto incrementado
  • label – Título do item
  • link – URL
  • parent – id do pai
  • sort – para ordenarmos se quisermos

Então, ficaria assim:

CREATE TABLE IF NOT EXISTS `menus` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `label` varchar(50) NOT NULL,
  `link` varchar(100) NOT NULL,
  `parent` int(11) NOT NULL DEFAULT '0',
  `sort` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=17 ;

Uma pequena observação: O AUTO_INCREMENT está setado para 17 porque vamos adicionar 16 registros a seguir.

Passo 2: Inserção de dados na tabela MySQL

Agora que temos a estrutura da nossa tabela pronta e já criamos a mesma no banco de dados, vamos inserir alguns dados de teste:

INSERT INTO `menus` (`id`, `label`, `link`, `parent`, `sort`) VALUES
(1, 'PHP', '#', 0, 0),
(2, 'Tutorials', '#', 1, NULL),
(3, 'Scripts', '#', 1, NULL),
(4, 'Arrays', '#', 2, NULL),
(5, 'Operators', '#', 2, NULL),
(6, 'Arithmetic operators', '#', 5, NULL),
(7, 'Assignment operators', '$', 5, NULL),
(8, 'Java', '#', 0, NULL),
(9, 'Tutorials', '', 8, NULL),
(10, 'Programs', '', 8, NULL),
(11, 'JavaScript', '#', 0, NULL),
(12, 'MySQL', '#', 0, NULL),
(13, 'CSS', '', 0, NULL),
(14, 'Tutorials', '', 13, NULL),
(15, 'Servlet', '', 9, NULL),
(16, 'JSP', '', 9, NULL);

Passo 3: Obtenção de dados da tabela

Agora que temos nossa tabela populada com registros de teste, podemos fazer um SELECT para consultar e trazer os dados da tabela:

<?php
$sql = "SELECT id, label, link, parent FROM menus ORDER BY parent, sort, label";
$result = mysqli_query($conn, $sql) or die("database error:". mysqli_error($conn));
// Criar um Array para conter uma lista de itens e pais
$menus = array(
	'items' => array(),
	'parents' => array()
);
// Construimos o Array com dados do SQL
while ($items = mysqli_fetch_assoc($result)) {
	// Cria um array a partir do id do item
	$menus['items'][$items['id']] = $items;
	// Criar uma lista de todos os itens com filhos
	$menus['parents'][$items['parent']][] = $items['id'];
}
// Mostra toda a árvore de menu usando uma função que criamos
echo createTreeView(0, $menus);
?>

Esse pode ser seu arquivo index.php e você deve perceber que logo no início rodamos a função mysql_query e estamos usando uma variável $conn.

Essa variável deve conter a conexão com o BD – $conn = mysqli_connect e você pode colocar em um arquivo separado e chamar com require ou include.

Passo 4: Criação da estrutura dinâmica – Treeview

Agora que montamos nosso array menus contendo todos os itens e também a lista de itens com filhos – array multidimensional – vamos criar uma função para montar a estrutura:

function createTreeView($parent, $menu) {
   $html = "";
   if (isset($menu['parents'][$parent])) {
      $html .= "
      <ol class='tree'>";
       foreach ($menu['parents'][$parent] as $itemId) {
          if(!isset($menu['parents'][$itemId])) {
             $html .= "<li><label for='subfolder2'><a href='".$menu['items'][$itemId]['link']."'>".$menu['items'][$itemId]['label']."</a></label> <input type='checkbox' name='subfolder2'/></li>";
          }
          if(isset($menu['parents'][$itemId])) {
             $html .= "
             <li><label for='subfolder2'><a href='".$menu['items'][$itemId]['link']."'>".$menu['items'][$itemId]['label']."</a></label> <input type='checkbox' name='subfolder2'/>";
             $html .= createTreeView($itemId, $menu);
             $html .= "</li>";
          }
       }
       $html .= "</ol>";
   }
   return $html;
}

Basicamente, temos um função única, mas, se tivermos um item com filhos, vamos rodar a mesmo função internamente para montar os subitens.

Recomendo você criar um arquivo de funções e colocar essa função lá e depois fazer um include no seu arquivo principal.

Passo 5: Montando o Treeview com CSS

Agora que temos a parte dinâmica construída, podemos usar um pouco de CSS para estilizar nosso Script.

Um detalhe que você deve observar é que não precisamos usar JavaScript, basta usar um truque de CSS para criar um estilo “expande e contrai” para subitens:

/* CSS to style Treeview menu  */
ol.tree {
	padding: 0 0 0 30px;
	width: 300px;
}
li { 
	position: relative; 
	margin-left: -15px;
	list-style: none;
}      
li input {
	position: absolute;
	left: 0;
	margin-left: 0;
	opacity: 0;
	z-index: 2;
	cursor: pointer;
	height: 1em;
	width: 1em;
	top: 0;
}
li input + ol {
	background: url(images/toggle-small-expand.png) 40px 0 no-repeat;
	margin: -1.600em 0px 8px -44px; 
	height: 1em;
}
li input + ol > li { 
	display: none; 
	margin-left: -14px !important; 
	padding-left: 1px; 
}
li label {
	background: url(images/folder.png) 15px 1px no-repeat;
	cursor: pointer;
	display: block;
	padding-left: 37px;
}
li input:checked + ol {
	background: url(images/toggle-small.png) 40px 5px no-repeat;
	margin: -1.96em 0 0 -44px; 
	padding: 1.563em 0 0 80px;
	height: auto;
}
li input:checked + ol > li { 
	display: block; 
	margin: 8px 0px 0px 0.125em;
}
li input:checked + ol > li:last-child { 
	margin: 8px 0 0.063em;
}

É isso! Essa é a base…

Acho que podemos classificar esse Script como intermediário, não acha?

Deixe seus comentários abaixo e se quiser pode baixar na integrar no meu Github:

DEIXE UMA RESPOSTA

Escrava seu comentário!
Insira seu nome aqui

Esse site utiliza o Akismet para reduzir spam. Aprenda como seus dados de comentários são processados.