Ext是一个很成熟的js框架,他的store存储结构将发送请求和接受请求封装起来,如此,我们只需要定义数据来源和数据结构,便可以通过store.load()获取数据:
// proxy:new Ext.data.ScriptTagProxy({ url:'http://localhost:17319/KBS/Grid/EditString.aspx'}),
proxy: new Ext.data.HttpProxy({ url: ' salesTargetList.action ' }),
reader: new Ext.data.JsonReader(
{
totalProperty : ' totalCount ' ,
root : ' root ' ,
id : ' storeID '
},
[
{name: ' id ' , type: ' int ' },
{name: ' orderMonth ' , type: ' int ' }, // 格式:200709
{name: ' storeID ' , type: ' int ' },
{name: ' storeName ' },
{name: ' vp ' , type: ' float ' },
{name: ' sales ' , type: ' float ' },
{name: ' newSR ' , type: ' int ' },
{name: ' newPC ' , type: ' int ' }
])
});
proxy指定了数据来源,将请求发送至salesTargetList.action, 而reader定义了它所读取数据的格式。这里我们所碰到的第一个问题出现了——那就是如何将一张查询出来的二维表格序列化成json对象。在项目框架 中,我们得到的结果通常是一个或一组(List)doMain对象,那么如何将它们转为可以被读取的数据格式呢?
我用的是一个插件jsonrpc,它不但解决了上面的问题,而且还提供将java类注册到js里的功能,如此,你可以在js中调用框架的业务逻辑。如此,可以让Ext更好地融合到你的项目中。好吧!这篇文章并不是介绍这个插件的。
salesTargetList.action在struts.xml中配置:
class = " com.herbalife.report.web.action.BizSalesTargetAction " >
< result type = " json " >
< param name = " root " > bizSalestarget </ param >
</ result >
< interceptor - ref name = " params " />
< interceptor - ref name = " servlet-config " />
</ action >
后面我会在一篇博客中,专门介绍一下这个插件的功能和配置。
那么,经过序列化,store便可以正确的读取到数据,格式如下:
" totalCount " : 2 ,
" root " :
[
{ " id " : 4 , " orderMonth " : 200712 , " sales " : 480.0 , " storeID " : 1 , " storeName " : " Altria Group Inc " , " vp " : 300.39 },
{ " id " : 5 , " orderMonth " : 200712 , " sales " : 112.0 , " storeID " : 2 , " storeName " : " AT&T Inc. " , " vp " : 1111.0 }
]
}
如果没有这个插件,你可以将这种格式的字符串,写入response中。前面是存储结构的定义,下面是列模型的定义:
var cm = new Ext.grid.ColumnModel([
{header: " StoreID " , dataIndex: ' storeID ' , width: 50 ,align: ' center ' ,
editor: new Ed( new fm.TextField({
allowBlank: false ,
disabled : true
}))
},{header: " StoreName " , dataIndex: ' storeName ' , width: 185 ,align: ' left ' ,
editor: new Ed( new fm.TextField({
allowBlank: false ,
disabled : true
}))
},{header: " OrderMonth " , dataIndex: ' orderMonth ' , width: 80 ,align: ' center ' , // renderer:formatDate,
editor: new Ed( new fm.TextField({
allowBlank: false ,
disabled : true // 设置无法编辑
}))
},{header: " VP " , dataIndex: ' vp ' , width: 70 ,renderer: ' usMoney ' ,
editor: new Ed( new fm.TextField({
allowBlank: false
}))
},{header: " Sales " , dataIndex: ' sales ' , width: 70 ,renderer: ' usMoney ' ,
editor: new Ed( new fm.TextField({
allowBlank: false
}))
}]);
// by default columns are sortable
cm.defaultSortable = true ;
接下来就是对editGrid的定义了:
ds: store,
cm: cm,
enableColLock: false ,
renderTo: document.body
});
ds 数据源,cm列模型。前面'grid-example'是页面中grid的载体——一个div的id,我们将grid绘制在这个div上。你需要将上面的 内容放在Ext.onReady(function(){},如此保证在打开页面时,就开始执行他们。完整代码附在文章最后。
如此一个editgird便完成了。你现在要做的是,确保访问salesTargetList.action能拿到数据。如果在.net下,就更方便了, 在page_load方法中,直接将满足格式的字符串,Response.write一下,然后调用end()方法,你便可以通过url访问了,如: http://localhost:4321/KBS/Grid/JsonString.aspx。当然,如果你电脑上有vs环境,你同样可以在java 中,使用上面那个链接(保证vs的虚拟网站处于运行状态),在store定义数据源,你需要使用ScriptTagProxy,表示跨域访问:proxy:new Ext.data.ScriptTagProxy({ url:'http://localhost:17319/KBS/Grid/EditString.aspx'})
附代码:
* Ext JS Library 1.1
* Copyright(c) 2006-2007, Ext JS, LLC.
* TonkNet@lislie
*
*/
function formatPercent(value){
return value + ' % ' ;
};
function formatDate(value){
// return value.substring(0,4) + '年' + value.substring(4,value.length) + '月';
var tmp = '' ;
for ( var i = 0 ;i < value.length;i ++ )
{
tmp += value.charAt(i);
if (i == 3 )
tmp += ' / ' ;
}
return tmp;
};
Ext.onReady( function (){
Ext.QuickTips.init();
// shorthand alias
var fm = Ext.form, Ed = Ext.grid.GridEditor;
// the column model has information about grid columns
// dataIndex maps the column to the specific data field in
// the data store (created below)
var cm = new Ext.grid.ColumnModel([
{header: " StoreID " , dataIndex: ' storeID ' , width: 50 ,align: ' center ' ,
editor: new Ed( new fm.TextField({
allowBlank: false ,
disabled : true
}))
},{header: " StoreName " , dataIndex: ' storeName ' , width: 185 ,align: ' left ' ,
editor: new Ed( new fm.TextField({
allowBlank: false ,
disabled : true
}))
},{header: " OrderMonth " , dataIndex: ' orderMonth ' , width: 80 ,align: ' center ' , // renderer:formatDate,
editor: new Ed( new fm.TextField({
allowBlank: false ,
disabled : true
}))
},{header: " VP " , dataIndex: ' vp ' , width: 70 ,renderer: ' usMoney ' ,
editor: new Ed( new fm.TextField({
allowBlank: false
}))
},{header: " Sales " , dataIndex: ' sales ' , width: 70 ,renderer: ' usMoney ' ,
editor: new Ed( new fm.TextField({
allowBlank: false
}))
},{header: " NewSR " , dataIndex: ' newSR ' , width: 60 ,align: ' right ' ,
editor: new Ed( new fm.TextField({
allowBlank: false
}))
},{header: " NewPC " , dataIndex: ' newPC ' , width: 60 ,align: ' right ' ,
editor: new Ed( new fm.TextField({
allowBlank: false
}))
}]);
// by default columns are sortable
cm.defaultSortable = true ;
// create the Data Store fro gird
var store = new Ext.data.Store({
// proxy:new Ext.data.ScriptTagProxy({ url:'http://localhost:17319/KBS/Grid/EditString.aspx'}),
proxy: new Ext.data.HttpProxy({ url: ' salesTargetList.action ' }),
reader: new Ext.data.JsonReader(
{
totalProperty : ' totalCount ' ,
root : ' root ' ,
id : ' storeID '
},
[
{name: ' id ' , type: ' int ' },
{name: ' orderMonth ' , type: ' int ' }, // 格式:200709
{name: ' storeID ' , type: ' int ' },
{name: ' storeName ' },
{name: ' vp ' , type: ' float ' },
{name: ' sales ' , type: ' float ' },
{name: ' newSR ' , type: ' int ' },
{name: ' newPC ' , type: ' int ' }
])
});
store.load();
// create the editor grid
var grid = new Ext.grid.EditorGrid( ' grid-example ' , {
ds: store,
cm: cm,
enableColLock: false ,
renderTo: document.body
});
var layout = Ext.BorderLayout.create({
center: {
margins:{left: 3 ,top: 3 ,right: 3 ,bottom: 3 },
panels: [ new Ext.GridPanel(grid)]
}
}, ' grid-panel ' );
// render it
grid.render();
var gridHead = grid.getView().getHeaderPanel( true );
var monthText = new Ext.form.TextField({name : ' monthT ' ,id : ' monthT ' }); // 月份 TextField
var storeList = new Ext.form.ComboBox({ // 店铺 storeName
id : ' storeL ' ,
name: ' storeL ' ,
store: store,
valueField: ' storeID ' ,
typeAhead: true ,
displayField: ' storeName ' ,
triggerAction: ' all ' ,
emptyText: ' Select a store... ' ,
selectOnFocus: true ,
width: 135
});
var tb = new Ext.Toolbar(gridHead,
[{
text : ' 月份 ' ,
handler : function () {
alert( ' 请按如下格式输入日期:200707 ' );
}
},monthText,{
text : ' 店铺 '
},storeList
,{
text : ' 查询 ' ,
handler : doSearch
},{
text : ' 保存 ' ,
handler : Save
}
]);
/* ---------------- #region Filter ------------------- */
/* Ext.get('storeL').on('change', SFilter, this, true);
function SFilter(combo,a,b) {
alert('111');
var storeName = storeList.getValue();
store.filter("storeName", storeName, false);
} */
/* ---------------- #endregion Filter ------------------- */
/* ---------------- #endregion Check ------------------- */
Ext.get( ' monthT ' ).on( ' blur ' , Check);
function Check() {
var value = document.getElementById( ' monthT ' ).value;
var i = IsNumber(value);
if (i > - 1 ) {
Ext.MessageBox.show({
title: ' 提示 ' ,
msg: ' 月份包含非法字符:" ' + value.charAt(i) + ' ",请输入数字 ' ,
buttons: Ext.Msg.OK
});
return ;
}
}
function IsNumber(str) {
var inStr = " 1234567890 " ;
for ( var i = 0 ;i < str.length;i ++ ) {
if (inStr.indexOf(str.charAt(i)) == - 1 )
return i;
}
return - 1 ;
}
/* ---------------- #endregion Check ------------------- */
/* ---------------- #region Search ------------------- */
function doSearch() {
var mt = monthText.getValue();
var sn = storeList.getRawValue();
var msg = ' You condition is : ' ;
if (mt != null )
msg += ' month = " ' + mt + ' " , ' ;
if (sn != null )
msg += ' storeName = " ' + sn + ' " ' ;
Ext.example.msg( ' Message ' ,msg, this );
store.load({params : {month : mt,storeName : sn}});
}
/* ---------------- #region Search ------------------- */
/* ---------------- #region Update ------------------- */
function Save(){
Ext.MessageBox.confirm( ' 提示 ' , ' 确实要保存修改记录? ' ,doSave);
}
function doSave() {
jsonurl = " /JSON-RPC " ;
jsonrpc = new JSONRpcClient(jsonurl);
var modi = grid.dataSource.getModifiedRecords(); // 获取更改数据行记录
if (modi.length <= 0 ) {
Ext.MessageBox.show({
title: ' 提示 ' ,
msg: ' 您没有修改任何数据 ' ,
buttons: Ext.Msg.OK
});
return ;
}
var result = [];
for ( var i = 0 ;i < modi.length;i ++ ) {
var value = modi[i].data.newSR;
var i = IsNumber( " 0123456789. " ,value);
if (i > - 1 ) {
Ext.MessageBox.show({
title: ' 提示 ' ,
msg: ' NewSR中包含非法字符: ' + value.charAt(i),
buttons: Ext.Msg.OK
});
return ;
}
value = modi[i].data.newPC;
i = IsNumber( " 0123456789. " ,value);
if (i > - 1 ) {
Ext.MessageBox.show({
title: ' 提示 ' ,
msg: ' NewPC中包含非法字符: ' + value.charAt(i),
buttons: Ext.Msg.OK
});
return ;
}
result.push(modi[i].data);
}
jsonrpc.ajaxfacade.testModi(result); // 调用java类
Ext.MessageBox.show({
title: ' 提示 ' ,
msg: ' 修改成功 ' ,
buttons: Ext.Msg.OK
});
}
/* ---------------- #endregion Update ------------------- */
});
效果图: