在 CNIS (Canadian Network for International Surgery, 非營利組織) 當志工時推薦他們一個我比較熟悉的 Extjs framework, 但這個框架其實不好上手。同事問我怎麼從 db 撈一組國家列表, 前端用 Extjs 的 combobox 元件來互動 ? 於是我就動手了, 發現還真的挺複雜的, 所以趕快來記錄一下。
需求重點提示
- 這個下拉式選單 (combobox) 的內容是透過 ajax 初始化他的可用選項
- 獨立創建一個 controller.js 專門接收這個 request, 並與 MySQL 完成交互, 回傳 JSON 格式資料
- 需存取 stored-procedure
- combobox 需有一個 template 方便調整符合站台的樣式 (他們不要 Extjs 內建的樣式)
程式筆記
MySQL Store Procedure
CREATE DEFINER=`my_db`@`%` PROCEDURE `my_sp`(
)
BEGIN
SELECT
`country_code` AS `key`,
`country_name` AS `name`
FROM `myDB`.`myTable`;
END$$
controller.php
Yii framework 有個驗證機制, 需要 allow 給什麼 user 可存取什麼 controller, 要記得加上這一段代碼 (如下 accessRules 函式), 否則會得到 server side 的訊息:failed to load resource the server responded with a status of 403 (access forbidden)
controller// authorize the access permission
public function accessRules() {
return array(
...,
array('allow',
'actions'=>array('create','update','createExtJS','retrieveCode'),
'users'=>array('@'),
),...
);
}
public function actionRetrieveCode($type) {
Yii::log("====== Create Ajax calling ========", CLogger::LEVEL_INFO);
$command = Yii::app()->db->createCommand('CALL my_SP ()');
$rawData = $command->queryAll();
$json = array(
'success' => count($rawData) > 0,
'totalCount' => count($rawData),
'data' => $rawData
);
echo json_encode($json);
}
front-end.js
這邊就是 Extjs 主要的實作
Ext.define('Combo.model.Pair', { // common model for each combobox featured in key-value pair
extend: 'Ext.data.Model',
fields: ['key', 'name']
});
myStore = Ext.create('Ext.data.Store', {
id:'codeCountry',
model: 'Combo.model.Pair',
autoLoad:true,
proxy: {
type: 'ajax',
url : '/myApp/index.php?r=myPage/myController&type=Country',
reader: {
type: 'json',
root: 'data',
successProperty: 'success'
}
},
listeners: {
load: function () {
// set the default value after the store loads
Ext.getCmp('CbRelatedCountries').setValue(Ext.getCmp('CbRelatedCountries').getStore().getAt(0).get(Ext.getCmp('CbRelatedCountries').valueField));
}
}
});
this.codeRegion = Ext.create('Ext.data.Store', {
id:'codeRegion',
model: 'Combo.model.Pair',
autoLoad:true,
proxy: {
... }});
tpl_for_combobox.js
還記得需求有提到需要有自定義的 combobox 樣式嗎 ? 所以需增加這個 template{xtype: 'combobox', id: 'CbRelatedCountries', name: 'CbRelatedCountries', fieldLabel: 'Related Countries', allowBlank: false, labelWidth: 150, width: 500,
forceSelection: true,
multiSelect: true,
triggerAction: 'all',
lazyRender: true,
listConfig:{
itemTpl:new Ext.XTemplate('<tpl for="."><div class="x-combo-list-item">{key} : {name}</div></tpl>')
},
emptyText: '-- Select Options --',
queryMode: 'local',
displayField: 'key',
valueField: 'key',
submitValue: false,
store: myStore
}
有興趣的同學也可以留言交流。
參考資料
- http://docs.sencha.com/extjs/3.4.0/
Comments
Post a Comment