ExtJS 4 Exemplo MVC: Exemplo de Comboboxes Aninhados com PHP e MySQL

07/05/2012 | By | 19 Comments

Em 2010 publiquei um tutorial sobre combobooxes aninhados, mas em ExtJS 3. Algumas coisas mudaram em ExtJS 4, então decidi fazer um update no tutorial. Mudei também a linguagem de backend de Java para PHP.

O que vai mudar entre o tutorial do ExtJS 3 e ExtJS 4 é apenas o frontend, ou seja, o código ExtJS. Se quiser pode usar o backend que fiz no post passado com o código do ExtJS 4 ou o código do ExtJS 3 com o backend feito em PHP deste post.

extjs4 linked combobox loiane ExtJS 4 Exemplo MVC: Exemplo de Comboboxes Aninhados com PHP e MySQL

Vamos lá!

Estrutura do Projeto:

extjs4 linked combobox ExtJS 4 Exemplo MVC: Exemplo de Comboboxes Aninhados com PHP e MySQL

Código ExtJS 4:

Model – Estado

Ext.define('ExtMVC.model.State',{
    extend: 'Ext.data.Model',
    fields: [
       {name: 'state_id'},
       {name: 'state_name'}
    ],
    idProperty: 'state_id'
});

Store – Estados

Ext.define('ExtMVC.store.States',{
    extend: 'Ext.data.Store',

    storeId: 'statesStore',

    model: 'ExtMVC.model.State',

    autoLoad:true,

    proxy: {
        type: 'ajax',

        url: 'php/listStates.php',

        reader: {
                type: 'json',
                root: 'data'
        }
    }
});

Model – Cidade

Ext.define('ExtMVC.model.City',{
    extend: 'Ext.data.Model',
    fields: [
       {name: 'city_id'},
       {name: 'state_id'},
       {name: 'city_name'}
    ],

    idProperty: 'city_id'
});

Store – Cidades

Ext.define('ExtMVC.store.Cities',{
    extend: 'Ext.data.Store',

    model: 'ExtMVC.model.City',

    proxy: {
        type: 'ajax',

        url: 'php/listCities.php',

        reader: {
                type: 'json',
                root: 'data'
        }
    }
});

View

Ext.define('ExtMVC.view.StateCityCombo' ,{
    extend: 'Ext.form.Panel',
    alias : 'widget.statecityform',

    frame: true,
    title:'Linked Comboboxes',
    style:'margin:16px',
    bodyStyle:'padding:10px',

    fieldDefaults: {
        labelAlign: 'right',
        labelWidth: 85,
        msgTarget: 'side'
     },

    items: [{
        xtype: 'combo',
        id: 'stateCombo',
        fieldLabel:'Select State',
        displayField:'state_name',
        valueField:'state_id',
        store: Ext.create('ExtMVC.store.States'),
        triggerAction:'all',
        queryMode:'local',
    },
    {
        xtype: 'combo',
        id: 'cityCombo',
        fieldLabel:'Select City',
        displayField:'city_name',
        valueField:'city_id',
        store: Ext.create('ExtMVC.store.Cities'),
        triggerAction:'all',
        queryMode:'local',
        disabled:true,
        lastQuery:''
    }]

 });

ViewPort

Ext.define('ExtMVC.view.Viewport', {
    extend: 'Ext.Viewport',
    layout: 'fit',

    requires: [
        'ExtMVC.view.StateCityCombo'
    ],

    initComponent: function() {
        var me = this;

        Ext.apply(me, {
            items: [
                {
                    xtype: 'statecityform'
                }
            ]
        });

        me.callParent(arguments);
    }
});

Controller

Ext.define('ExtMVC.controller.LinkedComboboxes', {
    extend: 'Ext.app.Controller',

    models: ['State', 'City'],

    stores: ['States', 'Cities'],

    views: ['StateCityCombo'],

    init: function() {

        this.control({
            'statecityform #stateCombo': {
                select: this.loadCityCombo
            }
        });
    },

     loadCityCombo: function(combo, records) {

        var comboCity = Ext.ComponentQuery.query('statecityform #cityCombo')[0];

        comboCity.setDisabled(true);
        comboCity.setValue('');
        comboCity.store.removeAll();

        comboCity.store.load({
            params: { stateId: combo.getValue() }
        });
        comboCity.setDisabled(false);
     }
});

App

Ext.Loader.setConfig({enabled: true});

Ext.application({
    name: 'ExtMVC',

    controllers: [
        'LinkedComboboxes'
    ],

    autoCreateViewport: true
});

listaEstados.php

<?php
    //chama o arquivo de conexão com o bd
    include("database.php");

    //consulta sql
    $query = mysql_query("SELECT * FROM State") or die(mysql_error());

    //faz um looping e cria um array com os campos da consulta
    $rows = array('data' => array());
    while($state = mysql_fetch_assoc($query)) {
        $rows['data'][] = $state;
    }

    //encoda para formato JSON
    echo json_encode($rows);
?>

listaCidades.php

<?php
    //chama o arquivo de conexão com o bd
    include("database.php");

    $stateId = $_REQUEST['stateId'];

    $queryString = "SELECT * FROM City WHERE state_id = " . $stateId;

    //consulta sql
    $query = mysql_query($queryString) or die(mysql_error());

    //faz um looping e cria um array com os campos da consulta
    $rows = array('data' => array());
    while($city = mysql_fetch_assoc($query)) {
        $rows['data'][] = $city;
    }

    //encoda para formato JSON
    echo json_encode($rows);
