Autocomplete com jQuery UI + PHP + MySQL
Hoje vamos montar um autocomplete utilizando jQuery UI, PHP e MySQL, essa funcionalidade tem sido cada vez mais requisitada em sites e sistemas administrativos via WEB. O autocomplete traz mais dinâmica para experiência do usuário em diversas situações quando necessário digitar caracteres em uma input para efetuar um consulta.
Atualmente acredito que o autocomplete que seja mais famoso e utilizado seja a caixa de pesquisa do Google, onde digitamos as inciais do termo de pesquisa que procuramos e obtemos algo parecido com o resultado abaixo.
Outro caso de uso são em cadastros de clientes ou produtos, com autocomplete o usuário não precisa saber a descrição completa do produto, bastando apenas digitar as primeiras letras para ser exibido instantaneamente uma listagem de produtos onde a descrição inicia com os caracteres informados.
Nesse post vamos simular uma pesquisa com cadastro de livros, onde após selecionar o registro desejado na listagem do autocomplete será enviado uma requisição AJAX para capturar todos os dados do livro e preencher os campos do formulário, tudo isso instantaneamente sem dar refresh na página.
Ambiente de desenvolvimento segue abaixo.
– Bootstrap (Sou horrível de Front-End então tenho que usar bootstrap srsr)
– jQuery
– PHP 5.5
– MySQL 5.5
Construindo Autocomplete
Para iniciar esse exemplo vou postar abaixo o script SQL para criação do banco de dados db_blog, tabela livro e também as instruções de INSERT para carregar os dados:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
/* Cria o banco de dados */ CREATE DATABASE IF NOT EXISTS `db_blog`; USE `db_blog`; /* Cria a tabela livros */ CREATE TABLE `livro` ( `id` int(11) NOT NULL AUTO_INCREMENT, `codigo_barra` varchar(20) DEFAULT NULL, `titulo` varchar(50) DEFAULT NULL, `categoria` varchar(50) DEFAULT NULL, `unidade` varchar(20) DEFAULT NULL, `valor_compra` decimal(9,2) DEFAULT NULL, `valor_venda` decimal(9,2) DEFAULT NULL, `status` varchar(10) DEFAULT NULL, `data_cadastro` date DEFAULT NULL, PRIMARY KEY (`id`) )ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=latin1; /* Instrução para INSERTs */ INSERT INTO `livro` VALUES (1,'3333333333333','Use a Cabeça Java','Java','UN',60.00,72.00,'Ativo','2015-07-03'), (2,'3333333333333','jQuery UI','jQuery','UN',30.00,49.00,'Ativo','2015-07-03'), (3,'2222222222222','A Arte do SEO','SEO','UN',90.00,102.00,'Ativo','2015-07-03'), (4,'4444444444444','PHP e MVC com CodeIgniter','PHP','UN',60.00,72.00,'Inativo','2015-07-03'), (5,'5555555555555','Android Cookbook','Android','UN',80.00,85.00,'Ativo','2015-07-03'), (6,'6666666666666','Programação Profissional em HTML5','HTML5','UN',100.00,120.00,'Ativo','2015-07-03'), (7,'7777777777777','CSS3','CSS','UN',50.00,62.00,'Inativo','2015-07-03'), (8,'8888888888888','Linux Guia do Administrador do Sistema','Linux','UN',100.00,120.00,'Ativo','2015-07-03'), (9,'1111111111111','JavaScript Guia do Programador','JavaScript','UN',70.00,92.00,'Ativo','2015-07-03'), (10,'9999999999999','Aprendendo Padrões de Projeto com PHP','PHP','UN',90.00,112.00,'Inativo','2015-07-03'), (11,'3333333333333','Java Web Services','Java','UN',40.00,59.00,'Ativo','2015-07-03'); |
Abaixo segue o script da index.php contendo o HTML da página, observem que estou usando para estilização somente as classes CSS do bootstrap:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
<!DOCTYPE html> <html> <head> <title>Exemplo Autocomplete com AJAX + PHP + MySQL</title> <link rel="stylesheet" type="text/css" href="css/bootstrap.min.css"> <link rel="stylesheet" type="text/css" href="css/jquery-ui.min.css"> </head> <body> <div class='container'> <header class="row"> <h1 class='text-center text-primary'>Autocomplete com jQuery UI + PHP + MySQL</h1> </header> <br> <div class="row"> <div class="form-group col-md-6 col-md-offset-3"> <input type="text" class="form-control" id="busca" placeholder="Informe o Título do Livro"> </div> </div> <header class="row"> <h2 class='text-center text-danger'>Detalhes do Livro</h2> </header> <br> <div class="row"> <form> <div class="form-group col-md-3"> <label for="titulo">Código de Barra</label> <input type="text" class="form-control" id="codigo_barra"> </div> <div class="form-group col-md-6"> <label for="titulo">Título do Livro</label> <input type="text" class="form-control" id="titulo_livro"> </div> <div class="form-group col-md-3"> <label for="exampleInputPassword1">Categoria</label> <input type="text" class="form-control" id="categoria"> </div> <div class="form-group col-md-3"> <label for="valor_compra">Valor de Compra</label> <input type="text" class="form-control" id="valor_compra"> </div> <div class="form-group col-md-3"> <label for="valor_venda">Valor de Venda</label> <input type="text" class="form-control" id="valor_venda"> </div> <div class="form-group col-md-3"> <label for="status">Status</label> <input type="text" class="form-control" id="status"> </div> <div class="form-group col-md-3"> <label for="data_cadastro">Data de Cadastro</label> <input type="text" class="form-control" id="data_cadastro"> </div> </form> </div> </div> <script type="text/javascript" src="js/jquery.js"></script> <script type="text/javascript" src="js/jquery-ui.min.js"></script> <script type="text/javascript" src="js/custom.js"></script> </body> </html> |
Agora o arquivo custom.js onde tem toda a mágica para o funcionamento do autocomplete, preenchimento dos campos e limpeza, o segredo desse código é o trabalho em conjunto do plugin jQuery UI com requisições AJAX intercaladas. Observem que o autocomplete é acionado somente após o segundo carácter ser digitado no input de pesquisa, limitamos com a propriedade minLenghth do plugin, poderíamos até colocar após o terceiro carácter, essa prática ajudaria em pesquisas mais específicas contendo mais informações para filtro WHERE da instrução SQL.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
$(function() { // Atribui evento e função para limpeza dos campos $('#busca').on('input', limpaCampos); // Dispara o Autocomplete a partir do segundo caracter $( "#busca" ).autocomplete({ minLength: 2, source: function( request, response ) { $.ajax({ url: "consulta.php", dataType: "json", data: { acao: 'autocomplete', parametro: $('#busca').val() }, success: function(data) { response(data); } }); }, focus: function( event, ui ) { $("#busca").val( ui.item.titulo ); carregarDados(); return false; }, select: function( event, ui ) { $("#busca").val( ui.item.titulo ); return false; } }) .autocomplete( "instance" )._renderItem = function( ul, item ) { return $( "<li>" ) .append( "<a><b>Código de Barra: </b>" + item.codigo_barra + "<br><b>Título: </b>" + item.titulo + " - <b> Categoria: </b>" + item.categoria + "</a><br>" ) .appendTo( ul ); }; // Função para carregar os dados da consulta nos respectivos campos function carregarDados(){ var busca = $('#busca').val(); if(busca != "" && busca.length >= 2){ $.ajax({ url: "consulta.php", dataType: "json", data: { acao: 'consulta', parametro: $('#busca').val() }, success: function( data ) { $('#codigo_barra').val(data[].codigo_barra); $('#titulo_livro').val(data[].titulo); $('#categoria').val(data[].categoria); $('#valor_compra').val(data[].valor_compra); $('#valor_venda').val(data[].valor_venda); $('#data_cadastro').val(data[].data_cadastro); $('#status').val(data[].status); } }); } } // Função para limpar os campos caso a busca esteja vazia function limpaCampos(){ var busca = $('#busca').val(); if(busca == ""){ $('#codigo_barra').val(''); $('#titulo_livro').val('') $('#categoria').val(''); $('#valor_compra').val(''); $('#valor_venda').val(''); $('#data_cadastro').val(''); $('#status').val('') } } }); |
Para finalizar o script consulta.php que é responsável por receber os parâmetros das consultas e devolver os dados no formato JSON para página index.php, observem que esse script retorna dados para 2 tipos de consultas diferentes. A primeira consulta com acao = ‘autocomplete’ retorna apenas os campos que serão exibidos no autocomplete, a segunda consulta com acao = ‘consulta’ retorna todos os dados do livro que são requisitados após selecionar um item na listagem do autocomplete.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
<?php // Dados da conexão com o banco de dados define('SERVER', 'localhost'); define('DBNAME', 'db_blog'); define('USER', 'root'); define('PASSWORD', '011224'); // Recebe os parâmetros enviados via GET $acao = (isset($_GET['acao'])) ? $_GET['acao'] : ''; $parametro = (isset($_GET['parametro'])) ? $_GET['parametro'] : ''; // Configura uma conexão com o banco de dados $opcoes = array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES UTF8'); $conexao = new PDO("mysql:host=".SERVER."; dbname=".DBNAME, USER, PASSWORD, $opcoes); // Verifica se foi solicitado uma consulta para o autocomplete if($acao == 'autocomplete'): $where = (!empty($parametro)) ? 'WHERE titulo LIKE ?' : ''; $sql = "SELECT codigo_barra, titulo, categoria FROM livro " . $where; $stm = $conexao->prepare($sql); $stm->bindValue(1, '%'.$parametro.'%'); $stm->execute(); $dados = $stm->fetchAll(PDO::FETCH_OBJ); $json = json_encode($dados); echo $json; endif; // Verifica se foi solicitado uma consulta para preencher os campos do formulário if($acao == 'consulta'): $sql = "SELECT codigo_barra, titulo, categoria, unidade, valor_compra, valor_venda, status, DATE_FORMAT(data_cadastro, '%d/%m/%Y') AS data_cadastro FROM livro "; $sql .= "WHERE titulo LIKE ? LIMIT 1"; $stm = $conexao->prepare($sql); $stm->bindValue(1, $parametro.'%'); $stm->execute(); $dados = $stm->fetchAll(PDO::FETCH_OBJ); $json = json_encode($dados); echo $json; endif; |
O layout final da página sem itens consultados ficou assim:
Fazendo uma pesquisa por livros que contenham as letras “ja”, observem que conforme o item selecionado na listagem do autocomplete são preenchidos os campos do formulário, isso graças a requisição AJAX que envia como parâmetro o título selecionado na listagem:
Vídeo complementar ao post
Bom pessoal espero que tenham gostado desse post e do vídeo complementar, esses scripts postados aqui podem ser infinitamente modificados e melhorados para melhor atender a necessidades do leitor, inclusive pode se optar pela utilização do outros tipos de plugin para autocomplete, existem diversos deles na WEB.
Até a próxima …