分享

ExtJS实战(6)

 pint 2012-06-19
ExtJS实战(6)-extjs+json

好了,铺垫工作做的差不多了,主角闪亮登场。让ExtJS炫起来吧~~!

ExtJS本质上也是一个AJAX的框架,但是它和DWR有很大不同,首先,DWR是JAVA世界的产物,而ExtJS是后台无关的。也就是说,ExtJS的后台可以是.NET,PHP或者JAVA都可以。其实我们在网上看到的大部分例子都是PHP或者.NET,后台的。这说明ExtJS在所有后台都很受青睐。其次,DWR只关注客户端与服务器端的交互,没有自己的界面组件,而ExtJS最让人惊叹的就是其丰富而强大的界面组件,除此以外,它自身也能轻松地异步访问后台组件。现如今,RIA(富客户端应用)已经成了不争的趋势。那我们现在还不赶紧学习,还更待何时?

来张页面刺激下学习欲望先!

我们知道,在WEB开发中有一些共同的开发重心,譬如登陆注册,CRUD(增,删,改,查),数据的分页,排序和过滤,数据的统计报表,数据的导入导出,Cookies和Sessions的管理等。我们在网上看到很多ExtJS的零零星星的应用,有人做了CRUD,有人做了登陆注册,有了做了复杂查询,还有人扩展了分页,做了服务器端的排序,数据的导出等等,但就是没有人提供一个强大而翔实的案例,把这些ExtJS的知识点统一到项目中,或者有的人已经做除了一些真实的项目,可是又不愿意拿出来分享。哎,有感于此,老许来了。

既然是实战,当然需要大家有一定的根基,我给大家提供的开发工具也好,开发文档也罢,都是来帮助大家高效地学习和开发。另外,大家要把网上零零星星的例子多跑几个,然后再进入我们项目的学习。

好啦,大家还是要快速搭建好ExtJS应用的环境。测试通过。在我们的整个项目应用中,就两张核心的JS文件,它完成了项目所需要的所有核心功能,具有很高的参考价值。当然代码量也是比较大的:

1. 首先是init-main.js,这里定义了整个应用的主体布局视图Viewport。它和我们HTML中的frameset有点类似。在我们的主显示区里还放了一个TabPanel,这就是我们桌面应用中常见的选项面板。要理解下面的JS呢,你必须先掌握JSON这种数据格式,这个格式我在前面的ExtJS应用中已经详细讲过,如果还不太清楚,到http://www./json-zh.html 去看看,JSON在整个ExtJS体系里占有重要地位,熟悉JSON格式的人会对名/值对,{},[]很敏感。大家看到,在Viewport类和TabPanel类里都传入一个JSON对象来初始化整个组件。其次,你还要有容器和组件的概念,每个容器组件(容器同时也是组件,这是相对的,它放东西的时候是容器,被放置其中的时候就是组件!)都有一个items参数指定一个JSON数组来表明自己容纳的组件。我们要完成的功能是上面放公司的LOGO信息,左边是导航菜单栏,右边是主显示区。代码如下:

// create main tabpanel

var contentPanel = new Ext.TabPanel({

id : "tabPanel",

region : 'center',

enableTabScroll : true,

resizeTabs : true, // turn on tab resizing

deferredRender : false,

minTabWidth : 115,

// tabWidth:135,

activeTab : 0,

iconCls : 'tabs',

items : [{

contentEl : 'center',

title : '主页',

autoScroll : true

}],

defaults : {

autoScroll : true

},

plugins : new Ext.ux.TabCloseMenu()

});

//ExtJs应用的入口

Ext.onReady(function() {

Ext.state.Manager.setProvider(new Ext.state.CookieProvider());

// init main page framework

var viewport = new Ext.Viewport({

layout : 'border',

items : [{

region : 'north',

html : '<img src="resources/images/dwr_logo.gif" width=210 height=100><img src="resources/images/struts.png" ><img src="resources/images/hibernate.gif" width=200 height=90 ><img src="resources/images/spring_logo.png" width=200 height=70><img src="resources/images/extjs_logo.gif" height=60>',

split : true,

height : 130,

minSize : 100,

maxSize : 200,

collapsible : true,

title : '房屋出租系统',

margin : '0 0 0 0'

// border: false,

// layout:"absolute"

}, {

region : 'west',

id : 'west-panel',

title : '菜单栏',

split : true,

width : 200,

minSize : 175,

maxSize : 400,

collapsible : true,

margins : '0 0 5 5',

cmargins : '0 5 5 5',

layout : 'accordion',

layoutConfig : {

animate : true

},

items : [{

title : '房屋管理',

html : Ext.getDom('userMenus').innerHTML,

autoScroll : true,

border : false,

iconCls : 'user'

}, {

title : '机构管理',

html : Ext.getDom('unitMenus').innerHTML,

border : false,

autoScroll : true,

iconCls : 'unit'

}, {

title : '系统设置',

html : Ext.getDom('settingMenus').innerHTML,

border : false,

autoScroll : true,

iconCls : 'settings'

}, {

title : '电子日历',

// html : Ext.getDom('settingMenus').innerHTML,

border : false,

autoScroll : true,

iconCls : 'settings',

items : [new Ext.form.DateField()]

}, {

title : '企业短信',

html : Ext.getDom('msg').innerHTML,

border : false,

autoScroll : true,

iconCls : 'settings'

}, {

title : '公文审批',

// html : Ext.getDom('msg').innerHTML,

border : false,

autoScroll : true,

iconCls : 'settings'

}, {

title : '电子会议',

html : Ext.getDom('eMeeting').innerHTML,

border : false,

autoScroll : true,

iconCls : 'settings'

}, {

title : '电子邮件',

// html : Ext.getDom('msg').innerHTML,

border : false,

autoScroll : true,

iconCls : 'settings'

}, {

title : '电子文档',

// html : Ext.getDom('msg').innerHTML,

border : false,

autoScroll : true,

iconCls : 'settings'

}, {

title : '个性化设置',

// html : Ext.getDom('msg').innerHTML,

border : false,

autoScroll : true,

iconCls : 'settings'

}]

}, contentPanel]

});

// init main page tables

var panel = new Ext.Panel({

id : 'main-panel',

baseCls : 'x-plain',

renderTo : Ext.get("center"),

layout : 'table',

layoutConfig : {

columns : 2

},

defaults : {

frame : true,

width : 395

},

items : [{

title : '公告信息',

colspan : 2,

collapsible : true,

width : 800,

height : 430,

contentEl : 'afficheDiv'

}]

});

// clear temp elements.

Ext.getDom("menus").innerHTML = "";

});

// 定义菜单导航函数

function onClickMenuItem(node) {

var n = contentPanel.getComponent(node.id);

if (!n) { // //判断是否已经打开该面板

n = contentPanel.add({

'id' : node.id,

'title' : node.innerHTML,

iconCls : 'tabs',

closable : true,

autoLoad : {

url : 'tabFrame.jsp?url=' + node.href,

callback : this.initSearch,

scope : this,

scripts : true

} // 通过autoLoad属性载入目标页,如果要用到脚本,必须加上scripts属性

});

}

contentPanel.setActiveTab(n);

}

2. 然后是init-house.js,这是最重要也是最复杂的一个JS文件了。这个JS里面涉及到Ext.Window, Ext.FormPanel,Ext.grid.CheckboxSelectionModel,Ext.data.Record,Ext.grid.ColumnModel,Ext.data.Store,Ext.PagingToolbar,Ext.grid.GridPanel,Ext.MessageBox,Ext.menu.Menu等众多重要的ExtJS控件,要知道它们之间的关系就要先了解我们要做的事!这个应用中,我们要完成的界面功能是在页面上显示一张表格(这张表格的列由ColumnModel决定,数据行由Store决定!),表格上方显示一排工具按钮,分别用来做添加,修改,删除,复制,导出等功能,下方显示分页栏来展现分页数据,表格里面还设置了行级的右键菜单,可以完成和上排工具按钮一样的功能。在表格之上,我们还放置了一个查询表单,来完成我们强大的信息检索功能。最后我们添加和修改数据的时候,都会弹出一个窗口,里面放置着添加或修改数据的表单。还有,当用户执行了不正确的操作时,要弹出相应的提示对话框。OK,怀着攻克难关的激情,我们来看看这1000行代码吧!

var ds;// 数据源

var grid;// 数据显示表格

var searchForm;// 查询表单

var form;//添加/修改的表单

var win;// 添加或修改窗口

var limit = 5;//每页显示的记录数

var ptb;// 分页控件

var TopicRecord;//记录对象

