Ext是一个很成熟的js框架,他的store存储结构将发送请求和接受请求封装起来,如此,我们只需要定义数据来源和数据结构,便可以通过store.load()获取数据:
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
'
}
])
});
proxy指定了数据来源,将请求发送至salesTargetList.action, 而reader定义了它所读取数据的格式。这里我们所碰到的第一个问题出现了——那就是如何将一张查询出来的二维表格序列化成json对象。在项目框架 中,我们得到的结果通常是一个或一组(List)doMain对象,那么如何将它们转为可以被读取的数据格式呢?
我用的是一个插件jsonrpc,它不但解决了上面的问题,而且还提供将java类注册到js里的功能,如此,你可以在js中调用框架的业务逻辑。如此,可以让Ext更好地融合到你的项目中。好吧!这篇文章并不是介绍这个插件的。
salesTargetList.action在struts.xml中配置:
<
action name
=
"
salesTargetList
"
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 fm
=
Ext.form, Ed
=
Ext.grid.GridEditor;
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
;
// 每一行可以添加renderer属性,在editGrid渲染时,回调函数进行一些处理,例如格式化日期,或添加样式、事件等等......
接下来就是对editGrid的定义了:
var
grid
=
new
Ext.grid.EditorGrid(
'
grid-example
'
, {
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 -------------------
*/
});
效果图: