练习CRM搭建笔记——1、Browser Side

目标:使用ExtJS3.4搭建Web页面(20130130)(20130219修改)

1、了解ExtJS

1)简介

ExtJS是一种主要用于创建前端用户界面、与后台技术无关的、用JS实现的前端ajax框架,如果你不懂PS&CSS又想做出漂亮的界面,不妨试一试ExtJS。

优点:

有着丰富的控件库、丰富的工具包、清晰的语法结构,可以让一个有Swing编程经验的人很容易上手。

对AJAX进行了很好的封装,另你可以在不用知道XMLHttpRequest&ActionXObject的情况下,就写出一个AJAX程序。

缺点:

由于ExtJS过度的封装,导致其组件的灵活性下降,在改变外观样式的时候,也经常出现弄巧成拙的事情。

TIPS:

ExtJS是基于AJAX技术的,如果你对AJAX没有一个全面的了解,在深入学习时会走不少弯路。

2)选择哪个版本

目前最新版是4.1.3,官方承诺会给出一个向后兼容(ExtJS3)的方案,但ExtJS3到ExtJS4的变化巨大,所以,学习ExtJS4并且兼容两者需花费较大代价。

ExtJS4较ExtJS3结构更清晰,更便于开发&维护,新人可以直接学习ExtJS4,而这里则使用ExtJS3。

ExtJS3.4下载地址:http://www.sencha.com/products/extjs3/download/


2、如何在项目中使用ExtJS

1)导入必要的文件

使用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元素全部无效(还未被加载)。

2)从一个简单的应用入手

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"/>



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、页面整体布局

1)布局结构

titlePanel
newsPanelshowPanel
menuPanel

titlePanel——标题栏(置放说明、用户切换、注销按钮)、newsPanel——新闻栏(公告、新闻、通知)、menuPanel——菜单栏(主要功能按钮均至于此)、showPanel——显示栏(功能按钮反馈信息显示于此)

2)建立草案

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


5、各模块初步搭建(20130202)(20130220修改)

1)north——标题(titlePanel)

使用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之间的差异,才能更好的使用它们调整间距。

2)west——公告&菜单(嵌套了newsPanel&menuPanel的westPanel)

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
});

3)center——显示区(20130203)

显示区默认界面以九宫格为例,类似布局在设置时有一个技巧,就是使用分层式结构建立这一系列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;
	}
}


6、动态加载ExtJS组件

1)Eclipse中ExtJS语法提示插件安装

在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文件。

2)动态加载初步

用户每次打开主页可能只需要访问其中的个别页面,但当用户首次访问主页时,总会一次性将全部JS代码加载到本地,随着主页JS代码的增多,这无疑是一种资源浪费,因此这里需要做一点优化。使首次访问时只加载主页必要信息,分支页信息只有当用户点击menuPanel中的某个按钮时,才会进行进一步加载,然后显示在center区域。首先将center区域用于加载分支页的tabPanel提取为全局变量:

/*定义全局变量tabPanel*/
var tabPanel;
Ext.onReady(function(){
//...
<!--初始化tabPanel-->
tabPanel = new Ext.TabPanel({
	region:'center'//位置
	,activeTab: 0
	,items:[centerPanel]
});
//...
})

通过普通方式完成mainPanel的加载:

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);
	}
}
通过在html标签中添加onclick事件触发togo即可达到在tabPanel中打开分支页的效果。

3)动态加载完善

但以上方式仍然会在首次打开就引入所有js文件,势必造成资源浪费,所以采用需要时引入的方式,称为动态加载。

将它修改为动态加载方式,这里使用js提供的方式:

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);
}
然后,将原来在onclick事件中触发togo改为触发dynamicImportJs(js文件名),通过将原来的function togo函数名去掉,就可以达到动态加载的效果了。

为了避免每次点击按钮都会触发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();

4)MyEclipse初步优化:

(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 的大小之和不能超过你的电脑内存大小。


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。

8、mainPanel子窗口之新建用户

使用与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();

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值