接着上一节介绍控件拖放的设计。

  通过前面的介绍知道,我们的区域类型的容器控件有三种:Card、Table、Mixed。

  Card 可以支持几乎所有的常用控件,包括:文本TextField、多文本TextArea、数字NumberField、金额NumberField、日期DateField、下拉树NetDropDown、按钮Button、复选框CheckBox、单选框Radio;Table可以支持的常用控件比Card稍微少一点,它不支持button类型的控件以及多文本TextArea控件;Mixed不支持常用控件,它只支持我们的容器控件类型,就是它本身和Card和Table,它的作用就是一个嵌套作用,让我们可以生成复杂的表单模板。三个类型的容器控件支持的子控件各不相同,我们先定义一个公共的Object对象来存储一些容器相关的信息,方便我们后面处理控件拖放事件的时候做一些判断使用。

1  //公共配置信息
2     ftConfig = {
3         isDraging: false, //表示是否正在拖放控件
4         dragXY: { x: 0, y: 0 }, //拖动控件时候记录坐标
5         panelType: \'Card Table Mixed\',//表示我们容器控件类型的字符串
6         tableRejectType: \'Button TextArea CheckBox Radio\'//表格区域不接受的控件类型字符串     
7     };

然后就是我们具体的拖放处理代码逻辑。上一节我们介绍了使用一个Droptarget来为我们的画布控件添加了可以接收拖动、释放的功能,在Droptarget里面我们为它定义了两个事件1. notifyEnter事件,当我们的鼠标拖动控件到画布区域上面后就设置配置信息的isDraging=true;

2. notifyDrop事件,当我们在画布上释放拖动的控件后就会触发该事件,通过该事件我们获取到拖放的控件信息,并进行相关的拖放处理。

 1 ftConfig = {
 2         regNum: 1,//区域序号
 3         ctrolNum: 1,//控件序号
 4         isDraging: false, //表示是否正在拖放控件
 5         dragXY: { x: 0, y: 0 }, //拖动控件时候记录坐标
 6         panelType: \'card table mixed\',//表示我们容器控件类型的字符串
 7         tableRejectType: \'button textarea checkbox radio\'//表格区域不接受的控件类型字符串     
 8     };
 9     function notifyDrop(dd, e, data) {
10         var c, d = data.records[0].data, dropId,
11             type = d.type.toLocaleLowerCase();
12         ftConfig.isDraging = false;
13         switch (type) {
14             case \'card\':
15                 c = {
16                     id: \'region\' + ftConfig.regNum,
17                     title: \'卡片区域\' + ftConfig.regNum,
18                     type: type,
19                     cols: 4, //默认为卡片区域设置4列
20                     minHeight: 100,
21                     border: true,
22                     collapsible: true,
23                     bodyPadding: \'5 20px 5 0\',
24                     margin: \'0px 0px 5px 0\',
25                     layout: \'column\',
26                     closable: true,
27                     defaults: { labelAlign: \'right\', labelWidth: 100, margin: \'3,0\' }
28                 }; break;
29             case \'table\':
30                 c = {
31                     id: \'region\' + ftConfig.regNum,
32                     title: \'表格区域\' + ftConfig.regNum,
33                     type: type,
34                     xtype: \'grid\',
35                     height: 200,
36                     margin: \'0px 0px 5px 0\',
37                     collapsible: true,
38                     autoScroll: true,
39                     closable: true,
40                     columns: {}
41                 }; break;
42             case \'mixed\':
43                 c = {
44                     id: \'region\' + ftConfig.regNum,
45                     title: \'混合区域\' + ftConfig.regNum,
46                     type: type,
47                     border: true,
48                     collapsible: true,
49                     closable: true,
50                     minHeight: 100,
51                     bodyPadding: \'10px\',
52                     margin: \'0px 0px 5px 0\'
53                 }; break;
54             default:
55                 c = {
56                     id: newID(\'ct\'),
57                     index: ftConfig.ctrolNum,
58                     type: type,
59                     xtype: type,
60                     fieldLabel: \'控件\'
61                 }; break;
62         }
63         dropId = e.target.id.split(\'-\')[0];
64         dropId = dropId === \'gridview\' ? e.target.parentNode.id.split(\'-\')[0] : dropId;
65         return addRegionControl(dropId, c);
66     }

notifyDrop function

 

 1 //添加控件到区域
 2     function addRegionControl(pid, c) {
 3         var p = findRegion(pid);
 4         if (!p) return false;
 5         if (ftConfig.panelType.indexOf(c.type) >= 0 && p.type !== \'mixed\') {//如果是区域控件就只能放在mixed类型panel里面;  
 6             p = p.findParentByType(\'panel\');
 7             if (p) {
 8                 return addRegionControl(p.id, c);
 9             }
10             return false;
11         }
12         else if (ftConfig.panelType.indexOf(c.type) < 0) {
13             if (p.type === \'mixed\') {//如果是其他控件就不能放到mixed类型panel里面; 
14                 return false;
15             }
16             else if (p.type === \'table\') {//如果是控件添加到表格区域的处理
17                 var index = p.columns.length + 1;
18                 p.addColumn({ text: \'\' + index, width: 120, cls: "center", align: \'left\' });
19             }
20             else {//(p.type === \'card\') 如果是添加控件到卡片区域的处理 
21                 c.columnWidth = 1 / p.cols;
22                 p.add(c);
23             }
24         }
25         else {
26             p.add(c);
27         }
28         ftConfig.ptype.indexOf(c.type) >= 0 ? ftConfig.regNum++ : ftConfig.ctrolNum++;
29         return true;
30     }
31     //根据Id查找区域的可用控件或者父级控件
32     function findRegion(id) {
33         if (!id || !(c = Ext.getCmp(id)))
34             return null;
35         if (c.type && ftConfig.panelType.indexOf(c.type) >= 0) {
36             return c;
37         }
38         else {
39             var p = c.findParentByType(\'panel\');
40             if (p) {
41                 return findRegion(p.id);
42             }
43             return null;
44         }
45     }

add control process

通过上面的拖放处理逻辑我们已经可以初步的设计表单模板了,下面附上4张图片操作效果图:

图一

图二

图三

图四

大家可以看看拖放前后四张图的区别。

至此我们实现了设计器最重要的一步——拖拽控件,好吧这一节就先到这里。。。洗洗睡了。

版权声明:本文为rpoplar原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/rpoplar/p/4249298.html