目标:使用ExtJS3.4搭建Web页面(20130130)(20130219修改)
1、了解ExtJS
-
ExtJS是一种主要用于创建前端用户界面、与后台技术无关的、用JS实现的前端ajax框架,如果你不懂PS&CSS又想做出漂亮的界面,不妨试一试ExtJS。
优点:
有着丰富的控件库、丰富的工具包、清晰的语法结构,可以让一个有Swing编程经验的人很容易上手。
对AJAX进行了很好的封装,另你可以在不用知道XMLHttpRequest&ActionXObject的情况下,就写出一个AJAX程序。
缺点:
由于ExtJS过度的封装,导致其组件的灵活性下降,在改变外观样式的时候,也经常出现弄巧成拙的事情。
TIPS:
ExtJS是基于AJAX技术的,如果你对AJAX没有一个全面的了解,在深入学习时会走不少弯路。
-
目前最新版是4.1.3,官方承诺会给出一个向后兼容(ExtJS3)的方案,但ExtJS3到ExtJS4的变化巨大,所以,学习ExtJS4并且兼容两者需花费较大代价。
ExtJS4较ExtJS3结构更清晰,更便于开发&维护,新人可以直接学习ExtJS4,而这里则使用ExtJS3。
ExtJS3.4下载地址:http://www.sencha.com/products/extjs3/download/
1)简介
2)选择哪个版本
2、如何在项目中使用ExtJS
-
使用ExtJS所需的必要文件包括以下4个:
ext-3.4.0\ext-all.js(Ext的主要库文件)
ext-3.4.0\adapter\ext\ext-base.js(Ext的“适配器”)
ext-3.4.0\src\locale\ext-lang-zh_CN.js(中文字体文件)
ext-3.4.0\resources(resources目录包含ExtJS所需CSS文件&效果图片)
将以上文件统一复制到项目中用于存放extjs的目录,比如我的目录是extjs。
然后,在页面引入ExtJS所需文件:
<!-- 注意下列ExtJS必要文件的引入顺序,顺序错误将导致无法正确加载 --> <link rel="stylesheet" type="text/css" href="extjs/resources/css/ext-all.css"/> <link rel="stylesheet" type="text/css" href="extjs/ext-patch.css"/><!--ext-patch.css是一个修复不同浏览器显示字体大小不同的补丁,并非必要导入,也可直接使用修正过字体大小的ext-all.css--> <script type="text/javascript" src="extjs/ext-base.js"></script> <script type="text/javascript" src="extjs/ext-all.js"></script> <script type="text/javascript" src="extjs/ext-lang-zh_CN.js"></script>
导入所需文件后,可以进行下简单测试:
<script type="text/javascript"> Ext.onReady(function(){//Ext.onReady的作用在于等待html元素加载完后再执行其中的“()”内的extjs代码 alert("test ok!");//测试一下是否导入成功 }) </script>
Notice:若不使用Ext.onReady加载ExtJS代码,页面会按顺序先执行位于head部分的ExtJS代码再加载html元素,这样做会导致ExtJS中所引用的html元素全部无效(还未被加载)。
-
ExtJS通过Javascript对Html DOM(Document Object Model)进行修改(包括加入CSS),从而改变Html页面的最终效果,因此,你即可以对页面已有的Html元素(比如div)进行渲染,也可以由ExtJS直接生成整个页面,方式比较灵活,考虑到直观&便捷性,这里使用前者,即先用div对页面进行整体布局,再用ExtJS对div进行渲染。
一个简单的应用,获取页面中Html元素:
<script type="text/javascript"> Ext.onReady(function(){ alert(Ext.get("test1").getValue());//通过id获得html元素 }) </script> <input type="text" value="value1" id="test1"/>
1)导入必要的文件
2)从一个简单的应用入手
3、Login界面
login.html部分:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<!-- 注意下列ExtJS必要文件的引入顺序,顺序错误将导致无法正确加载 -->
<link rel="stylesheet" type="text/css"
href="extjs/resources/css/ext-all.css" />
<link rel="stylesheet" type="text/css" href="extjs/ext-patch.css" />
<!--ext-patch.css是一个修复不同浏览器显示字体大小不同的补丁,并非必要导入,也可直接使用修正过字体大小的ext-all.css-->
<script type="text/javascript" src="extjs/ext-base.js"></script>
<script type="text/javascript" src="extjs/ext-all.js"></script>
<script type="text/javascript" src="extjs/ext-lang-zh_CN.js"></script>
<script type="text/javascript" src="customjs/login.js"></script>
</head>
<body>
<div
style="width: 100%; height: 100%; position: absolute; left: 0; top: 0;">
<img src="images/login_bg.jpg" style="width: 100%; height: 100%" />
</div>
<div id="bbgPanel"
style="position: absolute; z-index: 2; width: 763px; height: 433px;">
<div id="loginpanel"
style="position: absolute; z-index: 3; left: 31px; top: 32px;"></div>
</div>
</body>
</html>
login.js部分:
Ext.onReady(function() {
Ext.QuickTips.init();
var login_form = new Ext.FormPanel(
{
defaultType : 'textfield',
labelWidth : 50,
style : 'background:url(images/login_form_bg.jpg);padding:10px 5px 30px 0px',
region : 'center',
bodyStyle : 'background:url(images/login_form_bg.jpg);',
defaults : {
allowBlank : false,
blankText : '该字段不允许为空',
msgTarget : 'side'
},
waitMsgTarget : true,
items : [ {
fieldLabel : '用户名',
name : 'userName',
id : 'userName',
width : 210,
regex : /^[0-9a-zA-Z]{5,12}$/,
regexText : '只能为数字,字母并且长度在5-12之间',
style : 'margin-bottom:15px'
}, {
fieldLabel : '密 码',
name : 'userPwd',
id : 'userPwd',
width : 210,
regex : /^[0-9a-zA-Z]{5,12}$/,
regexText : '只能为数字,字母并且长度在5-12之间',
style : 'margin-bottom:15px'
},
{
xtype : 'panel',
layout : 'column',
border : false,
bodyStyle : 'background:#e9e9e9;',
items : [ {
width : 210,
bodyStyle : 'background:#e9e9e9;',
layout : 'form',
border : false,
items : [ {
xtype : 'textfield',
fieldLabel : '验证码',
name : 'checkcode',
id : 'checkcode',
allowBlank : false,
blankText : '该字段不允许为空',
msgTarget : 'side'
} ]
}, {
xtype : 'panel',
width : 63,
height : 22,
html : '<img src="images/checkcodeTest.jpg">'
} ]
}
],
buttons : [
{
text : '登录',
handler : function() {
/*
* login_form.getForm().submit({
* success:function(login_form,action){
* window.location.href =
* action.result.url + ".jsp"; },
* url:'login.action',
* waitMsg:'正在提交,请等待' })
*/
var uname = Ext.getCmp("userName");
var upwd = Ext.getCmp("userPwd");
Ext.Ajax
.request({
url : 'login.action',
params : {
userName : uname
.getValue(),
userPwd : upwd
.getValue()
},
method : 'post',
callback : function(
options, success,
response) {
if (success) {
// Ext.Msg.alert("系统提示",Ext.util.JSON.decode(response.responseText).msg);
window.location.href = Ext.util.JSON
.decode(response.responseText).url
+ ".jsp";
} else {
Ext.Msg.alert(
"系统提示",
"提交失败");
alert(response.responseText);
}
}
});
}
}, {
text : '取消',
handler : function() {
login_form.getForm().reset();
}
} ]
});
var panel = new Ext.Panel({
renderTo : 'loginpanel',
layout : 'border',
width : 690,
height : 352,
bodyStyle : 'border:none;',
defaults : {
border : false
},
items : [ {
region : 'north',
height : 95,
html : '<img src="images/login_top.jpg">'
}, {
region : 'south',
height : 61,
html : '<img src="images/login_bottom.jpg">'
}, {
region : 'west',
width : 392,
height : 196,
html : '<img src="images/login_left.jpg">'
}, login_form ]
});
Ext.get("bbgPanel").center(Ext.getBody());
Ext.get("bbgPanel").setStyle("background","url(images/login_bbg.png) no-repeat");//最后加载中间背景,防止背景闪动,这是一个折中解决方式
});
4、页面整体布局
-
titlePanel newsPanel showPanel menuPanel titlePanel——标题栏(置放说明、用户切换、注销按钮)、newsPanel——新闻栏(公告、新闻、通知)、menuPanel——菜单栏(主要功能按钮均至于此)、showPanel——显示栏(功能按钮反馈信息显示于此)
-
VeiwPort 代表浏览器的整个显示区域,该对象会渲染到页面的body区域,并随着浏览器显示区域的大小调整自动改变,一个页面中只能有一个ViewPort 实例。
ViewPort采用border布局,titlePanel置于north区域,showPnael置于center区域,(westPanel是一个border布局的Panel,其中newsPanel置于north区域&menuPanel置于center区域)westPanel置于west区域。
<script type="text/javascript"> Ext.onReady(function(){ var viewport = new Ext.Viewport({//ViewPort能根据浏览器缩放,调整显示区域所显示的组件大小 layout:'border'//这种常用布局以东南西北中的形式布局 ,items:[{//north——标题 region:'north'//位置 ,contentEl:'north'//显示元素id=north的内容 ,height:104 },{//west——公告&菜单 region:'west' ,contentEl:'west' ,title:'公告' ,width:200 ,collapsible:true//折叠效果true },{//center——显示区 region:'center' ,contentEl:'center' }] }); }); </script> </head> <body> <div id="north">titlePane</div> <div id="west"></div> <div id="center">mainPanel</div> </body
1)布局结构
2)建立草案
5、各模块初步搭建(20130202)(20130220修改)
-
使用photoshop制作背景,选取所需的背景的1个像素Ctrl+C(复制)==》Ctrl+N(新建)==》Ctrl+V(粘贴),然后保存到项目images子目录下。(为了保证切割完整性,可用放大镜查看,Alt+S、T调整大小)
title_bg.jpg、title_logo.jpg、title_about.jpg、title_exit.jpg(规划好名字以便维护)
==》统一保存到图片目录images下。
在页面中引用背景&图标:
<body> <div id="north"> <div id="north_top" style="background-image: url(images/title_bg.jpg); height: 82px"> <!--由于子div使用float漂浮,使得子div不会主动填充父div的高度,因此需要指定父div高度height才能正常显示背景图片--> <div id="north_top_logo" style="float: left; padding-left: 25px;"> <img src="images/title_logo.jpg" /> </div> <div id="north_top_about" style="float: right; padding-right: 140px;"> <img src="images/title_about.jpg" /> </div> <div id="north_top_exit" style="float: right; padding-right: 60px;"> <img src="images/title_exit.jpg" /> </div> </div> <div id="north_wel" style="background-color: #1c71c1; height: 22px; font-size: 12px; color: #FFFFF; padding-legt: 25px; line-height: 22px">Welcome to use MyCRM</div> <!--文字显示于行中,因此设置行高line-height与元素高度一致,文字才能居中--> </div> <div id="west"></div> <div id="center">mainPanel</div> </body>
Notice:了解margin&padding之间的差异,才能更好的使用它们调整间距。
-
westPanel部分是一个复合面板,分为上(newsPanel)下(menuPanel)两部分,因此使用border布局,上部置于north区域,下部至于center区域。
首先是newsPanel部分,它所显示的是列表形式的新闻公告,因此先创建一块属于newsPanel的div,在div中建立ul列表,然后在ExtJS代码中使用contentEl元素引用该div即可。
<!-- CSS部分 --> #newsHtml { font-size: 14px; height: 75px; padding-top: 5px padding-left:10px; background-color: #F1FFFF; } #newsHtml ul { list-style-type: none;<!-- 不使用系统默认的标的 --> } #newsHtml ul li { height: 23px; } <!-- ExtJS部分 --> var newsPanel = new Ext.Panel({ region:'north', title:'新闻公告', width:200, contentEl:'newsHtml' }); <!-- Html部分 --> <div id="newsHtml"> <ul> <li><img src="images/news_icon.jpg" />news one</li> <li><img src="images/news_icon.jpg" />news two</li> <li><img src="images/news_icon.jpg" />news three</li> </ul> </div>
再来是menuPanel部分,它所显示的是四方格形式的功能按钮,这里采用ul列表,将列表元素浮动的办法生成四方格按钮布局,与newsPanel相同地,先建立div,再在div中建立ul列表,然后利用css使ul元素li浮动形成四方格的展现形式。
menuPanel具有3个分组,采用accordion布局,因此需要为每个分组建立不同的div,id分别对应menuHtml1、menuHtml2、menuHtml3,但由于3个分组使用的css相同,所以,可以指定class="menuHtml",对menuHtml进行css设置简化代码。
<!-- css部分 --> .menuTitleIcon { background: url(images/menu_title_icon.jpg) no-repeat; } .menuHtml ul { list-style-type: none; width: 190px; } .menuHtml ul li { cursor: pointer; width: 80px; height: 96px; padding-left: 5px; float: left; font-size: 14px; text-align: center; } .menuItemBg { margin-left: 5px; width: 65px; height: 86px; } .menuItemText { width: 80px; text-align: center; padding-left: 4px; } <!-- ExtJS部分 --> var menuPanel = new Ext.Panel({ region : 'center', layout : 'accordion',//水平Tab风格的折叠布局 width : 200, layoutConfig : {//布局配置 titleCollapse : true,//点击标题栏任意位置均可激活折叠 animate : true,//动画效果是否打开 activeOnTop : false//折叠开启的栏目是否置于顶端 }, items : [ { title : 'title1', contentEl : 'menuHtml1', iconCls : 'menuTitleIcon', bodyStyle : 'background-color:#f7fcff;' }, { title : 'title2', contentEl : 'menuHtml2', iconCls : 'menuTitleIcon', bodyStyle : 'background-color:#f7fcff;' }, { title : 'title3', contentEl : 'menuHtml3', iconCls : 'menuTitleIcon', bodyStyle : 'background-color:#f7fcff;' } ] }); <!-- Html部分,menuHtml2、menuHtml3与menuHtml1相似,以此类推 --> <div id="menuHtml1" class="menuHtml"> <ul> <li> <div style="background: url(images/menu_icon_1_1.jpg) center no-repeat;" class="menuItemBg"></div> <div class="menuItemText">客户拜访</div> </li> <li><div style="background: url(images/menu_icon_1_2.jpg) center no-repeat;" class="menuItemBg"></div> <div class="menuItemText">联系人管理</div></li> <li><div style="background: url(images/menu_icon_1_3.jpg) center no-repeat;" class="menuItemBg"></div> <div class="menuItemText">拜访记录</div></li> <li><div style="background: url(images/menu_icon_1_4.jpg) center no-repeat;" class="menuItemBg"></div> <div class="menuItemText">分析与报表</div></li> </ul> </div>
最后,将newsPanel&menuPanel置入westPanel,完成左侧面板。将westPanel替换viewPort中原先的west部分即完成了嵌套布局。
var westPanel = new Ext.Panel({//west——公告&菜单 title : 'west', layout : 'border', collapsible : true,//折叠效果true region : 'west', width : 200, items : [ newsPanel, menuPanel ]//将newsPanel&menuPanel作为元素加入newsPanel });
-
显示区默认界面以九宫格为例,类似布局在设置时有一个技巧,就是使用分层式结构建立这一系列div:
<div id="centerHtml"> <div id="mainHtml1"> <div id="mainHtml1_1"><h1>过期用户<span>0</span></h1></div> <div id="mainHtml1_2"><h1>过期用户<span>0</span></h1></div> <div id="mainHtml1_3"><h1>过期用户<span>0</span></h1></div> </div> <div id="mainHtml2"> <div id="mainHtml2_1"><h1>过期用户<span>0</span></h1></div> <div id="mainHtml2_2"><h1>过期用户<span>0</span></h1></div> <div id="mainHtml2_3"><h1>过期用户<span>0</span></h1></div> </div> <div id="mainHtml3"> <div id="mainHtml3_1"><h1>过期用户<span>0</span></h1></div> <div id="mainHtml3_2"><h1>过期用户<span>0</span></h1></div> <div id="mainHtml3_3"><h1>过期用户<span>0</span></h1></div> </div> </div>
为了使代码便于管理,应尽量合理地简化css代码数量、清晰代码结构,所以利用技巧将一些可复用的代码合并到一起:
#centerHtml { background-color: #f5f6f7; height: 100%; width: 100%; overflow: auto; } #centerHtml h1 { font-size: 14px; position: absolute; bottom: 15px; left: 70px; } #centerHtml span { color: #FF0000; } #mainHtml1 { background: url(images/main_icon_1_bg.jpg) repeat-x; height: 160px; width: 100%; } #mainHtml1_1,#mainHtml1_2,#mainHtml1_3 { height: 160px; text-align: center; position: relative; } #mainHtml1_1 { background: url(images/main_icon_1_1.jpg) center top no-repeat; width: 230px; float: left; } #mainHtml1_2 { background: url(images/main_icon_1_2.jpg) center top no-repeat; float: left; width: 175px; } #mainHtml1_3 { background: url(images/main_icon_1_3.jpg) center top no-repeat; width: 248px; float: right; } #mainHtml2 { height: 160px; width: 100%; } #mainHtml2_1,#mainHtml2_2,#mainHtml2_3 { height: 160px; text-align: center; position: relative; } #mainHtml2_1 { background: url(images/main_icon_2_1.jpg) center center no-repeat; width: 230px; float: left; } #mainHtml2_2 { background: url(images/main_icon_2_2.jpg) center center no-repeat; float: left; width: 175px; } #mainHtml2_3 { background: url(images/main_icon_2_3.jpg) center center no-repeat; width: 248px; float: right; } #mainHtml3 { background: url(images/main_icon_3_bg.jpg) repeat-x; height: 164px; width: 100%; } #mainHtml3_1,#mainHtml3_2,#mainHtml3_3 { height: 164px; text-align: center; position: relative; } #mainHtml3_1 { background: url(images/main_icon_3_1.jpg) center top no-repeat; width: 230px; float: left; } #mainHtml3_2 { background: url(images/main_icon_3_2.jpg) center top no-repeat; float: left; width: 175px; } #mainHtml3_3 { background: url(images/main_icon_3_3.jpg) center top no-repeat; width: 248px; float: right; }
为了使整体显示效果能够随Browser大小改变进行实时调整,需要使用js对width&height进行事件控制。
var westWidth = 230; var $ = function(str) { return document.getElementById(str); } Ext.EventManager.onWindowResize(function(width, height) {//浏览器窗口大小调整触发事件 setItemsMiddle(westWidth); setItemHMiddle(); }); function setItemsMiddle(westWidth) { var bodyWidth = document.body.clientWidth - westWidth; for ( var i = 1; i <= 3; i++) { $("mainHtml" + i + "_2").style.width = bodyWidth - $("mainHtml1_1").clientWidth - $("mainHtml1_3").clientWidth + "px"; var icon_h1 = $("mainHtml" + i + "_2").getElementsByTagName("h1")[0]; icon_h1.style.left = ($("mainHtml" + i + "_2").clientWidth - icon_h1.clientWidth)/ 2 + "px"; } } function setItemHMiddle() { var bodyHeight = document.body.clientHeight - 104; itemHeight = bodyHeight - $("mainHtml1").clientHeight - $("mainHtml3").clientHeight + "px"; $("mainHtml2").style.height = itemHeight; for ( var i = 1; i <= 3; i++) { $("mainHtml2_" + i + "").style.height = itemHeight; } }
1)north——标题(titlePanel)
2)west——公告&菜单(嵌套了newsPanel&menuPanel的westPanel)
3)center——显示区(20130203)
-
在MyEclipse中安装ExtJS语法插件,http://www.spket.com/update,Configuration Center==》Software==》Browse Software==》add site。
添加成功后,Preferences==》Spket==》New输入ExtJS3.2==》Add Library选择ExtJS==》add File加入ext.jsb2文件。
-
用户每次打开主页可能只需要访问其中的个别页面,但当用户首次访问主页时,总会一次性将全部JS代码加载到本地,随着主页JS代码的增多,这无疑是一种资源浪费,因此这里需要做一点优化。使首次访问时只加载主页必要信息,分支页信息只有当用户点击menuPanel中的某个按钮时,才会进行进一步加载,然后显示在center区域。首先将center区域用于加载分支页的tabPanel提取为全局变量:
/*定义全局变量tabPanel*/ var tabPanel; Ext.onReady(function(){ //... <!--初始化tabPanel--> tabPanel = new Ext.TabPanel({ region:'center'//位置 ,activeTab: 0 ,items:[centerPanel] }); //... })
通过普通方式完成mainPanel的加载:
通过在html标签中添加onclick事件触发togo即可达到在tabPanel中打开分支页的效果。function togo(){ var menu1_visit = tabPanel.findById("tab1_1");//搜索已定义组件中是否存在id为tab1_1的组件 if(!menu1_visit){ var sbuttonPanel = new Ext.Panel({ title:'搜索范围' ,layout:'column' ,defaultType:'button' ,items:[{ text:'今天已联系' ,columnWidth:.333 },{ text:'过期未联系' ,columnWidth:.333 },{ text:'全部' ,columnWidth:.333 }] }); var tab = tabPanel.add({ id:'tab1_1'//定义id的含义在于,再次打开时搜索标识为该id的组件是否存在,若已存在则直接取出,避免重复打开 ,title:'客户拜访' ,closable:true ,items[sbuttonPanel] }); tabPanel.activate(tab); }else{ tabPanel.activate(menu1_visit); } }
-
但以上方式仍然会在首次打开就引入所有js文件,势必造成资源浪费,所以采用需要时引入的方式,称为动态加载。
将它修改为动态加载方式,这里使用js提供的方式:
然后,将原来在onclick事件中触发togo改为触发dynamicImportJs(js文件名),通过将原来的function togo函数名去掉,就可以达到动态加载的效果了。function dynamicImportJS(src) { var jsPath = "customjs/" + src + ".js"; var headDom = document.getElementsByTagName("head").item(0);//虽然head只有一个下标为0的元素,但碍于语法规定必定加上item(0) var jsDom = document.createElement("script"); jsDom.type = "text/javascript"; jsDom.src = jsPath; headDom.appendChild(jsDom); }
为了避免每次点击按钮都会触发dynamicImportJs转而重复加载相同的js文件,所以需要对点击机制做一些修改:
//index.html //首先定义一个全局变量 var centerComponent = new Object();//定义一个center区域的全局组件数组,首次点击时先从数组中寻找,若失败再进行加载,避免每次点击时重复加载 function dynamicImportJS(src){ //var l = document.getElementsByTagName("script").length; //alert(l);//测试重复点击是否重复加载 try{ centerComponent[src](); } catch(e){//仅当第一次执行出现异常时才加载js文件,虽然每次点击仅执行src对应函数 var jsPath = "customjs/" + src + ".js"; var headDom = document.getElementsByTagName("head").item(0);//虽然head只有一个下标为0的元素,但碍于语法规定必定加上item(0) var jsDom = document.createElement("script"); jsDom.type = "text/javascript"; jsDom.src = jsPath; headDom.appendChild(jsDom); } } //menu1_visit.js centerComponent.menu1_visit = function() { var menu1_visit = centerPanel.findById("menu1_visit"); if(!menu1_visit){ //...... } centerComponent.menu1_visit();
-
(1)取消自动validation:windows–>perferences–>myeclipse–>validation除开Manual下面的复选框全部选中之外,其他全部不选。
(2)取消Eclipse拼写检查:windows–>perferences–>general–>validation->editors->Text Editors->spelling。
(3)更改内存使用文件:打开 eclipse.ini,把XX:PermSize和XX:MaxPermSize调大,注意:XX:MaxPermSize 和 Xmx 的大小之和不能超过你的电脑内存大小。
1)Eclipse中ExtJS语法提示插件安装
2)动态加载初步
3)动态加载完善
4)MyEclipse初步优化:
7、mainPanel子窗口之查询
搜索表单FormPanel:
var formPanel = new Ext.form.FormPanel({
anchor : '0 25%',
title : '客户搜索',
labelAlign : 'right',
labelWidth : 60,
frame : true,
items : [ {
layout : 'column',
items : [ {
columnWidth : .28,
layout : 'form',
defaultType : 'textfield',
items : [ {
fieldLabel : '客户编码'
}, {
fieldLabel : '客户名称'
}, {
fieldLabel : '拼音码'
} ]
}, {
columnWidth : .28,
layout : 'form',
defaultType : 'textfield',
items : [ {
fieldLabel : '电话1'
}, {
fieldLabel : '所属部门'
}, {
fieldLabel : '所属人'
} ]
}, {
columnWidth : .28,
layout : 'form',
defaultType : 'textfield',
items : [ {
fieldLabel : '客户登记'
}, {
fieldLabel : '客户来源'
}, {
fieldLabel : '客户性质'
} ]
}, {
columnWidth : .16,
defaultType : 'button',
layout : 'column',
items : [ {
text : '搜索',
columnWidth : .5
}, {
text : '清空',
columnWidth : .5
} ]
} ]
} ]
});
显示数据的GridPanel:
/* 定义用于显示数据的ColumnModel */
var sModel = new Ext.grid.CheckboxSelectionModel();
var cModel = new Ext.grid.ColumnModel([ new Ext.grid.RowNumberer(),
sModel, {
header : '流水号',
dataIndex : 'id',// dataIndex对应后台数据key:value中的key
editor : new Ext.grid.GridEditor(new Ext.form.TextField({
allowBlank : false
}))
}, {
header : '客户名称',
dataIndex : 'name',// dataIndex对应后台数据key:value中的key
editor : new Ext.grid.GridEditor(new Ext.form.TextField({
allowBlank : false
}))
}, {
header : '客户性质',
dataIndex : 'ctype',// dataIndex对应后台数据key:value中的key
editor : new Ext.grid.GridEditor(new Ext.form.TextField({
allowBlank : false
}))
}, {
header : '客户等级',
dataIndex : 'cleave',// dataIndex对应后台数据key:value中的key
editor : new Ext.grid.GridEditor(new Ext.form.TextField({
allowBlank : false
}))
}, {
header : '电话一',
dataIndex : 'cnum',// dataIndex对应后台数据key:value中的key
editor : new Ext.grid.GridEditor(new Ext.form.TextField({
allowBlank : false
}))
}, {
header : '电子邮件',
dataIndex : 'cmail',// dataIndex对应后台数据key:value中的key
editor : new Ext.grid.GridEditor(new Ext.form.TextField({
allowBlank : false
}))
}, {
header : '联系人',
dataIndex : 'cman',// dataIndex对应后台数据key:value中的key
editor : new Ext.grid.GridEditor(new Ext.form.TextField({
allowBlank : false
}))
}, {
header : '联系记录',
dataIndex : 'cs',// dataIndex对应后台数据key:value中的key
editor : new Ext.grid.GridEditor(new Ext.form.TextField({
allowBlank : false
}))
} ]);
/* 定义测试数据 */
var data = [ // 多维数组
[ '1', '公司名', '客户', '重要客户', '010-88886666', 'abc@def.com',
'人名', '双方签订合同' ],
[ '2', '公司名', '客户', '重要客户', '010-88886666', 'abc@def.com',
'人名', '双方签订合同' ],
[ '3', '公司名', '客户', '重要客户', '010-88886666', 'abc@def.com',
'人名', '双方签订合同' ],
[ '4', '公司名', '客户', '重要客户', '010-88886666', 'abc@def.com',
'人名', '双方签订合同' ],
[ '5', '公司名', '客户', '重要客户', '010-88886666', 'abc@def.com',
'人名', '双方签订合同' ],
[ '6', '公司名', '客户', '重要客户', '010-88886666', 'abc@def.com',
'人名', '双方签订合同' ],
[ '7', '公司名', '客户', '重要客户', '010-88886666', 'abc@def.com',
'人名', '双方签订合同' ],
[ '8', '公司名', '客户', '重要客户', '010-88886666', 'abc@def.com',
'人名', '双方签订合同' ],
[ '9', '公司名', '客户', '重要客户', '010-88886666', 'abc@def.com',
'人名', '双方签订合同' ],
[ '10', '公司名', '客户', '重要客户', '010-88886666', 'abc@def.com',
'人名', '双方签订合同' ],
[ '11', '公司名', '客户', '重要客户', '010-88886666', 'abc@def.com',
'人名', '双方签订合同' ],
[ '12', '公司名', '客户', '重要客户', '010-88886666', 'abc@def.com',
'人名', '双方签订合同' ],
[ '13', '公司名', '客户', '重要客户', '010-88886666', 'abc@def.com',
'人名', '双方签订合同' ],
[ '14', '公司名', '客户', '重要客户', '010-88886666', 'abc@def.com',
'人名', '双方签订合同' ],
[ '15', '公司名', '客户', '重要客户', '010-88886666', 'abc@def.com',
'人名', '双方签订合同' ], ];
/* 数据源 */
var st = new Ext.data.Store({
proxy : new Ext.data.MemoryProxy(data),// 数据来源
reader : new Ext.data.ArrayReader({}, [ {
name : 'id'
}, {
name : 'name'
}, {
name : 'ctype'
}, {
name : 'cleave'
}, {
name : 'cnum'
}, {
name : 'cmail'
}, {
name : 'cman'
}, {
name : 'cs'
} ])
});
st.load();// 数据载入
/* 把formPanel&columnModel整合进GridPanel */
var gridPanel = new Ext.grid.GridPanel({
anchor : '0 65%',
renderTo : 'grid',// 要注意,若index中未创建id为grid的div,则会导致整个组件初始化失败
store : st,
cm : cModel,
sm : sModel,
tbar : new Ext.PagingToolbar({
store : st,
pageSize : 5,
displayInfo : true,
displayMsg : '显示第{0}条到{1}条记录,一共{2}条',
emptyMsg : '没有记录',
items : [ ' ', '-', {
text : '新建',
pressed : true
}, ' ', '-', {
text : '下次联系时间',
pressed : true
}, ' ', '-', {
text : '删除',
pressed : true
}, ' ', '-', {
text : '导出Excel',
pressed : true
}, ' ', '-' ]
}),
bbar : new Ext.PagingToolbar({
store : st,
pageSize : 5,
displayInfo : true,
displayMsg : '显示第{0}条到{1}条记录,一共{2}条',
emptyMsg : '没有记录',
items : [ ' ', '-', {
text : '新建',
pressed : true
}, ' ', '-', {
text : '下次联系时间',
pressed : true
}, ' ', '-', {
text : '删除',
pressed : true
}, ' ', '-', {
text : '导出Excel',
pressed : true
}, ' ', '-' ]
})
});
把sbuttonPanel&FormPanel&GridPanel整合进tabPanel。
使用与visit页面相同的动态加载方式,加载时通过搜索id判断内存中是否存在已打开的addCompany页面:
centerComponent.menu1_addCompany = function() {
var old_menu1_addCompany = centerPanel.findById("menu1_addCompany");
if (!old_menu1_addCompany) {
var data = [ [ '-1', '请选择' ], [ 'value1', '测试数据1' ],
[ 'value2', '测试数据2' ] ];
var areaStore = new Ext.data.SimpleStore({
fields : [ 'value', 'text' ],
proxy : new Ext.data.MemoryProxy(data)
});
var buttonPanelTop = new Ext.form.FormPanel({
anchor : '98%',
defaultType : 'button',
layout : 'column',
items : [ {
text : '保存',
columnWidth : .333
}, {
text : '保存并新建',
columnWidth : .333
}, {
text : '返回',
columnWidth : .333
} ]
});
var f = new Ext.Panel();
f.cl
var formPanel = new Ext.form.FormPanel({
anchor : '98%',
title : '客户--新建',
labelAlign : 'right',
labelWidth : 80,
autoScroll : true,
frame : true,
items : [ {
xtype : 'fieldset',
checkboxToggle : true,
title : '基本信息',
autoHeight : true,
items : [ {
layout : 'column',
items : [ {
columnWidth : .5,
layout : 'form',
defaults : {
anchor : '100%'
},
defaultType : 'textfield',
items : [ {
fieldLabel : '客户编码'
}, {
fieldLabel : '拼音码'
}, {
xtype : 'combo',
fieldLabel : '区域名称',
id : 'areaCombo',
name : 'areaCombo',
store : areaStore,
emptyText : '请选择',
displayField : 'text',
valueField : 'value',
mode : 'local',
triggerAction : 'all'// 相当于自己匹配开关,all代表即使有与输入框内容完全匹配的值也显示全部内容
}, {
fieldLabel : '所属行业'
}, {
fieldLabel : '传真'
}, {
xtype : 'combo',
fieldLabel : '省份',
id : 'sf',
name : 'sf',
store : areaStore,
emptyText : '请选择',
displayField : 'text',
valueField : 'value',
mode : 'local',
triggerAction : 'all'// 相当于自己匹配开关,all代表即使有与输入框内容完全匹配的值也显示全部内容
}
]
}, {
columnWidth : .5,
layout : 'form',
defaults : {
anchor : '100%'
},
defaultType : 'textfield',
items : [ {
fieldLabel : '客户名称'
}, {
xtype : 'combo',
fieldLabel : '客户等级',
id : 'khdj',
name : 'khdj',
store : areaStore,
emptyText : '请选择',
displayField : 'text',
valueField : 'value',
mode : 'local',
triggerAction : 'all'
}, {
xtype : 'combo',
fieldLabel : '客户来源',
id : 'khly',
name : 'khly',
store : areaStore,
emptyText : '请选择',
displayField : 'text',
valueField : 'value',
mode : 'local',
triggerAction : 'all'
}, {
xtype : 'combo',
fieldLabel : '公司规模',
id : 'gsgm',
name : 'gsgm',
store : areaStore,
emptyText : '请选择',
displayField : 'text',
valueField : 'value',
mode : 'local',
triggerAction : 'all'
}, {
fieldLabel : '邮政编码'
}, {
xtype : 'combo',
fieldLabel : '城市',
id : 'city',
name : 'city',
store : areaStore,
emptyText : '请选择',
displayField : 'text',
valueField : 'value',
mode : 'local',
triggerAction : 'all'
} ]
}
]
}, {
layout : 'form',
anchor : '100%',
xtype : 'textfield',
fieldLabel : '联系地址'
}, {
layout : 'column',
items : [ {
columnWidth : .5,
layout : 'form',
defaults : {
anchor : '100%'
},
defaultType : 'textfield',
items : [ {
fieldLabel : '电子邮件'
}, {
fieldLabel : '电话一'
}, {
fieldLabel : '手机'
}, {
fieldLabel : '下次联系时间'
} ]
}, {
columnWidth : .5,
layout : 'form',
defaults : {
anchor : '100%'
},
defaultType : 'textfield',
items : [ {
fieldLabel : '公司网址'
}, {
fieldLabel : '电话二'
}, {
fieldLabel : '客户需求'
}, {
xtype : 'combo',
fieldLabel : '客户性质',
id : 'khxz',
name : 'khxz',
emptyText : '请选择',
store : areaStore,
displayField : 'text',
valueField : 'value',
mode : 'local',
triggerAction : 'all'
} ]
} ]
}, {
layout : 'form',
anchor : '100%',
xtype : 'textarea',
fieldLabel : '备注'
}
]
}, {
xtype : 'fieldset',
checkboxToggle : true,
title : '企业信息',
autoHeight : true,
layout : 'column',
items : [ {
columnWidth : .5,
layout : 'form',
defaults : {
anchor : '100%'
},
defaultType : 'textfield',
items : [ {
xtype : 'combo',
fieldLabel : '经营范围',
id : 'jyfw',
name : 'jyfw',
store : areaStore,
emptyText : '请选择',
displayField : 'text',
valueField : 'value',
mode : 'local',
triggerAction : 'all'
}, {
fieldLabel : '企业性质'
}, {
fieldLabel : '注册资金'
}, {
fieldLabel : '银行账户'
} ]
}, {
columnWidth : .5,
layout : 'form',
defaults : {
anchor : '100%'
},
defaultType : 'textfield',
items : [ {
fieldLabel : '企业性质'
}, {
fieldLabel : '注册资金'
}, {
fieldLabel : '银行账户'
} ]
} ]
}, {
xtype : 'fieldset',
checkboxToggle : true,
title : '自定义信息',
autoHeight : true,
layout : 'column',
items : [ {
columnWidth : .5,
layout : 'form',
defaults : {
anchor : '100%'
},
defaultType : 'textfield',
items : [ {
fieldLabel : '客户需求1'
}, {
fieldLabel : '客户需求3'
}, {
xtype : 'combo',
fieldLabel : '自定选项1',
id : 'zdxy1',
name : 'zdxy1',
store : areaStore,
emptyText : '请选择',
displayField : 'text',
valueField : 'value',
mode : 'local',
triggerAction : 'all'
}, {
xtype : 'combo',
fieldLabel : '自定选项3',
id : 'zdxy3',
name : 'zdxy3',
store : areaStore,
emptyText : '请选择',
displayField : 'text',
valueField : 'value',
mode : 'local',
triggerAction : 'all'
}, {
xtype : 'datefield',
emptyText : '请选择',
format : 'Y-m-d',
disabledDays : [ 0, 6 ],
fieldLabel : '自定时间1'
} ]
}, {
columnWidth : .5,
layout : 'form',
defaults : {
anchor : '100%'
},
defaultType : 'textfield',
items : [ {
fieldLabel : '客户需求2'
}, {
fieldLabel : '客户需求4'
}, {
xtype : 'combo',
fieldLabel : '自定选项2',
id : 'zdxy2',
name : 'zdxy2',
store : areaStore,
emptyText : '请选择',
displayField : 'text',
valueField : 'value',
mode : 'local',
triggerAction : 'all'
}, {
xtype : 'combo',
fieldLabel : '自定选项4',
id : 'zdxy4',
name : 'zdxy4',
store : areaStore,
emptyText : '请选择',
displayField : 'text',
valueField : 'value',
mode : 'local',
triggerAction : 'all'
}, {
xtype : 'datefield',
emptyText : '请选择',
format : 'Y-m-d',
disabledDays : [ 0, 6 ],
fieldLabel : '自定时间2'
} ]
} ]
}, {
xtype : 'fieldset',
checkboxToggle : true,
title : '企业信息',
autoHeight : true,
layout : 'column',
items : [ {
columnWidth : .5,
layout : 'form',
defaults : {
anchor : '100%'
},
defaultType : 'textfield',
items : [ {
fieldLabel : '创建人'
}, {
fieldLabel : '修改人'
}, {
fieldLabel : '所属人'
} ]
}, {
columnWidth : .5,
layout : 'form',
defaults : {
anchor : '100%'
},
defaultType : 'textfield',
items : [ {
fieldLabel : '创建日期'
}, {
fieldLabel : '修改日期'
} ]
} ]
}
]
});
areaStore.on("load", function() {// 执行load方法时,执行函数……
var areaCombox = Ext.getCmp("areaCombo");
areaCombox.setValue(data[1][0]);// 打开时默认选中项“请选择”
});
areaStore.load();
var buttonPanelBottom = new Ext.form.FormPanel({
anchor : '98%',
defaultType : 'button',
layout : 'column',
items : [ {
text : '保存',
columnWidth : .333
}, {
text : '保存并新建',
columnWidth : .333
}, {
text : '返回',
columnWidth : .333
} ]
});
var new_menu1_addCompany = centerPanel.add({
id : '1-2',
title : '添加客户',
layout : 'anchor',
autoScroll : true,
closable : true,
items : [ buttonPanelTop, formPanel, buttonPanelBottom ]
});
centerPanel.activate(new_menu1_addCompany);
} else {
centerPanel.activate(old_menu1_addCompany);
}
}
centerComponent.menu1_addCompany();