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

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.

Vamos lá!

Estrutura do Projeto:

Código ExtJS 4:

Model - Estado

[code lang="js" firstline="1" toolbar="true" collapse="false" wraplines="false"]
Ext.define('ExtMVC.model.State',{
extend: 'Ext.data.Model',
fields: [
{name: 'state_id'},
{name: 'state_name'}
],
idProperty: 'state_id'
});
[/code]

Store - Estados

[code lang="js" firstline="1" toolbar="true" collapse="false" wraplines="false"]
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'
}
}
});
[/code]

Model - Cidade

[code lang="js" firstline="1" toolbar="true" collapse="false" wraplines="false"]
Ext.define('ExtMVC.model.City',{
extend: 'Ext.data.Model',
fields: [
{name: 'city_id'},
{name: 'state_id'},
{name: 'city_name'}
],

idProperty: 'city_id'
});
[/code]

Store - Cidades

[code lang="js" firstline="1" toolbar="true" collapse="false" wraplines="false"]
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'
}
}
});
[/code]

View

[code lang="js" firstline="1" toolbar="true" collapse="false" wraplines="false"]
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:''
}]

});
[/code]

ViewPort

[code lang="js" firstline="1" toolbar="true" collapse="false" wraplines="false"]
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);
}
});
[/code]

Controller

[code lang="js" firstline="1" toolbar="true" collapse="false" wraplines="false"]
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);
}
});
[/code]

App

[code lang="js" firstline="1" toolbar="true" collapse="false" wraplines="false"]
Ext.Loader.setConfig({enabled: true});

Ext.application({
name: 'ExtMVC',

controllers: [
'LinkedComboboxes'
],

autoCreateViewport: true
});
[/code]

listaEstados.php

[code lang="php" firstline="1" toolbar="true" collapse="false" wraplines="false"]
<?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);
?>
[/code]

listaCidades.php

[code lang="php" firstline="1" toolbar="true" collapse="false" wraplines="false"]
<?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);
?>
[/code]

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!