📄 main.js
字号:
// get first selected node tree.getSelectedNode = function() {// var nodes = this.selModel.getSelectedNodes();// if (nodes[0]) { return nodes[0]; }// return null; return this.selModel.getSelectedNode(); }; // context menu to delete / duplicate... var contextMenu = new Ext.menu.Menu({items:[{ text : 'Delete this element', scope : this, handler : function(item) { this.removeNode(contextMenu.node); } },{ text : 'Add new element as child', scope : this, handler : function(item) { var node = this.appendConfig({}, contextMenu.node); this.treePanel.expandPath(node.getPath()); } },{ text : 'Add new element under', scope : this, handler : function(item) { var node = this.appendConfig({}, contextMenu.node.parentNode); this.treePanel.expandPath(node.getPath()); } },{ text : 'Duplicate this element', scope : this, handler : function(item) { var node = contextMenu.node; var newNode = cloneNode(node); if (node.isLast()) { node.parentNode.appendChild(newNode); } else { node.parentNode.insertBefore(newNode, node.nextSibling); } this.updateForm(false, node.parentNode); } }]}); tree.on('contextmenu', function(node, e) { e.preventDefault(); if (node != this.treePanel.root) { contextMenu.node = node; contextMenu.showAt(e.getXY()); } }, this); this.treePanel = tree; }, // layers used for selection higlight & resize initLayers : function() { this.layer = new Ext.Layer({cls:'outerLayer'}); this.layer.setOpacity(0.2); this.layer.on('click', this.hideLayers, this); this.layer.on('contextmenu', this.hideLayers, this); this.innerLayer = new Ext.Layer({cls:'innerLayer'}); this.innerLayer.setOpacity(0.3); this.innerLayer.createChild({cls:'text',html:'Resize me !'}); this.innerLayer.on('click', this.hideLayers, this); this.innerLayer.on('contextmenu', this.hideLayers, this); this.innerLayer.resizer = new Ext.Resizable(this.innerLayer, {dynamic:true}); this.innerLayer.resizer.on('resize', function(r,w,h) { var n = this.editPanel.currentNode; if (!n || !n.elConfig) { return false; } var s = n.fEl.el.getSize(); if (s.width != w) { n.elConfig.width = w; if (n.parentNode.elConfig.layout == 'column') { delete n.elConfig.columnWidth; } } if (s.height != h) { n.elConfig.height = h; } this.updateForm(true, n.parentNode); this.setCurrentNode(n); this.highlightElement(n.fEl.el); }, this); }, // customized property grid for attributes initEditPanel : function() { var fields = []; for (var i in Main.FIELDS) {fields.push([i,i]);} var newPropertyField = new Ext.form.ComboBox({ mode : 'local', valueField : 'value', displayField : 'name', store : new Ext.data.SimpleStore({ fields: ['value','name'], data : fields })}); newPropertyField.on('specialkey', function(tf,e) { var name = tf.getValue(); var ds = this.editPanel.store; if (e.getKey() == e.ENTER && name != '' && !ds.getById(name)) { var defaultVal = ""; if (this.attrType(name) == 'object') { defaultVal = "{}"; } if (this.attrType(name) == 'number') { defaultVal = 0; } ds.add(new Ext.grid.PropertyRecord({name:name, value:defaultVal}, name)); this.editPanel.startEditing(ds.getCount()-1, 1); tf.setValue(''); } }, this); var grid = new Ext.grid.PropertyGrid({ title : 'Parameters', height : 200, split : true, region : 'south', source : {}, bbar : ['Add :', newPropertyField ], customEditors : Main.getCustomEditors(), newPropertyField : newPropertyField }); var valueRenderer = function(value, p, r) { if (typeof value == 'boolean') { p.css = (value ? "typeBoolTrue" : "typeBoolFalse"); return (value ? "True" : "False"); } else if (this.attrType(r.id) == 'object') { p.css = "typeObject"; return value; } else { return value; } }.createDelegate(this); var propertyRenderer = function(value, p) { var t = Main.FIELDS[value]; qtip = (t ? t.desc : ''); p.attr = 'qtip="' + qtip.replace(/"/g,'"') + '"'; return value; }; grid.colModel.getRenderer = function(col){ return (col == 0 ? propertyRenderer : valueRenderer); }; var contextMenu = new Ext.menu.Menu({items:[{ id : 'MenuPropertyDelete', text : 'Delete this property', scope : this, handler : function(item,e) { var ds = grid.store; delete grid.getSource()[item.record.id]; ds.remove(item.record); delete item.record; this.updateNode(grid.currentNode); var node = grid.currentNode.parentNode || grid.currentNode; this.updateForm.defer(200, this, [false, node]); } }]}); // property grid contextMenu grid.on('rowcontextmenu', function(g, idx, e) { e.stopEvent(); var r = this.store.getAt(idx); if (!r) { return false; } var i = contextMenu.items.get('MenuPropertyDelete'); i.setText('Delete property "' + r.id + '"'); i.record = r; contextMenu.showAt(e.getXY()); }, grid); // update node text & id grid.store.on('update', function(s,r,t) { if (t != Ext.data.Record.EDIT) { return; } var node = grid.currentNode; this.updateNode(grid.currentNode); this.updateForm(false, node.parentNode || node); }, this, {buffer:100}); this.editPanel = grid; }, // the main form panel, containing builded form initFormPanel : function() { var form = new Ext.form.FormPanel({ autoScroll : true, region : "center", items:[{}] }); form.currentNode = null; this.formPanel = form; }, // hide select layers (e is click event) hideLayers : function(e) { if (e) { e.preventDefault(); } this.layer.hide(); this.innerLayer.hide(); }, // set current editing node setCurrentNode : function(node) { var p = this.editPanel; p.enable(); if (!node || !node.elConfig) { p.currentNode = null; p.setSource({}); p.disable(); } else { config = node.elConfig; for (k in config) { if (this.attrType(k) == 'object' && typeof config[k] == 'object') { try { var ec = Ext.encode(config[k]); config[k] = ec; } catch(e) {} } } p.setSource(config); p.currentNode = node; if (node.fEl == this.formPanel) { p.disable(); } } }, // update node text & id (if necessary) updateNode : function(node) { if (!node) { return; } node.setText(this.configToText(node.elConfig)); if (node.elConfig.id && node.elConfig.id != node.id) {// node.getOwnerTree().unregisterNode(node); node.id = node.elConfig.id;// node.getOwnerTree().registerNode(node); } }, // update the form at the specified node // if force is not true, only update if autoUpdate is true updateForm : function(force, node) { node = node || this.treePanel.root; var updateTime = (node == this.treePanel.root); var time = null; // search container to update, upwards node = this.searchForContainerToUpdate(node); if (force === true || this.autoUpdate) { var config = this.getTreeConfig(node, true); time = this.setFormConfig(config, node.fEl); this.updateTreeEls(node.fEl); this.hideLayers(); // save into cookies this.cookies.set('formbuilderconfig', this.getTreeConfig()); } if (time && updateTime) { Ext.ComponentMgr.get('RenderingTimeBtn').setText( 'Rendering time : <i>' + time + 'ms</i>'); } }, // load from cookies if present loadConfigFromCookies : function() { var c = this.cookies.get('formbuilderconfig'); if (c) { this.setConfig(c); return true; } else { return false; } }, // search upware for a container to update searchForContainerToUpdate : function(node) { // search for a parent with border or column layout var found = null; var root = this.treePanel.root; var n = node; while (n != root) { if (n && n.elConfig && (n.elConfig.layout == 'border' || n.elConfig.layout == 'column')) { found = n; } n = n.parentNode; } if (found !== null) { return found.parentNode; } // no column parent, search for first container with items n = node; while (n != root) { if (!n.fEl || !n.fEl.items) { n = n.parentNode; } else { break; } } return n; }, // hilight an element highlightElement : function(el) { if (el == this.formPanel.el) { return; } if (el) { var elParent = el.findParent('.x-form-element', 5, true); if (elParent) { this.layer.setBox(elParent.getBox()); this.layer.show(); } else { this.layer.hide(); } this.innerLayer.setBox(el.getBox()); this.innerLayer.show(); } }, // get the tree config at the specified node getTreeConfig : function(node, addNodeInfos) { if (!node) { node = this.treePanel.root; } var config = Ext.apply({}, node.elConfig); if (!config.id && addNodeInfos) { config.id = node.id; } for (k in config) { if (this.attrType(k) == 'object') { try { config[k] = Ext.decode(config[k]); } catch(e) {} } } if (addNodeInfos) { config._node = node; } var items = []; node.eachChild(function(n) { items.push(this.getTreeConfig(n, addNodeInfos)); }, this); if (items.length > 0) { config.items = items; } else { delete config.items; } return config; }, // update node.fEl._node associations updateTreeEls : function(el) { if (!el) { el = this.formPanel; } if (el._node) { el._node.fEl = el; } if (!el.items) { return; } try { el.items.each(function(i) { this.updateTreeEls(i); }, this); } catch (e) {} }, // obsolete, read a form (with initialConfig properties) loadConfigFromForm : function(el) { if (!el) { el = this.formPanel; } var node = el._node || this.treePanel.root; while(node.firstChild){ node.removeChild(node.firstChild); } if (!el.items) { return; } el.items.each(function(i) { var newNode = new Ext.tree.TreeNode({ text : this.configToText(i.initialConfig), id : i.id }); newNode.fEl = i; newNode.elConfig = i.initialConfig; i._node = newNode; node.appendChild(newNode); this.loadConfigFromForm(i); }, this); }, // node text created from config of el configToText : function(c) { var txt = []; c = c || {}; if (c.xtype) { txt.push(c.xtype); } if (c.fieldLabel) { txt.push('[' + c.fieldLabel + ']'); } if (c.boxLabel) { txt.push('[' + c.boxLabel + ']'); } if (c.layout) { txt.push('<i>' + c.layout + '</i>'); } if (c.title) { txt.push('<b>' + c.title + '</b>'); } if (c.text) { txt.push('<b>' + c.text + '</b>'); } return (txt.length == 0 ? "Element" : txt.join(" ")); }, // return type of attribute attrType : function(name) { if (!Main.FIELDS[name]) { return 'unknown'; } return Main.FIELDS[name].type; }, // add a preset (textfield, ...) addPreset : function(b) { var c = {}; switch(b.value) { case 'fieldset': c.xtype = 'fieldset'; c.title = 'Field Set'; c.autoHeight = true; break; case 'textfield': c.xtype = 'textfield'; c.fieldLabel = 'Text Field'; c.name = ''; break; case 'textarea': c.xtype = 'textarea'; c.fieldLabel = 'Text Area'; c.name = ''; break; case 'combo': c.xtype = 'combo'; c.fieldLabel = 'Combo'; c.name = ''; break; case 'radio': c.xtype = 'radio'; c.boxLabel = 'Radio'; c.name = ''; c.checked = false; break; case 'checkbox': c.xtype = 'checkbox'; c.boxLabel = 'Check'; c.name = ''; c.checked = false; break; case 'column': c.layout = 'column'; c.items = [ {columnWidth:0.5, layout:'form'}, {columnWidth:0.5, layout:'form'} ]; } var node = this.appendConfig(c);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -