Como Criar um Menu Treeview Din√Ęmico com PHP

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: