Codeigniter + jqTransform + Combos dinâmicos

Esse post é em homenagem a meu amigo Ubiracy mais conhecido como Bira-bira-birô hehehehe, que junto comigo, se mordeu todo pra tentar resolver esse problema. Depois de muito pesquisar e nada encontrar, conseguimos criar elementos options em tempo de execução no jqTransform, que é um plugin jquery pra customizar a cara dos formulários. Bonitinho mas ordinário.

Pois bem, vamos precisar de:

  • jqTransform
  • Algum conhecimento em JSON
  • Algum conhecimento em Ajax
  • Codeigniter (opcional)

A solução funciona da seguinte forma, você vai criar dois combos, um de estados e outro de cidades. Os itens do combo de cidades vão ser carregados dinamicamente via ajax a depender do que foi selecionado no combo de estados.

  1. JSON
    Crie um método em seu model que realiza a consulta de cidades
    public function lista_cidades($id_estado)
    {
        $this->db->select("id, nome");
        $this->db->where("id_estado", $id_estado);
    
        return $this->db->get("cidades");
    }
    

    Em seu controller, crie um novo método público que escreva no browser o resultado da consulta no padrão json.

    public function cidades($id_estado)
    {
        header('Content-type: application/json');
        $this->load->model("cidade_model");
        $cidades = $this->cidade_model->lista_cidades($id_estado)->result_array();
        $json = "[";
        foreach ($cidades as $cidade) {
    	$json.= '{"value": "{$cidade['id']}", "label": "{$cidade['nome']}",';
        }
        $json = preg_replace("/,$/", "", $json);
        $json.= "[";
    }
    

    Pronto, agora você já tem um método em seu controller que filtra as cidades por estado e gera um documento json.

  2. HTML
    <tr>;
    	<td>Estado:</td>
    	<td><div id="div_cmb_estado" class="select-menus"><?php echo form_dropdown('cmb_estado', $cmb_estado); ?></div></td>;
    	<td>Cidade:</td>
    	<td>
    		<div id="container">
    			<div id="div_cmb_cidade" class="select-menus"><select id="cmb_cidade" name="cmb_cidade"></select></div>
    		</div>
    	</td>
    </tr>
    


    Crie o combo de estados normalmente, se você estiver usando form helper como eu, chame a função form_dropdown passando os dados que irão compor este combo. Observe que a variável $cmb_estado contém o array de dados que popula o combo de estados.
    Já o combo cidades (neste nosso exemplo), não terá nenhum registro inicialmente. Ele será preenchido dinamicamente como falei anteriormente. O pulo do gato é a div container. Os elementos que irão compor o combo devem ficar dentro dessa div.

  3. Ajax
    Finalmente, o ajax para criar o options. Basta chamar a url do seu método que cria o json e fazer o parser no resultado.
    $(document).ready(function() {
    
    	// Aplica o skin com jqTransform
    	$("form.jqtransform").jqTransform();
    
             // OnClick no item do combo de estados
    	$("#div_cmb_estado div.jqTransformSelectWrapper ul li a").click(function(){
    
    	// Recupera o valor do item selecionado
    	var index = $(this).attr('index');
    	var value = $('#div_cmb_estado div.jqTransformSelectWrapper option:eq(' + index + ')').attr('value');
    
    	// Chamada ao método criado no controller via ajax
    	$.ajax({
    	    type: "GET",
    	    async: true,
    	    url: "/exemplo/cidades/" + value,
    	    dataType:"json",
    	    error: function(XMLHttpRequest, textStatus, errorThrown) {
    		   alert(textStatus);
    	    },
    	    success: function(resposta){
    
    		// Limpa o "combo" de cidades
    		var html_combo = '<div id="div_cmb_cidade" class="select-menus"><select id="cmb_cidades" name="cmb_cidades"></div>';
    		$("#container").html(html_combo);
    
    		// Faz o parser no json e cria os elementos
    		for (i = 0; i < resposta.length; i++) {
    		   $("#cmb_cidades").append('<option selected value="' + resposta[i].value + '">' + resposta[i].label + '</option>');
    		}
    
    		// Chama novamente o jqTransform para o select. Funciona como um refresh no layout
    	         $("#cmb_cidades").jqTransSelect();
    		}
    	    });
    	});
    });
    

Espero ter ajudado, até o próximo post.

obs: Esse editor do wordpress é muito bom, ¬¬