?>

Download do Código Fonte:

Você pode fazer o download do código fonte completo no meu repositório do github: https://github.com/loiane/extjs4-linked-combobox

Demo:

Exemplo funcionando: http://loiane.com/extjs/extjs4-linked-combobox/

Até a próxima!

Filed in: Ext JS 4 | Tags: ,

Comments (19)

Links to this Post

  1. Exemplos Sencha ExtJS 4 em MVC | Loiane Groner | 29/05/2012
  1. Paulo Porto

    A página do link “Exemplo funcionando” não funciona. E já lhe adianto que é algo na conexão do PHP com o banco de dados ao obter os estados. :)

    Mensagem de erro obtida via GDT:
    Warning: mysql_connect() [function.mysql-connect]: Lost connection to MySQL server at ‘reading initial communication packet’, system error: 111 in /home/loiane/public_html/extjs/extjs4-linked-combobox/php/database.php on line 16
    Lost connection to MySQL server at ‘reading initial communication packet’, system error: 111

    Até mais!

  2. James

    Muito bom o exemplo,

    Sei que o exemplo é simples, porém gostaria de tirar uma dúvida referente ao uso do ID no componente, pois trabalho com o Ext3 e não utilizo o id devido na abertura de várias janelas pode acontecer de ter outro componente com o mesmo id em uma janela já aberta, ocasionando um erro durante a renderização.

    Esse tipo de erro ocorre no Ext4?

    Obrigado.

    • James,
      Não é boa prática dar id aos componentes do extjs, exceto os casos em que isso é realmente necessário, como no caso desse exemplo.
      No ExtJS 4 o problema vai continuar acontecendo, pois faz parte do ciclo de vida do componente do ExtJS, mas existem maneiras de se contornar isso.
      Por isso que no ExtJS a gente usa o ComponentQuery e não Ext.getCmp.

  3. Marcelo

    Parabéns Loiane, muito bom o post… verifique depois o charset pois as cidades e estados com acentuação não estão aparecendo, o charset deve ser UTF-8.

  4. @James, @Loiane
    No Ext 4 você pode usar o atributo itemId ao invés do id, assim é possível ter múltiplos componentes com o mesmo itemId (desde que estejam em containers diferentes). Você pode buscar elementos passando o itemId como parâmetro no método Ext.ComponentQuery.query.

  5. Sebastian

    Opa, Loiane, supondo que esse combo faça parte de dois forms e eu carregue esse dois forms ao mesmo tempo no mesmo panel, pode acontecer de quando eu alterar o combo do form1 alterar também o valor do form2? Eu estou com esse problema quando, tento usar esse combo que vc criou em mais de um lugar o valor de um interfere no outro.

  6. Jair Verçosa

    Oi Loiane, muito bom o exemplo.

    Apenas uma dúvida, eu sou obrigado a colocar todos os controllers e models na Application? Eu sei que nesse momento ele carrega todas as classes.

    Em uma aplicação grande isso não ficaria pesado.

    Abraço, acompanho o seu trabalho e é simplesmente excelente!!!

  7. Julius

    Tenho aproveitado o maximo das suas aulas. Todas muito boas.
    Obrigado Loiane

  8. Maurício Vinicius

    Olá, Loiane.
    Fiz exatamente como no seu exemplo, porém na segunda vez que modifico o estado, quando seleciono o campo cidades o Ext fica no carregando e não sai, apenas de mostrar de fundo as cidades recuperadas para aquele estrado.
    Ou seja, as cidades do novo estado já estão carregadas porém não consigo selecionar a cidade devido a estar o “Loading” na frente do campo.

  9. Olá, baixei os códigos e ainda tem o problema do encodeamento json, como contornar isso ?

  10. Gustavo Bauer Machado

    Loiane como faço para poder carregar os combobox apos eu salvar eles no banco, ai quando vou editar não sei como setar para o valor que ele recebe do banco

  11. Olá Loiane, primeiramente meus parabéns pelo tutorial você contribui bastante para o mundo dos desenvolvedores e sua didática é sem palavras.
    Sobre os combos você está mencionando o atributo “mode” que era utilizado no componente na versão ExtJS3, neste caso teria que ser o atributo “queryMode” para a versão ExtJS4.

    Att.

    Legolas

  12. L Ramos

    Olá, Loiane. Parabéns pela iniciativa! Sugiro um acréscimo no código do database.php, de forma que seja evitado/corrigido o problema da acentuação. Nos testes que eu fiz, o “json” estava convertendo dados acentuados para “null”. Abs.

    //executa a conexão com o banco, caso contrário mostra o erro ocorrido
    $conexao = mysql_connect($servidor,$user,$senha) or die (mysql_error());
    //incluir esta linha no código
    mysql_set_charset(‘utf8′, $conexao);

Leave a Reply

Trackback URL | RSS Feed for This Entry

VideoPokiesOnline.com is the leading Pokies - Online Casino Guide in Australia. Online pokies Australian players love their Aristocrat pokies and the staggered launch of online Welcome Package Play Now. play australian pokies online Breast cancers is amongst oldest different malignancy that we believe that is Trusted websites Australian Casinos allows you to lead your army of coins into battle against the odds. Free Online Pokies at Top Rated Australian Online Casinos.
Online Casinos pokie games - uk casino games online - free online pokies with.
Slots and enjoy: ?one of a kind VIP program ? $500 Welcome Package ? Online Pokies Australia online casinos and land parlors. Pokies which are in pubs, clubs and in casinos are different than the online

Online Slots Wild Jack.