function getInsertForm() {

form = new Ext.FormPanel({

labelWidth : 100,

monitorValid : true,// 把有formBind:true的按钮和验证绑定

baseCls : 'x-plain',

defaults : {

width : 200

},

defaultType : 'textfield',// 默认字段类型

// 定义表单元素

items : [{

fieldLabel : '标题',

name : 'house.title',

allowBlank : false

}, {

fieldLabel : '租金',

name : 'house.hireprice'

}, {

fieldLabel : '联系人',

name : 'house.linkman'

}, {

fieldLabel : '联系电话',

name : 'house.linktel'

}, {

fieldLabel : '几室',

xtype : "combo",

hiddenName : "house.room",// 大家要注意的是hiddenName和name属性,name只是下拉列表的名称,作用是可通过,而hiddenName才是提交到后台的input的name。如果没有设置hiddenName,在后台是接收不到真正的值的。

store : new Ext.data.SimpleStore({

fields : ['a', 'b'],

data : [['1', '一'], ['2', '二'], ['3', '三']]

}),

valueField : 'a',

displayField : 'b',

mode : 'local',

triggerAction : 'all',

forceSelection : true,

selectOnFocus : true,

editable : false,

readOnly : true,

emptyText : "无限制!"

}, {

fieldLabel : '几厅',

xtype : "combo",

hiddenName : "house.ting",// 大家要注意的是hiddenName和name属性,name只是下拉列表的名称,作用是可通过,而hiddenName才是提交到后台的input的name。如果没有设置hiddenName,在后台是接收不到真正的值的。

store : new Ext.data.SimpleStore({

fields : ['a', 'b'],

data : [['1', '一'], ['2', '二'], ['3', '三']]

}),

valueField : 'a',

displayField : 'b',

mode : 'local',

triggerAction : 'all',

forceSelection : true,

selectOnFocus : true,

editable : false,

readOnly : true,

emptyText : "无限制!"

}, {

fieldLabel : "区域",

xtype : 'combo',

store : new Ext.data.SimpleStore({

fields : ['id', 'name'],

data : Ext.grid.areaComboBoxItems

}),

valueField : "id",

displayField : "name",

mode : 'local',

forceSelection : true,// 必须选择一项

emptyText : '请选择区域...',// 默认值

name : "area",

hiddenName : "house.areaId",// hiddenName才是提交到后台的input的name

editable : false,// 不允许输入

triggerAction : 'all',// 因为这个下拉是只能选择的,所以一定要设置属性triggerAction为all,不然当你选择了某个选项后,你的下拉将只会出现匹配选项值文本的选择项,其它选择项是不会再显示了,这样你就不能更改其它选项了。

id : 'parent_id1',

name : 'parent1',

listeners : {

select : function(combo, record, index) {

houseService.getAllStreets(combo.value, function(

data) {

if (data != null) {

var list2 = [];

for (var i = 0; i < data.length; i++) {

list2[i] = [data[i].sid, data[i].sname];

}

Ext.getCmp('child_id1').clearValue();

Ext.getCmp('child_id1').store

.loadData(list2);

}

});

}

}

}, {

fieldLabel : "街道",

xtype : 'combo',

store : new Ext.data.SimpleStore({

fields : ['id', 'name'],

data : []

}),

valueField : "id",

displayField : "name",

// 数据是在本地

mode : 'local',

forceSelection : true,// 必须选择一项

emptyText : '请选择街道...',// 默认值

editable : false,// 不允许输入

triggerAction : 'all',// 因为这个下拉是只能选择的,所以一定要设置属性triggerAction为all,不然当你选择了某个选项后,你的下拉将只会出现匹配选项值文本的选择项,其它选择项是不会再显示了,这样你就不能更改其它选项了。

allowBlank : false,// 该选项值不能为空

id : 'child_id1',

name : "child1",

hiddenName : "house.streetId"

}, {

fieldLabel : '房屋设施',

xtype : 'textarea',

name : 'house.housething'

}],

buttons : [{

text : '保存',

formBind : true,

type : 'submit',

// 定义表单提交事件

handler : function() {

if (form.form.isValid()) {// 验证合法后使用加载进度条

// 提交到服务器操作

form.form.doAction('submit', {

url : '../houseHandler.do?action=addHouse',// 文件路径

method : 'post',// 提交方法post或get

params : '',

// 提交成功的回调函数

failure : function(retForm, retAction) {

if (retAction.result

&& retAction.result == '1') {

Ext.MessageBox.alert('提示', '保存数据成功!');

win.hide();

ptb.cursor=ptb.store.getTotalCount()+1-ptb.pageSize;

ds.load({

params : {

start : ptb.cursor,

limit : ptb.pageSize

}

});

} else if (retAction.result

&& retAction.result == 'error') {

Ext.MessageBox.alert('提示', '保存数据失败!');

} else {

Ext.Msg.alert('错误', '服务器出现错误请稍后再试!');

}

},

waitMsg : '保存数据...'

});

}

}

}, {

text : '取消',

handler : function() {

form.form.reset();

}// 重置表单

}]

});

return form;

}

function getUpdateForm() {

form = new Ext.FormPanel({

labelWidth : 100,

monitorValid : true,// 把有formBind:true的按钮和验证绑定

baseCls : 'x-plain',

defaults : {

width : 200

},

defaultType : 'textfield',// 默认字段类型

// 定义表单元素

items : [{

fieldLabel : 'ID',

name : 'house.hid',

allowBlank : false,

readOnly : true

}, {

fieldLabel : '标题',

name : 'house.title',

allowBlank : false

}, {

fieldLabel : '租金',

name : 'house.hireprice'

}, {

fieldLabel : '联系人',

name : 'house.linkman'

}, {

fieldLabel : '联系电话',

name : 'house.linktel'

}, {

fieldLabel : '几室',

xtype : "combo",

hiddenName : "house.room",// 大家要注意的是hiddenName和name属性,name只是下拉列表的名称,作用是可通过,而hiddenName才是提交到后台的input的name。如果没有设置hiddenName,在后台是接收不到真正的值的。

store : new Ext.data.SimpleStore({

fields : ['a', 'b'],

data : [['1', '一'], ['2', '二'], ['3', '三']]

}),

valueField : 'a',

displayField : 'b',

mode : 'local',

triggerAction : 'all',

forceSelection : true,

selectOnFocus : true,

editable : false,

readOnly : true,

emptyText : "无限制!"

}, {

fieldLabel : '几厅',

xtype : "combo",

hiddenName : "house.ting",// 大家要注意的是hiddenName和name属性,name只是下拉列表的名称,作用是可通过,而hiddenName才是提交到后台的input的name。如果没有设置hiddenName,在后台是接收不到真正的值的。

store : new Ext.data.SimpleStore({

fields : ['a', 'b'],

data : [['1', '一'], ['2', '二'], ['3', '三']]

}),

valueField : 'a',

displayField : 'b',

mode : 'local',

triggerAction : 'all',

forceSelection : true,

selectOnFocus : true,

editable : false,

readOnly : true,

emptyText : "无限制!"

}, {

fieldLabel : "区域",

xtype : 'combo',

store : new Ext.data.SimpleStore({

fields : ['id', 'name'],

data : Ext.grid.areaComboBoxItems

}),

valueField : "id",

displayField : "name",

mode : 'local',

forceSelection : true,// 必须选择一项

emptyText : '请选择区域...',// 默认值

name : "area",

hiddenName : "house.areaId",// hiddenName才是提交到后台的input的name

editable : false,// 不允许输入

triggerAction : 'all',// 因为这个下拉是只能选择的,所以一定要设置属性triggerAction为all,不然当你选择了某个选项后,你的下拉将只会出现匹配选项值文本的选择项,其它选择项是不会再显示了,这样你就不能更改其它选项了。

id : 'parent_id2',

name : 'parent2',

listeners : {

select : function(combo, record, index) {

houseService.getAllStreets(combo.value, function(

data) {

if (data != null) {

var list2 = [];

for (var i = 0; i < data.length; i++) {

list2[i] = [data[i].sid, data[i].sname];

}

Ext.getCmp('child_id2').clearValue();

Ext.getCmp('child_id2').store

.loadData(list2);

}

});

}

}

}, {

fieldLabel : "街道",

xtype : 'combo',

store : new Ext.data.SimpleStore({

fields : ['id', 'name'],

data : []

}),

valueField : "id",

displayField : "name",

// 数据是在本地

mode : 'local',

forceSelection : true,// 必须选择一项

emptyText : '请选择街道...',// 默认值

editable : false,// 不允许输入

triggerAction : 'all',// 因为这个下拉是只能选择的,所以一定要设置属性triggerAction为all,不然当你选择了某个选项后,你的下拉将只会出现匹配选项值文本的选择项,其它选择项是不会再显示了,这样你就不能更改其它选项了。

allowBlank : false,// 该选项值不能为空

id : 'child_id2',

name : "child2",

hiddenName : "house.streetId"

}, {

fieldLabel : '房屋设施',

xtype : 'textarea',

name : 'house.housething'

}],

buttons : [{

text : '修改',

formBind : true,

type : 'submit',

// 定义表单提交事件

handler : function() {

if (form.form.isValid()) {// 验证合法后使用加载进度条

// 提交到服务器操作

form.form.doAction('submit', {

url : '../houseHandler.do?action=editHouse',// 文件路径

method : 'post',// 提交方法post或get

params : '',

// 提交成功的回调函数

failure : function(retForm, retAction) {

if (retAction.result

&& retAction.result == '1') {

Ext.MessageBox.alert('提示', '更新数据成功!');

win.hide();

ds.load({

params : {

start : ptb.cursor,

limit : ptb.pageSize

}

});

} else if (retAction.result

&& retAction.result == 'error') {

Ext.MessageBox.alert('提示', '更新数据失败!');

} else {

Ext.Msg.alert('错误', '服务器出现错误请稍后再试!');

}

},

waitMsg : '更新数据...'

});

}

}

}, {

text : '取消',

handler : function() {

form.form.reset();

}// 重置表单

}]

});

return form;

}

// 页面加载后执行的代码

Ext.onReady(function() {

// get All unit Name for comboBox.

houseService.getAllAreas(function(data) {

if (data != null) {

var list = [];

for (var i = 0; i < data.length; i++) {

list[i] = [data[i].aid, data[i].aname];

}

Ext.grid.areaComboBoxItems = list;

initData();

}

});

});

// 初始化数据

function initData() {

if (!searchForm) {

searchForm = new Ext.FormPanel({

collapsible : true,

autoHeight : true,

frame : true,

width : 800,

monitorValid : true,// 把有formBind:true的按钮和验证绑定

layout : "form",

labelWidth : 55,

title : "查询房屋信息",

renderTo : Ext.getBody(),

items : [{

xtype : "panel",// 默认就是它

layout : "column",

fieldLabel : "标题",

isFormField : true,

items : [{

columnWidth : 0.17,

xtype : "textfield",

name : "title",

anchor : "100%"

}, {

columnWidth : 0.4,

layout : "form",

labelWidth : 60,// 注意,这个参数在这里可以调整简单fieldLabel的布局位置

items : [{

xtype : "datefield",

fieldLabel : "发布日期",

name : "booktime",

anchor : "90%"

}]

}]

}, { // 上面是第一行

xtype : "panel",

layout : "column",

fieldLabel : "几室",

isFormField : true,

items : [{

columnWidth : 0.15,

xtype : "combo",

name : "room",

hiddenName : "room",// 大家要注意的是hiddenName和name属性,name只是下拉列表的名称,作用是可通过,而hiddenName才是提交到后台的input的name。如果没有设置hiddenName,在后台是接收不到真正的值的。

store : new Ext.data.SimpleStore({

fields : ['a', 'b'],

data : [['1', '一'], ['2', '二'],

['3', '三']]

}),

valueField : 'a',

displayField : 'b',

mode : 'local',

triggerAction : 'all',

// forceSelection : true,

// selectOnFocus : true,

editable : false,

emptyText : "无限制!",

anchor : "80%"

}, {

columnWidth : 0.2,

layout : "form",

labelWidth : 40,// 注意,这个参数在这里可以调整简单fieldLabel的布局位置

items : [{

xtype : "combo",

name : "ting",

hiddenName : "ting",

fieldLabel : "几厅",

store : new Ext.data.SimpleStore({

fields : ['a', 'b'],

data : [['1', '一'], ['2', '二'],

['3', '三']]

}),

valueField : 'a',

displayField : 'b',

allowBlank : true,

readOnly : true,

mode : 'local',

triggerAction : 'all',

selectOnFocus : true,

emptyText : "无限制!",

anchor : "80%"

}]

}, {

columnWidth : 0.15,

layout : "form",

labelWidth : 40,// 注意,这个参数在这里可以调整简单fieldLabel的布局位置

items : [{

fieldLabel : "租金",

xtype : "textfield",

vtype : "double",// 实数格式验证,自己扩展ExtJS

name : "priceStart",

anchor : "95%"

}]

}, {

columnWidth : 0.15,

layout : "form",

labelWidth : 10,// 注意,这个参数在这里可以调整简单fieldLabel的布局位置

items : [{

fieldLabel : "至",

labelSeparator : "",

xtype : "textfield",

vtype : "double",// 实数格式验证,自己扩展ExtJS

name : "priceEnd",

anchor : "80%"

}]

},

{

columnWidth : 0.2,

layout : "form",

labelWidth : 40,

items : [{

xtype : "radio",

fieldLabel : "排序",

boxLabel : "升序",

name : "sortCond",

checked : true,

inputValue : "asc",// 这里如果用value,值是on,所以用inputValue(出现这种情况的是radio,checkbox)

anchor : "80%"

}]

}, {

columnWidth : 0.15,

layout : "form",

labelWidth : 1,// 让标签宽度为很小的值(奇怪的是为0时反而不行)

items : [{

xtype : "radio",

boxLabel : "降序",

labelSeparator : "",// 去除分隔符“:”

name : "sortCond",

inputValue : "desc",

anchor : "80%"

}]

}

]

}, {

xtype : "panel",

layout : "column",

fieldLabel : "区域",

isFormField : true,

items : [{

columnWidth : 0.3,

xtype : 'combo',

store : new Ext.data.SimpleStore({

fields : ['id', 'name'],

data : Ext.grid.areaComboBoxItems

}),

valueField : "id",

displayField : "name",

mode : 'local',

// anchor : "60%",

forceSelection : true,// 必须选择一项

emptyText : '请选择区域...',// 默认值

name : "area",

hiddenName : "area",// hiddenName才是提交到后台的input的name

editable : false,// 不允许输入

triggerAction : 'all',// 因为这个下拉是只能选择的,所以一定要设置属性triggerAction为all,不然当你选择了某个选项后,你的下拉将只会出现匹配选项值文本的选择项,其它选择项是不会再显示了,这样你就不能更改其它选项了。

id : 'parent_id',

name : 'parent',

listeners : {

select : function(combo, record, index) {

houseService.getAllStreets(combo.value,

function(data) {

if (data != null) {

var list2 = [];

for (var i = 0; i < data.length; i++) {

list2[i] = [

data[i].sid,

data[i].sname];

}

Ext.grid.streetComboBoxItems = list2;

Ext.getCmp('child_id')

.clearValue();

Ext.getCmp('child_id').store

.loadData(list2);

}

});

}

}

}, {

fieldLabel : '街道',// 默认值

columnWidth : 0.3,

labelWidth : 40,

xtype : 'combo',

store : new Ext.data.SimpleStore({

fields : ['id', 'name'],

data : []

}),

valueField : "id",

displayField : "name",

// 数据是在本地

mode : 'local',

forceSelection : true,// 必须选择一项

emptyText : '请选择街道...',// 默认值

editable : false,// 不允许输入

triggerAction : 'all',// 因为这个下拉是只能选择的,所以一定要设置属性triggerAction为all,不然当你选择了某个选项后,你的下拉将只会出现匹配选项值文本的选择项,其它选择项是不会再显示了,这样你就不能更改其它选项了。

// allowBlank:false,//该选项值不能为空

fieldLabel : '选择',

id : 'child_id',

name : "street",

hiddenName : "street",

anchor : "60%"

}

]

}],

buttons : [{

text : "确定",

handler : query,

formBind : true

}, {

text : "取消",

handler : reset

}]

});

}

function query() {

// alert(DWRUtil.getValue("sortCond"));

// 这里是关键,重新载入数据源,并把搜索表单值提交

ds.load({

params : {

start : 0,

limit : ptb.getPageSize(),

'cond.title' : Ext.get('title').dom.value,

'cond.areaId' : Ext.get('area').dom.value,

'cond.streetId' : Ext.get('street').dom.value,

'cond.room' : Ext.get('room').dom.value,

'cond.ting' : Ext.get('ting').dom.value,

'cond.booktime' : Ext.get('booktime').dom.value,

'cond.priceStart' : Ext.get('priceStart').dom.value,

'cond.priceEnd' : Ext.get('priceEnd').dom.value,

'cond.sortCond' : DWRUtil.getValue("sortCond")

// 换一种方式获取radio里的值

// 取得搜索表单文本域的值,发送到服务端

}

})

}

function reset() {

searchForm.form.reset();

}

ds = new Ext.data.Store({

// proxy: new Ext.data.MemoryProxy(jsondata),

proxy : new Ext.data.HttpProxy({

url : '../house.do'

}),

reader : new Ext.data.JsonReader({

totalProperty : 'totalProperty',

root : 'root'

}, [{

name : 'hid'

}, {

name : 'title'

}, {

name : 'linkman'

}, {

name : 'linktel'

}, {

name : 'hireprice'

}, {

name : 'booktimeInfo'

}, {

name : 'roomTing'

}, {

name : 'areaStreet'

}])

});

ds.load({

params : {

start : 0,

limit : limit

}

});

// 这里很关键,如果不加,翻页后搜索条件就变没了,这里的意思是每次数据载入前先把搜索表单值加上去,

// 这样就做到了翻页保留搜索条件了.如果struts框架里的form放在session区域,就可以省略。

// ds.on('beforeload', function() {

// Ext.apply(this.baseParams, {

// 'cond.title' : Ext.get('title').dom.value,

// 'cond.area' : Ext.get('area').dom.value,

// 'cond.street' : Ext.get('street').dom.value,

// 'cond.room' : Ext.get('room').dom.value,

// 'cond.ting' : Ext.get('ting').dom.value,

// 'cond.booktime' : Ext.get('booktime').dom.value,

// 'cond.priceStart' : Ext.get('priceStart').dom.value,

// 'cond.priceEnd' : Ext.get('priceEnd').dom.value,

// // sortCond : Ext.get('sortCond').dom.value,

// 'cond.sortCond' : DWRUtil.getValue("sortCond")

// // 换一种方式获取radio里的值

// });

// });

initGrid();

}

// 初始化显示表格

function initGrid() {

Ext.QuickTips.init();

// //////////////////////////////////////////////////////////////////////////////////////

// win

// //////////////////////////////////////////////////////////////////////////////////////

if (!win) {

win = new Ext.Window({

el : 'add-window',

layout : 'fit', // 布局方式fit,自适应布局

width : 350,

height : 400,

modal : true,

plain : true,

bodyStyle : 'padding:5px;',

maximizable : false,// 禁止最大化

closable : true,// 禁止关闭

collapsible : true,// 可折叠

buttonAlign : 'center',

closeAction : 'hide'

});

}

var sm = new Ext.grid.CheckboxSelectionModel();

var cm = new Ext.grid.ColumnModel([sm, {

id : 'hid',

header : "房屋号",

width : 20,

sortable : true,

dataIndex : 'hid'

}, {

header : "房屋标题",

width : 40,

sortable : true,

dataIndex : 'title'

}, {

header : "联系人",

width : 20,

sortable : true,

dataIndex : 'linkman'

}, {

header : "联系电话",

width : 30,

sortable : true,

dataIndex : 'linktel'

}, {

header : "月租金",

width : 30,

sortable : true,

renderer : function(value) {

// Ext.util.Format.usMoney

if (value > 1000) {

return "<span style='color:red;font-weight:bold;'>"

+ value + "</span>元";

} else {

return "<span style='color:green;font-weight:bold;'>"

+ value + "</span>元";

}

},

dataIndex : 'hireprice'

}, {

header : "发布日期",

width : 30,

sortable : true,

// renderer: Ext.util.Format.dateRenderer('m/d/Y'),

dataIndex : 'booktimeInfo'

}, {

header : "房屋格局",

width : 40,

sortable : true,

dataIndex : 'roomTing'

}, {

header : "街道地址",

width : 60,

sortable : true,

dataIndex : 'areaStreet'

}]);

//定义一个完整的记录对象

TopicRecord = Ext.data.Record.create([{

name : 'hid',

mapping : 'house.hid'

},{

name : 'title',

mapping : 'house.title'

}, {

name : 'hireprice',

mapping : 'house.hireprice'

}, {

name : 'linkman',

mapping : 'house.linkman'

}, {

name : 'linktel',

mapping : 'house.linktel'

},{

name : 'room',

mapping : 'house.room'

},{

name : 'ting',

mapping : 'house.ting'

},{

name : 'areaId',

mapping : 'house.areaId'

},{

name : 'streetId',

mapping : 'house.streetId'

},{

name : 'housething',

mapping : 'house.housething'

}]);

//工具栏对象

ptb = new Ext.PagingToolbar({

plugins : new Ext.ux.Andrie.pPageSize(),

pageSize : limit,

store : ds,

displayInfo : true,

displayMsg : '显示第 {0} 条到 {1} 条记录,一共 {2} 条',

emptyMsg : "对不起,查询记录为空!"

});

grid = new Ext.grid.GridPanel({

id : 'button-grid',

border : false,

buttonAlign : 'right',

ds : ds,

cm : cm,

sm : sm,

stripeRows : true,

loadMask : true,

viewConfig : {

forceFit : true

},

// inline toolbars

tbar : [{

id : 'houseAddBtn',

text : '发布',

tooltip : '发布一条房屋信息',

iconCls : 'add',

onClick : function() {

// update form to insert form

win.title = '添加房屋信息';

form = getInsertForm();

var items = new Ext.util.MixedCollection();

items.add("form", form);

win.items = items;

win.show();

//form.getForm().reset();

}

}, '-', {

id : 'houseEditBtn',

text : '编辑',

tooltip : '修改一条房屋信息',

iconCls : 'option',

onClick : function() {

if (sm.getCount() == 1) {

// update form to edit form

win.title = '编辑房屋信息';

form = getUpdateForm();

var items = new Ext.util.MixedCollection();

items.add("form", form);

win.items = items;

win.show();

form.getForm().reset();

var hid = sm.getSelected().data.hid;

houseService.findById(hid, callback);

function callback(data) {

//列表影射,columnModelvar

var myNewRecord = new TopicRecord({'house.hid':data.hid, 'house.title': data.title, 'house.hireprice':data.hireprice

,'house.linkman':data.linkman,'house.linktel':data.linktel,'house.room':data.room,'house.ting':data.ting,'house.areaId':data.areaId,'house.streetId':data.streetId,'house.housething':data.housething});

houseService.getAllStreets(data.areaId, function(

data) {

if (data != null) {

var list2 = [];

for (var i = 0; i < data.length; i++) {

list2[i] = [data[i].sid, data[i].sname];

}

Ext.getCmp('child_id2').clearValue();

Ext.getCmp('child_id2').store

.loadData(list2);

// 实际的一条记录

form.getForm().loadRecord(myNewRecord);

}

});

}

} else {

Ext.MessageBox.alert('提示', '请选择一条记录!');

}

}

}, '-', {

id : 'houseDelBtn',

text : '删除',

tooltip : '删除选择的房屋信息',

iconCls : 'remove',

onClick : function() {

if (sm.hasSelection()) {

Ext.MessageBox.confirm('提示', '你确定要删除这些租房信息么?',

function(button) {

if (button == 'yes') {

var list = sm.getSelections();

var rList = [];

for (var i = 0; i < list.length; i++) {

rList[i] = list[i].data["hid"];

}

houseService.delHouse(rList,

function(data) {

if (data > 0) {

Ext.MessageBox

.alert(

'提示',

"删除"

+ data

+ '条数据成功!');

// 如果把当页数据删除完毕,则跳转到上一页!

if (data == ptb.store

.getTotalCount()

- ptb.cursor) {

ptb.cursor = ptb.cursor

- ptb.pageSize;

}

ds.load({

params : {

start : ptb.cursor,

limit : ptb.pageSize

}

});

} else {

Ext.MessageBox

.alert(

'提示',

"删除数据失败!");

}

});

}

});

} else {

Ext.MessageBox.alert('提示', "请至少选择一条记录!");

}

}

}, '-', {

id : 'houseRefreshBtn',

text : '刷新',

tooltip : '刷新房屋信息',

iconCls : 'refresh',

onClick : function() {

ds.load({

params : {

start : ptb.cursor,

limit : ptb.pageSize

}

});

}

}, '-', {

id : 'houseCopyBtn',

text : '复制',

tooltip : '复制添加选择的房屋信息',

iconCls : 'copy',

onClick : function() {

if (sm.getCount() == 1) {

// update form to edit form

form = getInsertForm();

var items = new Ext.util.MixedCollection();

items.add("form", form);

win.items = items;

win.show();

var hid = sm.getSelected().data.hid;

houseService.findById(hid, callback);

function callback(data) {

//列表影射,columnModelvar

var myNewRecord = new TopicRecord({'house.hid':data.hid, 'house.title': data.title, 'house.hireprice':data.hireprice

,'house.linkman':data.linkman,'house.linktel':data.linktel,'house.room':data.room,'house.ting':data.ting,'house.areaId':data.areaId,'house.streetId':data.streetId,'house.housething':data.housething});

houseService.getAllStreets(data.areaId, function(

data) {

if (data != null) {

var list2 = [];

for (var i = 0; i < data.length; i++) {

list2[i] = [data[i].sid, data[i].sname];

}

Ext.getCmp('child_id1').clearValue();

Ext.getCmp('child_id1').store

.loadData(list2);

// 实际的一条记录

form.getForm().loadRecord(myNewRecord);

}

});

}

} else {

Ext.MessageBox.alert('提示', "请选择一条记录!");

}

}

}, '-', {

id : 'houseImportBtn',

text : '导入',

tooltip : '批量导入房屋信息',

iconCls : 'import',

onClick : function() {

}

}, '-', {

id : 'houseExportExcelBtn',

text : '导出Excel',

tooltip : '导出房屋信息',

iconCls : 'export',

onClick : function() {

window.location = "../houseExport.do?type=excel&start="

+ ptb.cursor + "&limit=" + ptb.pageSize;

}

}, '-', {

id : 'houseExportPdfBtn',

text : '导出Pdf',

tooltip : '导出房屋信息',

iconCls : 'export',

onClick : function() {

window.location = "../houseExport.do?type=pdf&start="

+ ptb.cursor + "&limit=" + ptb.pageSize;

}

}, '-', {

id : 'housePrintBtn',

text : '打印',

tooltip : '打印房屋信息',

iconCls : 'print',

onClick : function() {

//利用IE的简单打印

self.print();

}

}, '-', {

id : 'houseDetailBtn',

text : '详情',

tooltip : '查看所选房屋信息详情',

iconCls : 'details',

onClick : function() {

Ext.MessageBox.alert("详细",'舞动绚丽的ExtJS吧!');

Ext.alert(333);

}

}],

bbar : ptb,

width : 800,

autoHeight : true,

// height : 250,

// frame : true,

title : '房屋信息列表',

iconCls : 'icon-grid',

renderTo : document.body

});

grid.on('rowcontextmenu', rightClickFn);// 右键菜单代码关键部分

var rightClick = new Ext.menu.Menu({

id : 'rightClickCont',

items : [{

id : 'rMenu1',

handler : Ext.getCmp('houseAddBtn').onClick,// 点击后触发的事件

text : '添加信息'

}, {

id : 'rMenu2',

handler : Ext.getCmp('houseEditBtn').onClick,

text : '编辑信息'

}, {

id : 'rMenu3',

handler : Ext.getCmp('houseDelBtn').onClick,// 点击后触发的事件

text : '删除信息'

}, {

id : 'rMenu4',

handler : Ext.getCmp('houseRefreshBtn').onClick,

text : '刷新数据'

}, {

id : 'rMenu5',

handler : Ext.getCmp('houseCopyBtn').onClick,// 点击后触发的事件

text : '复制数据'

}, {

id : 'rMenu6',

handler : Ext.getCmp('houseImportBtn').onClick,

text : '导入数据'

}, {

id : 'rMenu7',

handler : Ext.getCmp('houseExportExcelBtn').onClick,// 点击后触发的事件

text : '导出EXCEL数据'

}, {

id : 'rMenu8',

handler : Ext.getCmp('houseExportPdfBtn').onClick,

text : '导出PDF数据'

}, {

id : 'rMenu9',

handler : Ext.getCmp('housePrintBtn').onClick,// 点击后触发的事件

text : '打印数据'

}, {

id : 'rMenu10',

handler : Ext.getCmp('houseDetailBtn').onClick,

text : '查看详情'

}]

});

function rightClickFn(grid, rowindex, e) {

e.preventDefault();

rightClick.showAt(e.getXY());

}

// function rMenuFnAdd() {

// Ext.getCmp('houseAddBtn').onClick;

// }

// function rMenuFnEdit() {

//

// }

// function rMenuFnDel() {

//

// }

// function rMenuFnRefresh() {

//

// }

// function rMenuFnCopy() {

// alert(Ext.getCmp('houseCopyBtn').onClick);

// return Ext.getCmp('houseCopyBtn').onClick;

// }

// function rMenuFnImport() {

//

// }

// function rMenuFnExportExcel() {

//

// }

// function rMenuFnExcelPdf() {

//

// }

// function rMenuFnPrint() {

//

// }

// function rMenuFnDetail() {

// return Ext.getCmp('houseDetailBtn').onClick;

// }

}

