2 * The code that manages the tree...
4 * used to be inside the Interface, but has proved to be to difficult to manage.
6 * In principle, simple event handling code is put in the interface, and any hard
7 * lifting is done in nice files...
9 * It might be better to just extend 'tree', and use the extended class..
18 appendNode : function(parent, inConfig, point) {
21 var tree = Pman.Tab.BuilderTree.tree;
23 if (typeof(inConfig) == 'undefined') {
27 if (typeof(inConfig) !== 'undefined' && inConfig.items) { // loading!
28 items = inConfig.items;
29 delete inConfig.items;
32 var config = this.cloneConfig(inConfig);
34 var hidden = config['builder.hidden'] || false;
40 var newNode = new Roo.tree.TreeNode({
41 text: this.configToText(config)
44 newNode.elConfig = config;
46 //if (markUndo === true) {
47 //Pman.Tab.Builder.markUndo("Add " + newNode.text);
49 // appends to our tree...
50 console.log("APPEND NODE: " + point);
53 parent.parentNode.insertBefore(newNode, parent);
54 parent.parentNode.expand(true);
57 // if it's the last node.. then we append..
58 var ix = parent.parentNode.indexOf(parent) + 1;
59 if (parent.parentNode.childNodes.length == ix) {
60 parent.parentNode.appendChild(newNode);
63 var bef = parent.parentNode.childNodes[ix];
64 parent.parentNode.insertBefore(newNode, bef);
65 parent.parentNode.expand(true);
70 parent.appendChild(newNode);
75 newNode.ui.ctNode.style.display = hidden ? 'none' : '';
78 Roo.each(items, function(i) {
79 this.appendNode(newNode, i);
86 -- panels with panes...
87 if (items && items.length) {
88 for (var i = 0; i < items.length; i++) {
89 this.appendConfig(items[i], newNode, false);
92 if (opts.doUpdate !== false) {
93 this.updateForm(false, newNode);
100 clearAll : function() {
101 var tree = Pman.Tab.BuilderTree.tree;
104 if (rt.childNodes.length) {
105 rt.removeChild(rt.childNodes[0]);
108 tree.root.elConfig = Roo.apply({ }, this.defaultElConfig());
109 //var btop = Pman.Tab.BuilderTop;
110 //if (btop.modsel && btop.modsel.lastData) {
111 // this.tree.root.elConfig.app = btop.modsel.lastData.app;
114 this.setCurrentNode(tree.root,true);
117 cloneConfig : function(config) {
118 if (!config) { return null; }
121 for (var i in config) {
122 if (i.match(/^builder\./)) {
125 if (typeof config[i] == 'object') {
126 newConfig[i] = this.cloneConfig(config[i]);
127 } else if (typeof config[i] != 'function') { // should this happen?
128 newConfig[i] = config[i];
133 configToText : function(c) {
137 var sr = (typeof(c['+buildershow']) != 'undefined') && !c['+buildershow'] ? true : false;
138 if (sr) txt.push('<s>');
139 if (typeof(c['*prop']) != 'undefined') { txt.push(c['*prop']+ ':'); }
140 if (c.xtype) { txt.push(c.xtype); }
141 if (c.fieldLabel) { txt.push('[' + c.fieldLabel + ']'); }
142 if (c.boxLabel) { txt.push('[' + c.boxLabel + ']'); }
145 if (c.layout) { txt.push('<i>' + c.layout + '</i>'); }
146 if (c.title) { txt.push('<b>' + c.title + '</b>'); }
147 if (c.header) { txt.push('<b>' + c.header + '</b>'); }
148 if (c.legend) { txt.push('<b>' + c.legend + '</b>'); }
149 if (c.text) { txt.push('<b>' + c.text + '</b>'); }
150 if (c.name) { txt.push('<b>' + c.name+ '</b>'); }
151 if (c.region) { txt.push('<i>(' + c.region + ')</i>'); }
152 if (c.dataIndex) { txt.push('[' + c.dataIndex+ ']'); }
153 if (sr) txt.push('</s>');
154 return (txt.length == 0 ? "Element" : txt.join(" "));
158 currentNodeType : function() {
159 return this.nodeXtype(this.currentNode);
162 defaultElConfig : function() {
171 name : 'Module Name',
176 replaceCurrentNode : function(cfg)
178 var tree = Pman.Tab.BuilderTree.tree;
180 if (this.currentNode == tree.root) {
183 var pn = this.currentNode.parentNode;
185 var ix = pn.indexOf(this.currentNode);
186 pn.removeChild(this.currentNode);
188 if (!pn.childNodes.length) {
189 this.appendNode(pn, cfg, 'append')
194 this.appendNode(pn.childNodes[0], cfg, 'above');
199 this.appendNode(pn.childNodes[ix-1], cfg, 'below');
205 collapseToggle : function()
207 var tree = Pman.Tab.BuilderTree.tree;
209 if (this.currentNode == tree.root) {
212 var cfg = this.currentNode.elConfig;
213 // things that can not be deleted...
214 var hidden = cfg['builder.hidden'] || 0;
216 delete cfg['builder.hidden'];
218 cfg['builder.hidden'] = 1;
222 this.currentNode.ui.ctNode.style.display = !hidden ? 'none' : '';
225 //this.setCurrentNode(pn.childNodes.length ? pn.childNodes[ix] : pn ,true);
232 deleteCurrent : function()
235 var tree = Pman.Tab.BuilderTree.tree;
237 if (this.currentNode == tree.root) {
240 var cfg = this.currentNode.elConfig;
241 // things that can not be deleted...
244 var pn = this.currentNode.parentNode;
246 // work out if we make the next or parent the 'current node'
247 var ix = pn.indexOf(this.currentNode);
249 pn.removeChild(this.currentNode);
250 if (pn.childNodes.length) {
251 ix = Math.min(pn.childNodes.length-1, ix);
253 this.setCurrentNode(pn.childNodes.length ? pn.childNodes[ix] : pn ,true);
256 dupeNode : function(node)
258 var cfg = this.cloneConfig(node.elConfig);
260 var newNode = new Roo.tree.TreeNode(
263 text: this.configToText(cfg)
266 newNode.elConfig = cfg;
267 node.eachChild(function(n) {
268 newNode.appendChild(this.dupeNode(n));
274 loadBJS : function(module, part)
278 url : baseURL + '/Roo/Builder_part.php',
283 success : function(res)
288 if (!res.data.json.length) {
289 var cfg = _t.defaultElConfig();
290 cfg.name = Pman.Tab.BuilderTop.filesel.lastData.name;
291 cfg.part = Pman.Tab.BuilderTop.filesel.lastData.name;
298 _t.loadTree(JSON.parse(res.data.json));
308 loadTree : function(o)
310 var tree = Pman.Tab.BuilderTree.tree;
312 tree.root.elConfig = o;
313 if (typeof(o.xtype) == 'undefined') {
316 tree.root.setText(this.configToText(tree.root.elConfig));
317 this.appendNode(tree.root, o.items[0]);
318 tree.root.expand(true);
319 Pman.Tab.BuilderView.panel.redraw();
320 this.setCurrentNode(tree.root,true);
322 nodeXtype : function(n)
324 var tree = Pman.Tab.BuilderTree.tree;
325 if (!n || !n.elConfig) {return ''; }
326 var xt = n.elConfig.xtype || '';
327 var xns= n.elConfig['|xns'] || '';
328 xns += xns.length ? '.' : '';
331 setCurrentNode : function(node,select)
333 var tree = Pman.Tab.BuilderTree.tree;
335 this.currentNode = node || tree.root;
337 //Pman.Tab.BuilderView.highlightElement(this.currentNode);
339 var p = Pman.Tab.BuilderProps.grid;
340 if (p) { //may not be ready yet..
341 p.setCurrrentNode(this.currentNode);
345 this.currentNode.setText(this.configToText(this.currentNode.elConfig));
347 if (select) { //&& node !== this.tree.root) {
348 if (this.currentNode !== tree.root) {
349 this.currentNode.ensureVisible();
351 this.currentNode.expand(false,false);
352 this.currentNode.select();
355 Pman.Tab.BuilderPalette.grid.getSelectionModel().clearSelections();
356 Pman.Tab.BuilderPalette.grid.view.refresh();
362 var tree = Pman.Tab.BuilderTree.tree;
363 return this.toJS(tree.root);
366 var ret = this.cloneConfig(n.elConfig);
367 if (n.childNodes.length) {
369 n.eachChild(function(cn) {
370 ret.items.push(_this.toJS(cn));
383 handleDropNode : function (e)
385 // nodedragover handles the allow/disallow..
389 target - The node being targeted for the drop
390 data - The drag data from the drag source
391 point - The point of the drop - append, above or below
392 source - The drag source
393 rawEvent - Raw mouse event
394 dropNode - Drop node(s) provided by the source OR you can supply node(s) to be inserted by setting them on this object.
395 cancel - Set this to true to cancel the drop.
399 var np = e.point == 'append' ? e.target : e.target.parentNode ; // new parent
401 if (!e.tree || !e.dropNode) {
404 var data = e.source.dragData.selections[0].data;
406 var xar = data.name.split('.');
410 '|xns' : xar.join('.')
413 if (this.dragProp.length > 1) {
414 cfg['*prop'] = this.dragProp;
416 // at this point it should of a set of options...
417 var cls = cfg['|xns'] + '.' + cfg['xtype'];
420 if (typeof(Pman.Builder.Wizard[cls]) != 'undefined') {
421 Pman.Dialog.BuilderAdd.show( cfg , function(fdata ) {
423 _t.appendNode(e.target, fdata , e.point);
424 Pman.Tab.BuilderView.panel.redraw();
429 this.appendNode(e.target, cfg, e.point);
430 Pman.Tab.BuilderView.panel.redraw();
432 return false; // fixme drop of elements from palete..
435 // always drop onto own parent
436 if (np == e.dropNode.parentNode) {
437 if (e.rawEvent.ctrlKey) {
438 e.dropNode = this.dupeNode(e.dropNode);
442 // can append has to use palete...
443 // this code should be in nodedragover.
445 var cfg = this.toJS(e.dropNode);
446 this.appendNode(e.target, cfg, e.point);
448 Roo.log('no e.dropNode?');
449 return false; // do not allow movement..
451 if (_this.canAppend(np, e.dropNode.elConfig)) {
452 if (e.rawEvent.ctrlKey) {
453 e.dropNode = _this.dupeNode(e.dropNode);
455 if (np.elConfig.xtype == 'GridEditor') {
456 e.dropNode.elConfig['*prop'] = 'field';
462 Roo.log('can not drop ' + e.dropNode.elConfig.xtype + ' ontop of ' + np.elConfig.xtype);
470 handleDragOver : function(e)
472 Roo.log('nodedragover');
475 // if we have within the same tree:
476 // dropNode (the node being dragged !!important!!)
477 // point: below, append
481 // grid = the grid...
482 // source.dragData.selections[..]
485 // we can only check parents... (we in theory can check dupe properties.. but let's ignore that for the time being.)
490 // drag from palete..
491 if (!e.source.dragData.selections.length) {
495 var drop_rec = e.source.dragData.selections[0];
496 var drop_xtype = drop_rec.data.name;
497 var ok_parents = drop_rec.json.parents;
499 Roo.log("TEST PARENTS: " + ok_parents.join(', '));
500 var new_parent = this.nodeXtype((e.point == 'append') ? e.target : e.target.parentNode);
501 Roo.log("NEW PARENT: " + e.point + " = " + new_parent);
503 // see if the new_parent is actually in the list of ok_parents
507 Roo.each(ok_parents, function(n) {
508 Roo.log("compare "+n+" ? " + new_parent);
509 if (n == new_parent || n.split(':').shift() == new_parent) {
510 Roo.log("got match!");
512 _t.dragProp = (n == new_parent) ? '' : n.split(':').pop();
518 // done all the checks...
524 // have a drop node - hence comming from the same object..
525 var drop_xtype = this.nodeXtype(e.dropNode);
526 // currently we can not determine validity..
535 // first see if first element has a name.. - we can not save otherwise..
536 var t = Pman.Tab.BuilderTree.tree;
537 if (!t.root.elConfig.name.length) {
538 Roo.MessageBox.alert("Error", "No name set for form");
542 var sid = (typeof(sid) == 'undefined') ?
543 (Pman.Tab.BuilderTop.filesel.lastData ? Pman.Tab.BuilderTop.filesel.lastData.id : 0) : sid;
546 var js = this.toJS();
547 var render = new Pman.Builder.JsRender(js);
550 // console.log(json);
552 // check the select box to see if that has been set... - save it with that id..
557 url: baseURL + '/Roo/Builder_part.php',
560 json : Roo.encode(js, null, 4),
561 jsource : render.toSource(),
563 module_id : Pman.Tab.BuilderTop.modsel.getValue(),
566 success : function(data) {
570 // _this.filesel.setFromData(data);
572 // cb.call(_this,data);
574 // _this.postCode(data);