接着上一節介紹控件拖放的設計。
通過前面的介紹知道,我們的區域類型的容器控件有三種: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 }
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 }
通過上面的拖放處理邏輯我們已經可以初步的設計表單模板了,下面附上4張圖片操作效果圖:
圖一

圖二

圖三

圖四

大家可以看看拖放前后四張圖的區別。
至此我們實現了設計器最重要的一步——拖拽控件,好吧這一節就先到這里。。。洗洗睡了。