// 扩展extjs的验证!

Ext.apply(Ext.form.VTypes, {

// 固定电话、传真

phone : function(v) {

var r = /^((\(\d{2,3}\))|(\d{3}\-))?(\(0\d{2,3}\)|0\d{2,3}-)?[1-9]\d{6,7}(\-\d{1,4})?$/;

return r.test(v);

},

// 移动电话

mobile : function(v) {

var r = /^((\(\d{2,3}\))|(\d{3}\-))?13\d{9}$/;

return r.test(v);

},

// 邮政编码

zip : function(v) {

var r = /^[1-9]\d{5}$/;

return r.test(v);

},

// 搜索关键字过滤

search : function(v) {

var r = /^[^`~!@#$%^&*()+=|\\\][\]\{\}:;'\,.<>/?]*$/;

return r.test(v);

},

// 简体中文

chinese : function(v) {

var r = /^[\u0391-\uFFE5]+$/;

return r.test(v);

},

// 非中文

noChinese : function(v) {

var r = /^^[\u0391-\uFFE5]+$/;

return r.test(v);

},

// 货币

currency : function(v) {

var r = /^\d+(\.\d+)?$/;

return r.test(v);

},

// QQ

qq : function(v) {

var r = /^[1-9]\d{4,8}$/;

return r.test(v);

},

// 实数

double : function(v) {

var r = /^[-\+]?\d+(\.\d+)?$/;

return r.test(v);

},

// 安全密码

safe : function(v) {

var r = /^(([A-Z]*|[a-z]*|\d*|[-_\~!@#\$%\^&\*\.\(\)\[\]\{\}<>\?\\\/\'\"]*)|.{0,5})$|\s/;

return !r.test(v);

},

phoneText : '请输入正确的电话或传真号码!<br />格式如:0000-XXXXXXXX',

mobileText : '请输入正确的移动电话号码!<br />格式如:13XXXXXXXXX',

zipText : '请输入正确的邮政编码!',

searchText : '请不要输入非法的搜索字符!',

chineseText : '您只能在这里输入中文字符!',

noChineseText : '您不能在这里输入中文字符!',

currencyText : '请输入货币值!<br />格式如:1.00',

qqText : '请输入合法的QQ号码!',

doubleText : '请输入实数值,可带+/-号!',

safeText : '请输入足够安全的字符,包含英文和数字货其他字符!'

});

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约