/**
* @class Roo.dd.DragDrop
+ * @extends Roo.util.Observable
* Defines the interface and base operation of items that that can be
* dragged or can be drop targets. It was designed to be extended, overriding
* the event handlers for startDrag, onDrag, onDragOver and onDragOut.
if (id) {
this.init(id, sGroup, config);
}
+
};
-Roo.dd.DragDrop.prototype = {
+Roo.extend(Roo.dd.DragDrop, Roo.util.Observable , {
/**
* The id of the element associated with this object. This is what we
return ("DragDrop " + this.id);
}
-};
+});
})();
/*
if (id) {
this.initTarget(id, sGroup, config);
}
+ if (config.listeners || config.events) {
+ Roo.dd.DragDrop.superclass.constructor.call(this, {
+ listeners : config.listeners || {},
+ events : config.events || {}
+ });
+ }
};
// Roo.dd.DDTarget.prototype = new Roo.dd.DragDrop();
Roo.dd.DropTarget = function(el, config){
this.el = Roo.get(el);
+ var listeners = false; ;
+ if (config && config.listeners) {
+ listeners= config.listeners;
+ delete config.listeners;
+ }
Roo.apply(this, config);
if(this.containerScroll){
Roo.dd.ScrollManager.register(this.el);
}
-
- Roo.dd.DropTarget.superclass.constructor.call(this, this.el.dom, this.ddGroup || this.group,
- {isTarget: true});
+ this.addEvents( {
+ /**
+ * @scope Roo.dd.DropTarget
+ */
+
+ /**
+ * @event enter
+ * The function a {@link Roo.dd.DragSource} calls once to notify this drop target that the source is now over the
+ * target. This default implementation adds the CSS class specified by overClass (if any) to the drop element
+ * and returns the dropAllowed config value. This method should be overridden if drop validation is required.
+ *
+ * IMPORTANT : it should set this.overClass and this.dropAllowed
+ *
+ * @param {Roo.dd.DragSource} source The drag source that was dragged over this drop target
+ * @param {Event} e The event
+ * @param {Object} data An object containing arbitrary data supplied by the drag source
+ */
+ "enter" : true,
+
+ /**
+ * @event over
+ * The function a {@link Roo.dd.DragSource} calls continuously while it is being dragged over the target.
+ * This method will be called on every mouse movement while the drag source is over the drop target.
+ * This default implementation simply returns the dropAllowed config value.
+ *
+ * IMPORTANT : it should set this.dropAllowed
+ *
+ * @param {Roo.dd.DragSource} source The drag source that was dragged over this drop target
+ * @param {Event} e The event
+ * @param {Object} data An object containing arbitrary data supplied by the drag source
+
+ */
+ "over" : true,
+ /**
+ * @event out
+ * The function a {@link Roo.dd.DragSource} calls once to notify this drop target that the source has been dragged
+ * out of the target without dropping. This default implementation simply removes the CSS class specified by
+ * overClass (if any) from the drop element.
+ * @param {Roo.dd.DragSource} source The drag source that was dragged over this drop target
+ * @param {Event} e The event
+ * @param {Object} data An object containing arbitrary data supplied by the drag source
+ */
+ "out" : true,
+
+ /**
+ * @event drop
+ * The function a {@link Roo.dd.DragSource} calls once to notify this drop target that the dragged item has
+ * been dropped on it. This method has no default implementation and returns false, so you must provide an
+ * implementation that does something to process the drop event and returns true so that the drag source's
+ * repair action does not run.
+ *
+ * IMPORTANT : it should set this.success
+ *
+ * @param {Roo.dd.DragSource} source The drag source that was dragged over this drop target
+ * @param {Event} e The event
+ * @param {Object} data An object containing arbitrary data supplied by the drag source
+ */
+ "drop" : true
+ });
+
+
+ Roo.dd.DropTarget.superclass.constructor.call( this,
+ this.el.dom,
+ this.ddGroup || this.group,
+ {
+ isTarget: true,
+ listeners : listeners || {}
+
+
+ }
+ );
};
* @cfg {String} overClass
* The CSS class applied to the drop target element while the drag source is over it (defaults to "").
*/
+ /**
+ * @cfg {String} ddGroup
+ * The drag drop group to handle drop events for
+ */
+
/**
* @cfg {String} dropAllowed
* The CSS class returned to the drag source when drop is allowed (defaults to "x-dd-drop-ok").
* The CSS class returned to the drag source when drop is not allowed (defaults to "x-dd-drop-nodrop").
*/
dropNotAllowed : "x-dd-drop-nodrop",
-
+ /**
+ * @cfg {boolean} success
+ * set this after drop listener..
+ */
+ success : false,
+ /**
+ * @cfg {boolean|String} valid true/false or string (ok-add/ok-sub/ok/nodrop)
+ * if the drop point is valid for over/enter..
+ */
+ valid : false,
// private
isTarget : true,
// private
isNotifyTarget : true,
-
+
/**
- * The function a {@link Roo.dd.DragSource} calls once to notify this drop target that the source is now over the
- * target. This default implementation adds the CSS class specified by overClass (if any) to the drop element
- * and returns the dropAllowed config value. This method should be overridden if drop validation is required.
- * @param {Roo.dd.DragSource} source The drag source that was dragged over this drop target
- * @param {Event} e The event
- * @param {Object} data An object containing arbitrary data supplied by the drag source
- * @return {String} status The CSS class that communicates the drop status back to the source so that the
- * underlying {@link Roo.dd.StatusProxy} can be updated
+ * @hide
*/
- notifyEnter : function(dd, e, data){
+ notifyEnter : function(dd, e, data)
+ {
+ this.valid = true;
+ this.fireEvent('enter', dd, e, data);
if(this.overClass){
this.el.addClass(this.overClass);
}
- return this.dropAllowed;
+ return typeof(this.valid) == 'string' ? 'x-dd-drop-' + this.valid : (
+ this.valid ? this.dropAllowed : this.dropNotAllowed
+ );
},
/**
- * The function a {@link Roo.dd.DragSource} calls continuously while it is being dragged over the target.
- * This method will be called on every mouse movement while the drag source is over the drop target.
- * This default implementation simply returns the dropAllowed config value.
- * @param {Roo.dd.DragSource} source The drag source that was dragged over this drop target
- * @param {Event} e The event
- * @param {Object} data An object containing arbitrary data supplied by the drag source
- * @return {String} status The CSS class that communicates the drop status back to the source so that the
- * underlying {@link Roo.dd.StatusProxy} can be updated
+ * @hide
*/
- notifyOver : function(dd, e, data){
- return this.dropAllowed;
+ notifyOver : function(dd, e, data)
+ {
+ this.valid = true;
+ this.fireEvent('over', dd, e, data);
+ return typeof(this.valid) == 'string' ? 'x-dd-drop-' + this.valid : (
+ this.valid ? this.dropAllowed : this.dropNotAllowed
+ );
},
/**
- * The function a {@link Roo.dd.DragSource} calls once to notify this drop target that the source has been dragged
- * out of the target without dropping. This default implementation simply removes the CSS class specified by
- * overClass (if any) from the drop element.
- * @param {Roo.dd.DragSource} source The drag source that was dragged over this drop target
- * @param {Event} e The event
- * @param {Object} data An object containing arbitrary data supplied by the drag source
+ * @hide
*/
- notifyOut : function(dd, e, data){
+ notifyOut : function(dd, e, data)
+ {
+ this.fireEvent('out', dd, e, data);
if(this.overClass){
this.el.removeClass(this.overClass);
}
},
/**
- * The function a {@link Roo.dd.DragSource} calls once to notify this drop target that the dragged item has
- * been dropped on it. This method has no default implementation and returns false, so you must provide an
- * implementation that does something to process the drop event and returns true so that the drag source's
- * repair action does not run.
- * @param {Roo.dd.DragSource} source The drag source that was dragged over this drop target
- * @param {Event} e The event
- * @param {Object} data An object containing arbitrary data supplied by the drag source
- * @return {Boolean} True if the drop was valid, else false
+ * @hide
*/
- notifyDrop : function(dd, e, data){
- return false;
+ notifyDrop : function(dd, e, data)
+ {
+ this.success = false;
+ this.fireEvent('drop', dd, e, data);
+ return this.success;
}
});/*
* Based on:
ds = el.dataSource;
el = config.container;
}
-
+ var items = [];
+ if (config.items) {
+ items = config.items;
+ config.items = [];
+ }
Roo.PagingToolbar.superclass.constructor.call(this, el, null, config);
this.ds = ds;
this.cursor = 0;
this.renderButtons(this.el);
this.bind(ds);
+
+ // supprot items array.
+
+ Roo.each(items, function(e) {
+ this.add(Roo.factory(e));
+ },this);
+
};
Roo.extend(Roo.PagingToolbar, Roo.Toolbar, {
}
},
- onSpecialKey : function(field, e){
+ onSpecialKey : function(field, e)
+ {
//Roo.log('editor onSpecialKey');
if(this.completeOnEnter && e.getKey() == e.ENTER){
e.stopEvent();
this.completeEdit();
- }else if(this.cancelOnEsc && e.getKey() == e.ESC){
- this.cancelEdit();
- }else{
- this.fireEvent('specialkey', field, e);
+ return;
+ }
+ // do not fire special key otherwise it might hide close the editor...
+ if(e.getKey() == e.ENTER){
+ return;
}
+ if(this.cancelOnEsc && e.getKey() == e.ESC){
+ this.cancelEdit();
+ return;
+ }
+ this.fireEvent('specialkey', field, e);
+
},
/**
*/
valueNotFoundText : undefined,
/**
- * @cfg {bool} blockFocus Prevents all focus calls, so it can work with things like HTML edtor bar
+ * @cfg {Boolean} blockFocus Prevents all focus calls, so it can work with things like HTML edtor bar
*/
blockFocus : false,
/**
- * @cfg {bool} disableClear Disable showing of clear button.
+ * @cfg {Boolean} disableClear Disable showing of clear button.
*/
disableClear : false,
/**
- * @cfg {bool} alwaysQuery Disable caching of results, and always send query
+ * @cfg {Boolean} alwaysQuery Disable caching of results, and always send query
*/
alwaysQuery : false,
dv = !o || typeof(o[this.displayField]) == 'undefined' ? '' : o[this.displayField];
} else {
// this is an error condition!!!
- console.log('no value field set for '+ this.name);
+ Roo.log('no displayField value set for '+ (this.name ? this.name : this.id));
}
if(this.valueField){
'font-size'
];
-// <script type="text/javascript">
-/*
- * Based on
- * Ext JS Library 1.1.1
- * Copyright(c) 2006-2007, Ext JS, LLC.
- *
-
- */
-
-/**
- * @class Roo.form.HtmlEditorToolbar1
- * Basic Toolbar
- *
- * Usage:
- *
- new Roo.form.HtmlEditor({
- ....
- toolbars : [
- new Roo.form.HtmlEditorToolbar1({
- disable : { fonts: 1 , format: 1, ..., ... , ...],
- btns : [ .... ]
- })
- }
-
- *
- * @cfg {Object} disable List of elements to disable..
- * @cfg {Array} btns List of additional buttons.
- *
- *
- * NEEDS Extra CSS?
- * .x-html-editor-tb .x-edit-none .x-btn-text { background: none; }
- */
-
-Roo.form.HtmlEditor.ToolbarStandard = function(config)
-{
-
- Roo.apply(this, config);
- //Roo.form.HtmlEditorToolbar1.superclass.constructor.call(this, editor.wrap.dom.firstChild, [], config);
- // dont call parent... till later.
-}
-
-Roo.apply(Roo.form.HtmlEditor.ToolbarStandard.prototype, {
-
- tb: false,
-
- rendered: false,
-
- editor : false,
- /**
- * @cfg {Object} disable List of toolbar elements to disable
-
- */
- disable : false,
- /**
- * @cfg {Array} fontFamilies An array of available font families
- */
- fontFamilies : [
- 'Arial',
- 'Courier New',
- 'Tahoma',
- 'Times New Roman',
- 'Verdana'
- ],
-
- specialChars : [
- "©",
- "®",
- "™",
- "£" ,
- // "—",
- "…",
- "÷" ,
- // "á" , ?? a acute?
- "€" , //Euro
- // "“" ,
- // "”" ,
- // "•" ,
- "°" // , // degrees
-
- // "é" , // e ecute
- // "ú" , // u ecute?
- ],
- inputElements : [
- "form", "input:text", "input:hidden", "input:checkbox", "input:radio", "input:password",
- "input:submit", "input:button", "select", "textarea", "label" ],
- formats : [
- ["p"] ,
- ["h1"],["h2"],["h3"],["h4"],["h5"],["h6"],
- ["pre"],[ "code"],
- ["abbr"],[ "acronym"],[ "address"],[ "cite"],[ "samp"],[ "var"]
- ],
- /**
- * @cfg {String} defaultFont default font to use.
- */
- defaultFont: 'tahoma',
-
- fontSelect : false,
-
-
- formatCombo : false,
-
- init : function(editor)
- {
- this.editor = editor;
-
-
- var fid = editor.frameId;
- var etb = this;
- function btn(id, toggle, handler){
- var xid = fid + '-'+ id ;
- return {
- id : xid,
- cmd : id,
- cls : 'x-btn-icon x-edit-'+id,
- enableToggle:toggle !== false,
- scope: editor, // was editor...
- handler:handler||editor.relayBtnCmd,
- clickEvent:'mousedown',
- tooltip: etb.buttonTips[id] || undefined, ///tips ???
- tabIndex:-1
- };
- }
-
-
-
- var tb = new Roo.Toolbar(editor.wrap.dom.firstChild);
- this.tb = tb;
- // stop form submits
- tb.el.on('click', function(e){
- e.preventDefault(); // what does this do?
- });
-
- if(!this.disable.font && !Roo.isSafari){
- /* why no safari for fonts
- editor.fontSelect = tb.el.createChild({
- tag:'select',
- tabIndex: -1,
- cls:'x-font-select',
- html: editor.createFontOptions()
- });
- editor.fontSelect.on('change', function(){
- var font = editor.fontSelect.dom.value;
- editor.relayCmd('fontname', font);
- editor.deferFocus();
- }, editor);
- tb.add(
- editor.fontSelect.dom,
- '-'
- );
- */
- };
- if(!this.disable.formats){
- this.formatCombo = new Roo.form.ComboBox({
- store: new Roo.data.SimpleStore({
- id : 'tag',
- fields: ['tag'],
- data : this.formats // from states.js
- }),
- blockFocus : true,
- //autoCreate : {tag: "div", size: "20"},
- displayField:'tag',
- typeAhead: false,
- mode: 'local',
- editable : false,
- triggerAction: 'all',
- emptyText:'Add tag',
- selectOnFocus:true,
- width:135,
- listeners : {
- 'select': function(c, r, i) {
- editor.insertTag(r.get('tag'));
- editor.focus();
- }
- }
-
- });
- tb.addField(this.formatCombo);
-
- }
-
- if(!this.disable.format){
- tb.add(
- btn('bold'),
- btn('italic'),
- btn('underline')
- );
- };
- if(!this.disable.fontSize){
- tb.add(
- '-',
-
-
- btn('increasefontsize', false, editor.adjustFont),
- btn('decreasefontsize', false, editor.adjustFont)
- );
- };
-
-
- if(this.disable.colors){
- tb.add(
- '-', {
- id:editor.frameId +'-forecolor',
- cls:'x-btn-icon x-edit-forecolor',
- clickEvent:'mousedown',
- tooltip: this.buttonTips['forecolor'] || undefined,
- tabIndex:-1,
- menu : new Roo.menu.ColorMenu({
- allowReselect: true,
- focus: Roo.emptyFn,
- value:'000000',
- plain:true,
- selectHandler: function(cp, color){
- editor.execCmd('forecolor', Roo.isSafari || Roo.isIE ? '#'+color : color);
- editor.deferFocus();
- },
- scope: editor,
- clickEvent:'mousedown'
- })
- }, {
- id:editor.frameId +'backcolor',
- cls:'x-btn-icon x-edit-backcolor',
- clickEvent:'mousedown',
- tooltip: this.buttonTips['backcolor'] || undefined,
- tabIndex:-1,
- menu : new Roo.menu.ColorMenu({
- focus: Roo.emptyFn,
- value:'FFFFFF',
- plain:true,
- allowReselect: true,
- selectHandler: function(cp, color){
- if(Roo.isGecko){
- editor.execCmd('useCSS', false);
- editor.execCmd('hilitecolor', color);
- editor.execCmd('useCSS', true);
- editor.deferFocus();
- }else{
- editor.execCmd(Roo.isOpera ? 'hilitecolor' : 'backcolor',
- Roo.isSafari || Roo.isIE ? '#'+color : color);
- editor.deferFocus();
- }
- },
- scope:editor,
- clickEvent:'mousedown'
- })
- }
- );
- };
- // now add all the items...
-
-
- if(!this.disable.alignments){
- tb.add(
- '-',
- btn('justifyleft'),
- btn('justifycenter'),
- btn('justifyright')
- );
- };
-
- //if(!Roo.isSafari){
- if(!this.disable.links){
- tb.add(
- '-',
- btn('createlink', false, editor.createLink) /// MOVE TO HERE?!!?!?!?!
- );
- };
-
- if(!this.disable.lists){
- tb.add(
- '-',
- btn('insertorderedlist'),
- btn('insertunorderedlist')
- );
- }
- if(!this.disable.sourceEdit){
- tb.add(
- '-',
- btn('sourceedit', true, function(btn){
- this.toggleSourceEdit(btn.pressed);
- })
- );
- }
- //}
-
- var smenu = { };
- // special menu.. - needs to be tidied up..
- if (!this.disable.special) {
- smenu = {
- text: "©",
- cls: 'x-edit-none',
- menu : {
- items : []
- }
- };
- for (var i =0; i < this.specialChars.length; i++) {
- smenu.menu.items.push({
-
- html: this.specialChars[i],
- handler: function(a,b) {
- editor.insertAtCursor(String.fromCharCode(a.html.replace('&#','').replace(';', '')));
-
- },
- tabIndex:-1
- });
- }
-
-
- tb.add(smenu);
-
-
- }
- if (this.btns) {
- for(var i =0; i< this.btns.length;i++) {
- var b = this.btns[i];
- b.cls = 'x-edit-none';
- b.scope = editor;
- tb.add(b);
- }
-
- }
-
-
-
- // disable everything...
-
- this.tb.items.each(function(item){
- if(item.id != editor.frameId+ '-sourceedit'){
- item.disable();
- }
- });
- this.rendered = true;
-
- // the all the btns;
- editor.on('editorevent', this.updateToolbar, this);
- // other toolbars need to implement this..
- //editor.on('editmodechange', this.updateToolbar, this);
- },
-
-
-
- /**
- * Protected method that will not generally be called directly. It triggers
- * a toolbar update by reading the markup state of the current selection in the editor.
- */
- updateToolbar: function(){
-
- if(!this.editor.activated){
- this.editor.onFirstFocus();
- return;
- }
-
- var btns = this.tb.items.map,
- doc = this.editor.doc,
- frameId = this.editor.frameId;
-
- if(!this.disable.font && !Roo.isSafari){
- /*
- var name = (doc.queryCommandValue('FontName')||this.editor.defaultFont).toLowerCase();
- if(name != this.fontSelect.dom.value){
- this.fontSelect.dom.value = name;
- }
- */
- }
- if(!this.disable.format){
- btns[frameId + '-bold'].toggle(doc.queryCommandState('bold'));
- btns[frameId + '-italic'].toggle(doc.queryCommandState('italic'));
- btns[frameId + '-underline'].toggle(doc.queryCommandState('underline'));
- }
- if(!this.disable.alignments){
- btns[frameId + '-justifyleft'].toggle(doc.queryCommandState('justifyleft'));
- btns[frameId + '-justifycenter'].toggle(doc.queryCommandState('justifycenter'));
- btns[frameId + '-justifyright'].toggle(doc.queryCommandState('justifyright'));
- }
- if(!Roo.isSafari && !this.disable.lists){
- btns[frameId + '-insertorderedlist'].toggle(doc.queryCommandState('insertorderedlist'));
- btns[frameId + '-insertunorderedlist'].toggle(doc.queryCommandState('insertunorderedlist'));
- }
-
- var ans = this.editor.getAllAncestors();
- if (this.formatCombo) {
-
-
- var store = this.formatCombo.store;
- this.formatCombo.setValue("");
- for (var i =0; i < ans.length;i++) {
- if (ans[i] && store.query('tag',ans[i].tagName.toLowerCase(), false).length) {
- // select it..
- this.formatCombo.setValue(ans[i].tagName.toLowerCase());
- break;
- }
- }
- }
-
-
-
- // hides menus... - so this cant be on a menu...
- Roo.menu.MenuMgr.hideAll();
-
- //this.editorsyncValue();
- },
-
-
- createFontOptions : function(){
- var buf = [], fs = this.fontFamilies, ff, lc;
- for(var i = 0, len = fs.length; i< len; i++){
- ff = fs[i];
- lc = ff.toLowerCase();
- buf.push(
- '<option value="',lc,'" style="font-family:',ff,';"',
- (this.defaultFont == lc ? ' selected="true">' : '>'),
- ff,
- '</option>'
- );
- }
- return buf.join('');
- },
-
- toggleSourceEdit : function(sourceEditMode){
- if(sourceEditMode === undefined){
- sourceEditMode = !this.sourceEditMode;
- }
- this.sourceEditMode = sourceEditMode === true;
- var btn = this.tb.items.get(this.editor.frameId +'-sourceedit');
- // just toggle the button?
- if(btn.pressed !== this.editor.sourceEditMode){
- btn.toggle(this.editor.sourceEditMode);
- return;
- }
-
- if(this.sourceEditMode){
- this.tb.items.each(function(item){
- if(item.cmd != 'sourceedit'){
- item.disable();
- }
- });
-
- }else{
- if(this.initialized){
- this.tb.items.each(function(item){
- item.enable();
- });
- }
-
- }
- // tell the editor that it's been pressed..
- this.editor.toggleSourceEdit(sourceEditMode);
-
- },
- /**
- * Object collection of toolbar tooltips for the buttons in the editor. The key
- * is the command id associated with that button and the value is a valid QuickTips object.
- * For example:
-<pre><code>
-{
- bold : {
- title: 'Bold (Ctrl+B)',
- text: 'Make the selected text bold.',
- cls: 'x-html-editor-tip'
- },
- italic : {
- title: 'Italic (Ctrl+I)',
- text: 'Make the selected text italic.',
- cls: 'x-html-editor-tip'
- },
- ...
-</code></pre>
- * @type Object
- */
- buttonTips : {
- bold : {
- title: 'Bold (Ctrl+B)',
- text: 'Make the selected text bold.',
- cls: 'x-html-editor-tip'
- },
- italic : {
- title: 'Italic (Ctrl+I)',
- text: 'Make the selected text italic.',
- cls: 'x-html-editor-tip'
- },
- underline : {
- title: 'Underline (Ctrl+U)',
- text: 'Underline the selected text.',
- cls: 'x-html-editor-tip'
- },
- increasefontsize : {
- title: 'Grow Text',
- text: 'Increase the font size.',
- cls: 'x-html-editor-tip'
- },
- decreasefontsize : {
- title: 'Shrink Text',
- text: 'Decrease the font size.',
- cls: 'x-html-editor-tip'
- },
- backcolor : {
- title: 'Text Highlight Color',
- text: 'Change the background color of the selected text.',
- cls: 'x-html-editor-tip'
- },
- forecolor : {
- title: 'Font Color',
- text: 'Change the color of the selected text.',
- cls: 'x-html-editor-tip'
- },
- justifyleft : {
- title: 'Align Text Left',
- text: 'Align text to the left.',
- cls: 'x-html-editor-tip'
- },
- justifycenter : {
- title: 'Center Text',
- text: 'Center text in the editor.',
- cls: 'x-html-editor-tip'
- },
- justifyright : {
- title: 'Align Text Right',
- text: 'Align text to the right.',
- cls: 'x-html-editor-tip'
- },
- insertunorderedlist : {
- title: 'Bullet List',
- text: 'Start a bulleted list.',
- cls: 'x-html-editor-tip'
- },
- insertorderedlist : {
- title: 'Numbered List',
- text: 'Start a numbered list.',
- cls: 'x-html-editor-tip'
- },
- createlink : {
- title: 'Hyperlink',
- text: 'Make the selected text a hyperlink.',
- cls: 'x-html-editor-tip'
- },
- sourceedit : {
- title: 'Source Edit',
- text: 'Switch to source editing mode.',
- cls: 'x-html-editor-tip'
- }
- },
- // private
- onDestroy : function(){
- if(this.rendered){
-
- this.tb.items.each(function(item){
- if(item.menu){
- item.menu.removeAll();
- if(item.menu.el){
- item.menu.el.destroy();
- }
- }
- item.destroy();
- });
-
- }
- },
- onFirstFocus: function() {
- this.tb.items.each(function(item){
- item.enable();
- });
- }
-});
-
-
-
-
-// <script type="text/javascript">
-/*
- * Based on
- * Ext JS Library 1.1.1
- * Copyright(c) 2006-2007, Ext JS, LLC.
- *
-
- */
-
-
-/**
- * @class Roo.form.HtmlEditor.ToolbarContext
- * Context Toolbar
- *
- * Usage:
- *
- new Roo.form.HtmlEditor({
- ....
- toolbars : [
- new Roo.form.HtmlEditor.ToolbarStandard(),
- new Roo.form.HtmlEditor.ToolbarContext()
- })
- }
-
- *
- * @config : {Object} disable List of elements to disable.. (not done yet.)
- *
- *
- */
-
-Roo.form.HtmlEditor.ToolbarContext = function(config)
-{
-
- Roo.apply(this, config);
- //Roo.form.HtmlEditorToolbar1.superclass.constructor.call(this, editor.wrap.dom.firstChild, [], config);
- // dont call parent... till later.
-}
-Roo.form.HtmlEditor.ToolbarContext.types = {
- 'IMG' : {
- width : {
- title: "Width",
- width: 40
- },
- height: {
- title: "Height",
- width: 40
- },
- align: {
- title: "Align",
- opts : [ [""],[ "left"],[ "right"],[ "center"],[ "top"]],
- width : 80
-
- },
- border: {
- title: "Border",
- width: 40
- },
- alt: {
- title: "Alt",
- width: 120
- },
- src : {
- title: "Src",
- width: 220
- }
-
- },
- 'A' : {
- name : {
- title: "Name",
- width: 50
- },
- href: {
- title: "Href",
- width: 220
- } // border?
-
- },
- 'TABLE' : {
- rows : {
- title: "Rows",
- width: 20
- },
- cols : {
- title: "Cols",
- width: 20
- },
- width : {
- title: "Width",
- width: 40
- },
- height : {
- title: "Height",
- width: 40
- },
- border : {
- title: "Border",
- width: 20
- }
- },
- 'TD' : {
- width : {
- title: "Width",
- width: 40
- },
- height : {
- title: "Height",
- width: 40
- },
- align: {
- title: "Align",
- opts : [[""],[ "left"],[ "center"],[ "right"],[ "justify"],[ "char"]],
- width: 40
- },
- valign: {
- title: "Valign",
- opts : [[""],[ "top"],[ "middle"],[ "bottom"],[ "baseline"]],
- width: 40
- },
- colspan: {
- title: "Colspan",
- width: 20
-
- }
- },
- 'INPUT' : {
- name : {
- title: "name",
- width: 120
- },
- value : {
- title: "Value",
- width: 120
- },
- width : {
- title: "Width",
- width: 40
- }
- },
- 'LABEL' : {
- 'for' : {
- title: "For",
- width: 120
- }
- },
- 'TEXTAREA' : {
- name : {
- title: "name",
- width: 120
- },
- rows : {
- title: "Rows",
- width: 20
- },
- cols : {
- title: "Cols",
- width: 20
- }
- },
- 'SELECT' : {
- name : {
- title: "name",
- width: 120
- },
- selectoptions : {
- title: "Options",
- width: 200
- }
- },
- 'BODY' : {
- title : {
- title: "title",
- width: 120,
- disabled : true
- }
- }
-};
-
-
-
-Roo.apply(Roo.form.HtmlEditor.ToolbarContext.prototype, {
-
- tb: false,
-
- rendered: false,
-
- editor : false,
- /**
- * @cfg {Object} disable List of toolbar elements to disable
-
- */
- disable : false,
-
-
-
- toolbars : false,
-
- init : function(editor)
- {
- this.editor = editor;
-
-
- var fid = editor.frameId;
- var etb = this;
- function btn(id, toggle, handler){
- var xid = fid + '-'+ id ;
- return {
- id : xid,
- cmd : id,
- cls : 'x-btn-icon x-edit-'+id,
- enableToggle:toggle !== false,
- scope: editor, // was editor...
- handler:handler||editor.relayBtnCmd,
- clickEvent:'mousedown',
- tooltip: etb.buttonTips[id] || undefined, ///tips ???
- tabIndex:-1
- };
- }
- // create a new element.
- var wdiv = editor.wrap.createChild({
- tag: 'div'
- }, editor.wrap.dom.firstChild.nextSibling, true);
-
- // can we do this more than once??
-
- // stop form submits
-
-
- // disable everything...
- var ty= Roo.form.HtmlEditor.ToolbarContext.types;
- this.toolbars = {};
-
- for (var i in ty) {
-
- this.toolbars[i] = this.buildToolbar(ty[i],i);
- }
- this.tb = this.toolbars.BODY;
- this.tb.el.show();
-
-
- this.rendered = true;
-
- // the all the btns;
- editor.on('editorevent', this.updateToolbar, this);
- // other toolbars need to implement this..
- //editor.on('editmodechange', this.updateToolbar, this);
- },
-
-
-
- /**
- * Protected method that will not generally be called directly. It triggers
- * a toolbar update by reading the markup state of the current selection in the editor.
- */
- updateToolbar: function(){
-
- if(!this.editor.activated){
- this.editor.onFirstFocus();
- return;
- }
-
-
- var ans = this.editor.getAllAncestors();
-
- // pick
- var ty= Roo.form.HtmlEditor.ToolbarContext.types;
- var sel = ans.length ? (ans[0] ? ans[0] : ans[1]) : this.editor.doc.body;
- sel = sel ? sel : this.editor.doc.body;
- sel = sel.tagName.length ? sel : this.editor.doc.body;
- var tn = sel.tagName.toUpperCase();
- sel = typeof(ty[tn]) != 'undefined' ? sel : this.editor.doc.body;
- tn = sel.tagName.toUpperCase();
- if (this.tb.name == tn) {
- return; // no change
- }
- this.tb.el.hide();
- ///console.log("show: " + tn);
- this.tb = this.toolbars[tn];
- this.tb.el.show();
- this.tb.fields.each(function(e) {
- e.setValue(sel.getAttribute(e.name));
- });
- this.tb.selectedNode = sel;
-
-
- Roo.menu.MenuMgr.hideAll();
-
- //this.editorsyncValue();
- },
-
-
- // private
- onDestroy : function(){
- if(this.rendered){
-
- this.tb.items.each(function(item){
- if(item.menu){
- item.menu.removeAll();
- if(item.menu.el){
- item.menu.el.destroy();
- }
- }
- item.destroy();
- });
-
- }
- },
- onFirstFocus: function() {
- // need to do this for all the toolbars..
- this.tb.items.each(function(item){
- item.enable();
- });
- },
- buildToolbar: function(tlist, nm)
- {
- var editor = this.editor;
- // create a new element.
- var wdiv = editor.wrap.createChild({
- tag: 'div'
- }, editor.wrap.dom.firstChild.nextSibling, true);
-
-
- var tb = new Roo.Toolbar(wdiv);
- tb.add(nm+ ": ");
- for (var i in tlist) {
- var item = tlist[i];
- tb.add(item.title + ": ");
- if (item.opts) {
- // fixme
-
-
- tb.addField( new Roo.form.ComboBox({
- store: new Roo.data.SimpleStore({
- id : 'val',
- fields: ['val'],
- data : item.opts // from states.js
- }),
- name : i,
- displayField:'val',
- typeAhead: false,
- mode: 'local',
- editable : false,
- triggerAction: 'all',
- emptyText:'Select',
- selectOnFocus:true,
- width: item.width ? item.width : 130,
- listeners : {
- 'select': function(c, r, i) {
- tb.selectedNode.setAttribute(c.name, r.get('val'));
- }
- }
-
- }));
- continue;
-
-
-
-
-
- tb.addField( new Roo.form.TextField({
- name: i,
- width: 100,
- //allowBlank:false,
- value: ''
- }));
- continue;
- }
- tb.addField( new Roo.form.TextField({
- name: i,
- width: item.width,
- //allowBlank:true,
- value: '',
- listeners: {
- 'change' : function(f, nv, ov) {
- tb.selectedNode.setAttribute(f.name, nv);
- }
- }
- }));
-
- }
- tb.el.on('click', function(e){
- e.preventDefault(); // what does this do?
- });
- tb.el.setVisibilityMode( Roo.Element.DISPLAY);
- tb.el.hide();
- tb.name = nm;
- // dont need to disable them... as they will get hidden
- return tb;
-
-
- }
-
-
-
-
-});
-
-
-
-
-
-/*
- * Based on:
- * Ext JS Library 1.1.1
- * Copyright(c) 2006-2007, Ext JS, LLC.
- *
- * Originally Released Under LGPL - original licence link has changed is not relivant.
- *
- * Fork - LGPL
- * <script type="text/javascript">
- */
-
-/**
- * @class Roo.form.BasicForm
- * @extends Roo.util.Observable
- * Supplies the functionality to do "actions" on forms and initialize Roo.form.Field types on existing markup.
- * @constructor
- * @param {String/HTMLElement/Roo.Element} el The form element or its id
- * @param {Object} config Configuration options
- */
-Roo.form.BasicForm = function(el, config){
- this.allItems = [];
- this.childForms = [];
- Roo.apply(this, config);
- /*
- * The Roo.form.Field items in this form.
- * @type MixedCollection
- */
-
-
- this.items = new Roo.util.MixedCollection(false, function(o){
- return o.id || (o.id = Roo.id());
- });
- this.addEvents({
- /**
- * @event beforeaction
- * Fires before any action is performed. Return false to cancel the action.
- * @param {Form} this
- * @param {Action} action The action to be performed
- */
- beforeaction: true,
- /**
- * @event actionfailed
- * Fires when an action fails.
- * @param {Form} this
- * @param {Action} action The action that failed
- */
- actionfailed : true,
- /**
- * @event actioncomplete
- * Fires when an action is completed.
- * @param {Form} this
- * @param {Action} action The action that completed
- */
- actioncomplete : true
- });
- if(el){
- this.initEl(el);
- }
- Roo.form.BasicForm.superclass.constructor.call(this);
-};
-
-Roo.extend(Roo.form.BasicForm, Roo.util.Observable, {
- /**
- * @cfg {String} method
- * The request method to use (GET or POST) for form actions if one isn't supplied in the action options.
- */
- /**
- * @cfg {DataReader} reader
- * An Roo.data.DataReader (e.g. {@link Roo.data.XmlReader}) to be used to read data when executing "load" actions.
- * This is optional as there is built-in support for processing JSON.
- */
- /**
- * @cfg {DataReader} errorReader
- * An Roo.data.DataReader (e.g. {@link Roo.data.XmlReader}) to be used to read data when reading validation errors on "submit" actions.
- * This is completely optional as there is built-in support for processing JSON.
- */
- /**
- * @cfg {String} url
- * The URL to use for form actions if one isn't supplied in the action options.
- */
- /**
- * @cfg {Boolean} fileUpload
- * Set to true if this form is a file upload.
- */
- /**
- * @cfg {Object} baseParams
- * Parameters to pass with all requests. e.g. baseParams: {id: '123', foo: 'bar'}.
- */
- /**
- * @cfg {Number} timeout Timeout for form actions in seconds (default is 30 seconds).
- */
- timeout: 30,
-
- // private
- activeAction : null,
-
- /**
- * @cfg {Boolean} trackResetOnLoad If set to true, form.reset() resets to the last loaded
- * or setValues() data instead of when the form was first created.
- */
- trackResetOnLoad : false,
-
-
- /**
- * childForms - used for multi-tab forms
- * @type {Array}
- */
- childForms : false,
-
- /**
- * allItems - full list of fields.
- * @type {Array}
- */
- allItems : false,
-
- /**
- * By default wait messages are displayed with Roo.MessageBox.wait. You can target a specific
- * element by passing it or its id or mask the form itself by passing in true.
- * @type Mixed
- */
- waitMsgTarget : undefined,
-
- // private
- initEl : function(el){
- this.el = Roo.get(el);
- this.id = this.el.id || Roo.id();
- this.el.on('submit', this.onSubmit, this);
- this.el.addClass('x-form');
- },
-
- // private
- onSubmit : function(e){
- e.stopEvent();
- },
-
- /**
- * Returns true if client-side validation on the form is successful.
- * @return Boolean
- */
- isValid : function(){
- var valid = true;
- this.items.each(function(f){
- if(!f.validate()){
- valid = false;
- }
- });
- return valid;
- },
-
- /**
- * Returns true if any fields in this form have changed since their original load.
- * @return Boolean
- */
- isDirty : function(){
- var dirty = false;
- this.items.each(function(f){
- if(f.isDirty()){
- dirty = true;
- return false;
- }
- });
- return dirty;
- },
-
- /**
- * Performs a predefined action (submit or load) or custom actions you define on this form.
- * @param {String} actionName The name of the action type
- * @param {Object} options (optional) The options to pass to the action. All of the config options listed
- * below are supported by both the submit and load actions unless otherwise noted (custom actions could also
- * accept other config options):
- * <pre>
-Property Type Description
----------------- --------------- ----------------------------------------------------------------------------------
-url String The url for the action (defaults to the form's url)
-method String The form method to use (defaults to the form's method, or POST if not defined)
-params String/Object The params to pass (defaults to the form's baseParams, or none if not defined)
-clientValidation Boolean Applies to submit only. Pass true to call form.isValid() prior to posting to
- validate the form on the client (defaults to false)
- * </pre>
- * @return {BasicForm} this
- */
- doAction : function(action, options){
- if(typeof action == 'string'){
- action = new Roo.form.Action.ACTION_TYPES[action](this, options);
- }
- if(this.fireEvent('beforeaction', this, action) !== false){
- this.beforeAction(action);
- action.run.defer(100, action);
- }
- return this;
- },
-
- /**
- * Shortcut to do a submit action.
- * @param {Object} options The options to pass to the action (see {@link #doAction} for details)
- * @return {BasicForm} this
- */
- submit : function(options){
- this.doAction('submit', options);
- return this;
- },
-
- /**
- * Shortcut to do a load action.
- * @param {Object} options The options to pass to the action (see {@link #doAction} for details)
- * @return {BasicForm} this
- */
- load : function(options){
- this.doAction('load', options);
- return this;
- },
-
- /**
- * Persists the values in this form into the passed Roo.data.Record object in a beginEdit/endEdit block.
- * @param {Record} record The record to edit
- * @return {BasicForm} this
- */
- updateRecord : function(record){
- record.beginEdit();
- var fs = record.fields;
- fs.each(function(f){
- var field = this.findField(f.name);
- if(field){
- record.set(f.name, field.getValue());
- }
- }, this);
- record.endEdit();
- return this;
- },
-
- /**
- * Loads an Roo.data.Record into this form.
- * @param {Record} record The record to load
- * @return {BasicForm} this
- */
- loadRecord : function(record){
- this.setValues(record.data);
- return this;
- },
-
- // private
- beforeAction : function(action){
- var o = action.options;
- if(o.waitMsg){
- if(this.waitMsgTarget === true){
- this.el.mask(o.waitMsg, 'x-mask-loading');
- }else if(this.waitMsgTarget){
- this.waitMsgTarget = Roo.get(this.waitMsgTarget);
- this.waitMsgTarget.mask(o.waitMsg, 'x-mask-loading');
- }else{
- Roo.MessageBox.wait(o.waitMsg, o.waitTitle || this.waitTitle || 'Please Wait...');
- }
- }
- },
-
- // private
- afterAction : function(action, success){
- this.activeAction = null;
- var o = action.options;
- if(o.waitMsg){
- if(this.waitMsgTarget === true){
- this.el.unmask();
- }else if(this.waitMsgTarget){
- this.waitMsgTarget.unmask();
- }else{
- Roo.MessageBox.updateProgress(1);
- Roo.MessageBox.hide();
- }
- }
- if(success){
- if(o.reset){
- this.reset();
- }
- Roo.callback(o.success, o.scope, [this, action]);
- this.fireEvent('actioncomplete', this, action);
- }else{
- Roo.callback(o.failure, o.scope, [this, action]);
- this.fireEvent('actionfailed', this, action);
- }
- },
-
- /**
- * Find a Roo.form.Field in this form by id, dataIndex, name or hiddenName
- * @param {String} id The value to search for
- * @return Field
- */
- findField : function(id){
- var field = this.items.get(id);
- if(!field){
- this.items.each(function(f){
- if(f.isFormField && (f.dataIndex == id || f.id == id || f.getName() == id)){
- field = f;
- return false;
- }
- });
- }
- return field || null;
- },
-
- /**
- * Add a secondary form to this one,
- * Used to provide tabbed forms. One form is primary, with hidden values
- * which mirror the elements from the other forms.
- *
- * @param {Roo.form.Form} form to add.
- *
- */
- addForm : function(form)
- {
-
- if (this.childForms.indexOf(form) > -1) {
- // already added..
- return;
- }
- this.childForms.push(form);
- var n = '';
- Roo.each(form.allItems, function (fe) {
-
- n = typeof(fe.getName) == 'undefined' ? fe.name : fe.getName();
- if (this.findField(n)) { // already added..
- return;
- }
- var add = new Roo.form.Hidden({
- name : n
- });
- add.render(this.el);
-
- this.add( add );
- }, this);
-
- },
- /**
- * Mark fields in this form invalid in bulk.
- * @param {Array/Object} errors Either an array in the form [{id:'fieldId', msg:'The message'},...] or an object hash of {id: msg, id2: msg2}
- * @return {BasicForm} this
- */
- markInvalid : function(errors){
- if(errors instanceof Array){
- for(var i = 0, len = errors.length; i < len; i++){
- var fieldError = errors[i];
- var f = this.findField(fieldError.id);
- if(f){
- f.markInvalid(fieldError.msg);
- }
- }
- }else{
- var field, id;
- for(id in errors){
- if(typeof errors[id] != 'function' && (field = this.findField(id))){
- field.markInvalid(errors[id]);
- }
- }
- }
- Roo.each(this.childForms || [], function (f) {
- f.markInvalid(errors);
- });
-
- return this;
- },
-
- /**
- * Set values for fields in this form in bulk.
- * @param {Array/Object} values Either an array in the form [{id:'fieldId', value:'foo'},...] or an object hash of {id: value, id2: value2}
- * @return {BasicForm} this
- */
- setValues : function(values){
- if(values instanceof Array){ // array of objects
- for(var i = 0, len = values.length; i < len; i++){
- var v = values[i];
- var f = this.findField(v.id);
- if(f){
- f.setValue(v.value);
- if(this.trackResetOnLoad){
- f.originalValue = f.getValue();
- }
- }
- }
- }else{ // object hash
- var field, id;
- for(id in values){
- if(typeof values[id] != 'function' && (field = this.findField(id))){
-
- if (field.setFromData &&
- field.valueField &&
- field.displayField &&
- // combos' with local stores can
- // be queried via setValue()
- // to set their value..
- (field.store && !field.store.isLocal)
- ) {
- // it's a combo
- var sd = { };
- sd[field.valueField] = typeof(values[field.hiddenName]) == 'undefined' ? '' : values[field.hiddenName];
- sd[field.displayField] = typeof(values[field.name]) == 'undefined' ? '' : values[field.name];
- field.setFromData(sd);
-
- } else {
- field.setValue(values[id]);
- }
-
-
- if(this.trackResetOnLoad){
- field.originalValue = field.getValue();
- }
- }
- }
- }
-
- Roo.each(this.childForms || [], function (f) {
- f.setValues(values);
- });
-
- return this;
- },
-
- /**
- * Returns the fields in this form as an object with key/value pairs. If multiple fields exist with the same name
- * they are returned as an array.
- * @param {Boolean} asString
- * @return {Object}
- */
- getValues : function(asString){
- if (this.childForms) {
- // copy values from the child forms
- Roo.each(this.childForms, function (f) {
- this.setValues(f.getValues());
- }, this);
- }
-
-
-
- var fs = Roo.lib.Ajax.serializeForm(this.el.dom);
- if(asString === true){
- return fs;
- }
- return Roo.urlDecode(fs);
- },
-
- /**
- * Returns the fields in this form as an object with key/value pairs.
- * This differs from getValues as it calls getValue on each child item, rather than using dom data.
- * @return {Object}
- */
- getFieldValues : function()
- {
- if (this.childForms) {
- // copy values from the child forms
- Roo.each(this.childForms, function (f) {
- this.setValues(f.getValues());
- }, this);
- }
-
- var ret = {};
- this.items.each(function(f){
- if (!f.getName()) {
- return;
- }
- var v = f.getValue();
- if ((typeof(v) == 'object') && f.getRawValue) {
- v = f.getRawValue() ; // dates..
- }
- ret[f.getName()] = v;
- });
-
- return ret;
- },
-
- /**
- * Clears all invalid messages in this form.
- * @return {BasicForm} this
- */
- clearInvalid : function(){
- this.items.each(function(f){
- f.clearInvalid();
- });
-
- Roo.each(this.childForms || [], function (f) {
- f.clearInvalid();
- });
-
-
- return this;
- },
-
- /**
- * Resets this form.
- * @return {BasicForm} this
- */
- reset : function(){
- this.items.each(function(f){
- f.reset();
- });
-
- Roo.each(this.childForms || [], function (f) {
- f.reset();
- });
-
-
- return this;
- },
-
- /**
- * Add Roo.form components to this form.
- * @param {Field} field1
- * @param {Field} field2 (optional)
- * @param {Field} etc (optional)
- * @return {BasicForm} this
- */
- add : function(){
- this.items.addAll(Array.prototype.slice.call(arguments, 0));
- return this;
- },
-
-
- /**
- * Removes a field from the items collection (does NOT remove its markup).
- * @param {Field} field
- * @return {BasicForm} this
- */
- remove : function(field){
- this.items.remove(field);
- return this;
- },
-
- /**
- * Looks at the fields in this form, checks them for an id attribute,
- * and calls applyTo on the existing dom element with that id.
- * @return {BasicForm} this
- */
- render : function(){
- this.items.each(function(f){
- if(f.isFormField && !f.rendered && document.getElementById(f.id)){ // if the element exists
- f.applyTo(f.id);
- }
- });
- return this;
- },
-
- /**
- * Calls {@link Ext#apply} for all fields in this form with the passed object.
- * @param {Object} values
- * @return {BasicForm} this
- */
- applyToFields : function(o){
- this.items.each(function(f){
- Roo.apply(f, o);
- });
- return this;
- },
-
- /**
- * Calls {@link Ext#applyIf} for all field in this form with the passed object.
- * @param {Object} values
- * @return {BasicForm} this
- */
- applyIfToFields : function(o){
- this.items.each(function(f){
- Roo.applyIf(f, o);
- });
- return this;
- }
-});
-
-// back compat
-Roo.BasicForm = Roo.form.BasicForm;/*
- * Based on:
- * Ext JS Library 1.1.1
- * Copyright(c) 2006-2007, Ext JS, LLC.
- *
- * Originally Released Under LGPL - original licence link has changed is not relivant.
- *
- * Fork - LGPL
- * <script type="text/javascript">
- */
-
-/**
- * @class Roo.form.Form
- * @extends Roo.form.BasicForm
- * Adds the ability to dynamically render forms with JavaScript to {@link Roo.form.BasicForm}.
- * @constructor
- * @param {Object} config Configuration options
- */
-Roo.form.Form = function(config){
- var xitems = [];
- if (config.items) {
- xitems = config.items;
- delete config.items;
- }
-
-
- Roo.form.Form.superclass.constructor.call(this, null, config);
- this.url = this.url || this.action;
- if(!this.root){
- this.root = new Roo.form.Layout(Roo.applyIf({
- id: Roo.id()
- }, config));
- }
- this.active = this.root;
- /**
- * Array of all the buttons that have been added to this form via {@link addButton}
- * @type Array
- */
- this.buttons = [];
- this.allItems = [];
- this.addEvents({
- /**
- * @event clientvalidation
- * If the monitorValid config option is true, this event fires repetitively to notify of valid state
- * @param {Form} this
- * @param {Boolean} valid true if the form has passed client-side validation
- */
- clientvalidation: true,
- /**
- * @event rendered
- * Fires when the form is rendered
- * @param {Roo.form.Form} form
- */
- rendered : true
- });
-
- Roo.each(xitems, this.addxtype, this);
-
-
-
-};
-
-Roo.extend(Roo.form.Form, Roo.form.BasicForm, {
- /**
- * @cfg {Number} labelWidth The width of labels. This property cascades to child containers.
- */
- /**
- * @cfg {String} itemCls A css class to apply to the x-form-item of fields. This property cascades to child containers.
- */
- /**
- * @cfg {String} buttonAlign Valid values are "left," "center" and "right" (defaults to "center")
- */
- buttonAlign:'center',
-
- /**
- * @cfg {Number} minButtonWidth Minimum width of all buttons in pixels (defaults to 75)
- */
- minButtonWidth:75,
-
- /**
- * @cfg {String} labelAlign Valid values are "left," "top" and "right" (defaults to "left").
- * This property cascades to child containers if not set.
- */
- labelAlign:'left',
-
- /**
- * @cfg {Boolean} monitorValid If true the form monitors its valid state <b>client-side</b> and
- * fires a looping event with that state. This is required to bind buttons to the valid
- * state using the config value formBind:true on the button.
- */
- monitorValid : false,
-
- /**
- * @cfg {Number} monitorPoll The milliseconds to poll valid state, ignored if monitorValid is not true (defaults to 200)
- */
- monitorPoll : 200,
-
-
- /**
- * Opens a new {@link Roo.form.Column} container in the layout stack. If fields are passed after the config, the
- * fields are added and the column is closed. If no fields are passed the column remains open
- * until end() is called.
- * @param {Object} config The config to pass to the column
- * @param {Field} field1 (optional)
- * @param {Field} field2 (optional)
- * @param {Field} etc (optional)
- * @return Column The column container object
- */
- column : function(c){
- var col = new Roo.form.Column(c);
- this.start(col);
- if(arguments.length > 1){ // duplicate code required because of Opera
- this.add.apply(this, Array.prototype.slice.call(arguments, 1));
- this.end();
- }
- return col;
- },
-
- /**
- * Opens a new {@link Roo.form.FieldSet} container in the layout stack. If fields are passed after the config, the
- * fields are added and the fieldset is closed. If no fields are passed the fieldset remains open
- * until end() is called.
- * @param {Object} config The config to pass to the fieldset
- * @param {Field} field1 (optional)
- * @param {Field} field2 (optional)
- * @param {Field} etc (optional)
- * @return FieldSet The fieldset container object
- */
- fieldset : function(c){
- var fs = new Roo.form.FieldSet(c);
- this.start(fs);
- if(arguments.length > 1){ // duplicate code required because of Opera
- this.add.apply(this, Array.prototype.slice.call(arguments, 1));
- this.end();
- }
- return fs;
- },
-
- /**
- * Opens a new {@link Roo.form.Layout} container in the layout stack. If fields are passed after the config, the
- * fields are added and the container is closed. If no fields are passed the container remains open
- * until end() is called.
- * @param {Object} config The config to pass to the Layout
- * @param {Field} field1 (optional)
- * @param {Field} field2 (optional)
- * @param {Field} etc (optional)
- * @return Layout The container object
- */
- container : function(c){
- var l = new Roo.form.Layout(c);
- this.start(l);
- if(arguments.length > 1){ // duplicate code required because of Opera
- this.add.apply(this, Array.prototype.slice.call(arguments, 1));
- this.end();
- }
- return l;
- },
-
- /**
- * Opens the passed container in the layout stack. The container can be any {@link Roo.form.Layout} or subclass.
- * @param {Object} container A Roo.form.Layout or subclass of Layout
- * @return {Form} this
- */
- start : function(c){
- // cascade label info
- Roo.applyIf(c, {'labelAlign': this.active.labelAlign, 'labelWidth': this.active.labelWidth, 'itemCls': this.active.itemCls});
- this.active.stack.push(c);
- c.ownerCt = this.active;
- this.active = c;
- return this;
- },
-
- /**
- * Closes the current open container
- * @return {Form} this
- */
- end : function(){
- if(this.active == this.root){
- return this;
- }
- this.active = this.active.ownerCt;
- return this;
- },
-
- /**
- * Add Roo.form components to the current open container (e.g. column, fieldset, etc.). Fields added via this method
- * can also be passed with an additional property of fieldLabel, which if supplied, will provide the text to display
- * as the label of the field.
- * @param {Field} field1
- * @param {Field} field2 (optional)
- * @param {Field} etc. (optional)
- * @return {Form} this
- */
- add : function(){
- this.active.stack.push.apply(this.active.stack, arguments);
- this.allItems.push.apply(this.allItems,arguments);
- var r = [];
- for(var i = 0, a = arguments, len = a.length; i < len; i++) {
- if(a[i].isFormField){
- r.push(a[i]);
- }
- }
- if(r.length > 0){
- Roo.form.Form.superclass.add.apply(this, r);
- }
- return this;
- },
-
-
-
-
-
- /**
- * Find any element that has been added to a form, using it's ID or name
- * This can include framesets, columns etc. along with regular fields..
- * @param {String} id - id or name to find.
-
- * @return {Element} e - or false if nothing found.
- */
- findbyId : function(id)
- {
- var ret = false;
- if (!id) {
- return ret;
- }
- Ext.each(this.allItems, function(f){
- if (f.id == id || f.name == id ){
- ret = f;
- return false;
- }
- });
- return ret;
- },
-
-
-
- /**
- * Render this form into the passed container. This should only be called once!
- * @param {String/HTMLElement/Element} container The element this component should be rendered into
- * @return {Form} this
- */
- render : function(ct){
- ct = Roo.get(ct);
- var o = this.autoCreate || {
- tag: 'form',
- method : this.method || 'POST',
- id : this.id || Roo.id()
- };
- this.initEl(ct.createChild(o));
-
- this.root.render(this.el);
-
- this.items.each(function(f){
- f.render('x-form-el-'+f.id);
- });
-
- if(this.buttons.length > 0){
- // tables are required to maintain order and for correct IE layout
- var tb = this.el.createChild({cls:'x-form-btns-ct', cn: {
- cls:"x-form-btns x-form-btns-"+this.buttonAlign,
- html:'<table cellspacing="0"><tbody><tr></tr></tbody></table><div class="x-clear"></div>'
- }}, null, true);
- var tr = tb.getElementsByTagName('tr')[0];
- for(var i = 0, len = this.buttons.length; i < len; i++) {
- var b = this.buttons[i];
- var td = document.createElement('td');
- td.className = 'x-form-btn-td';
- b.render(tr.appendChild(td));
- }
- }
- if(this.monitorValid){ // initialize after render
- this.startMonitoring();
- }
- this.fireEvent('rendered', this);
- return this;
- },
-
- /**
- * Adds a button to the footer of the form - this <b>must</b> be called before the form is rendered.
- * @param {String/Object} config A string becomes the button text, an object can either be a Button config
- * object or a valid Roo.DomHelper element config
- * @param {Function} handler The function called when the button is clicked
- * @param {Object} scope (optional) The scope of the handler function
- * @return {Roo.Button}
- */
- addButton : function(config, handler, scope){
- var bc = {
- handler: handler,
- scope: scope,
- minWidth: this.minButtonWidth,
- hideParent:true
- };
- if(typeof config == "string"){
- bc.text = config;
- }else{
- Roo.apply(bc, config);
- }
- var btn = new Roo.Button(null, bc);
- this.buttons.push(btn);
- return btn;
- },
-
- /**
- * Adds a series of form elements (using the xtype property as the factory method.
- * Valid xtypes are: TextField, TextArea .... Button, Layout, FieldSet, Column, (and 'end' to close a block)
- * @param {Object} config
- */
-
- addxtype : function()
- {
- var ar = Array.prototype.slice.call(arguments, 0);
- var ret = false;
- for(var i = 0; i < ar.length; i++) {
- if (!ar[i]) {
- continue; // skip -- if this happends something invalid got sent, we
- // should ignore it, as basically that interface element will not show up
- // and that should be pretty obvious!!
- }
-
- if (Roo.form[ar[i].xtype]) {
- ar[i].form = this;
- var fe = Roo.factory(ar[i], Roo.form);
- if (!ret) {
- ret = fe;
- }
- fe.form = this;
- if (fe.store) {
- fe.store.form = this;
- }
- if (fe.isLayout) {
-
- this.start(fe);
- this.allItems.push(fe);
- if (fe.items && fe.addxtype) {
- fe.addxtype.apply(fe, fe.items);
- delete fe.items;
- }
- this.end();
- continue;
- }
-
-
-
- this.add(fe);
- // console.log('adding ' + ar[i].xtype);
- }
- if (ar[i].xtype == 'Button') {
- //console.log('adding button');
- //console.log(ar[i]);
- this.addButton(ar[i]);
- this.allItems.push(fe);
- continue;
- }
-
- if (ar[i].xtype == 'end') { // so we can add fieldsets... / layout etc.
- alert('end is not supported on xtype any more, use items');
- // this.end();
- // //console.log('adding end');
- }
-
- }
- return ret;
- },
-
- /**
- * Starts monitoring of the valid state of this form. Usually this is done by passing the config
- * option "monitorValid"
- */
- startMonitoring : function(){
- if(!this.bound){
- this.bound = true;
- Roo.TaskMgr.start({
- run : this.bindHandler,
- interval : this.monitorPoll || 200,
- scope: this
- });
- }
- },
-
- /**
- * Stops monitoring of the valid state of this form
- */
- stopMonitoring : function(){
- this.bound = false;
- },
-
- // private
- bindHandler : function(){
- if(!this.bound){
- return false; // stops binding
- }
- var valid = true;
- this.items.each(function(f){
- if(!f.isValid(true)){
- valid = false;
- return false;
- }
- });
- for(var i = 0, len = this.buttons.length; i < len; i++){
- var btn = this.buttons[i];
- if(btn.formBind === true && btn.disabled === valid){
- btn.setDisabled(!valid);
- }
- }
- this.fireEvent('clientvalidation', this, valid);
- }
-
-
-
-
-
-
-
-
-});
-
-
-// back compat
-Roo.Form = Roo.form.Form;
-/*
- * Based on:
- * Ext JS Library 1.1.1
- * Copyright(c) 2006-2007, Ext JS, LLC.
- *
- * Originally Released Under LGPL - original licence link has changed is not relivant.
- *
- * Fork - LGPL
- * <script type="text/javascript">
- */
-
- /**
- * @class Roo.form.Action
- * Internal Class used to handle form actions
- * @constructor
- * @param {Roo.form.BasicForm} el The form element or its id
- * @param {Object} config Configuration options
- */
-
-
-// define the action interface
-Roo.form.Action = function(form, options){
- this.form = form;
- this.options = options || {};
-};
-/**
- * Client Validation Failed
- * @const
- */
-Roo.form.Action.CLIENT_INVALID = 'client';
-/**
- * Server Validation Failed
- * @const
- */
- Roo.form.Action.SERVER_INVALID = 'server';
- /**
- * Connect to Server Failed
- * @const
- */
-Roo.form.Action.CONNECT_FAILURE = 'connect';
-/**
- * Reading Data from Server Failed
- * @const
- */
-Roo.form.Action.LOAD_FAILURE = 'load';
-
-Roo.form.Action.prototype = {
- type : 'default',
- failureType : undefined,
- response : undefined,
- result : undefined,
-
- // interface method
- run : function(options){
-
- },
-
- // interface method
- success : function(response){
-
- },
-
- // interface method
- handleResponse : function(response){
-
- },
-
- // default connection failure
- failure : function(response){
- this.response = response;
- this.failureType = Roo.form.Action.CONNECT_FAILURE;
- this.form.afterAction(this, false);
- },
-
- processResponse : function(response){
- this.response = response;
- if(!response.responseText){
- return true;
- }
- this.result = this.handleResponse(response);
- return this.result;
- },
-
- // utility functions used internally
- getUrl : function(appendParams){
- var url = this.options.url || this.form.url || this.form.el.dom.action;
- if(appendParams){
- var p = this.getParams();
- if(p){
- url += (url.indexOf('?') != -1 ? '&' : '?') + p;
- }
- }
- return url;
- },
-
- getMethod : function(){
- return (this.options.method || this.form.method || this.form.el.dom.method || 'POST').toUpperCase();
- },
-
- getParams : function(){
- var bp = this.form.baseParams;
- var p = this.options.params;
- if(p){
- if(typeof p == "object"){
- p = Roo.urlEncode(Roo.applyIf(p, bp));
- }else if(typeof p == 'string' && bp){
- p += '&' + Roo.urlEncode(bp);
- }
- }else if(bp){
- p = Roo.urlEncode(bp);
- }
- return p;
- },
-
- createCallback : function(){
- return {
- success: this.success,
- failure: this.failure,
- scope: this,
- timeout: (this.form.timeout*1000),
- upload: this.form.fileUpload ? this.success : undefined
- };
- }
-};
-
-Roo.form.Action.Submit = function(form, options){
- Roo.form.Action.Submit.superclass.constructor.call(this, form, options);
-};
-
-Roo.extend(Roo.form.Action.Submit, Roo.form.Action, {
- type : 'submit',
-
- run : function()
- {
- // run get Values on the form, so it syncs any secondary forms.
- this.form.getValues();
-
- var o = this.options;
- var method = this.getMethod();
- var isPost = method == 'POST';
- if(o.clientValidation === false || this.form.isValid()){
- Roo.Ajax.request(Roo.apply(this.createCallback(), {
- form:this.form.el.dom,
- url:this.getUrl(!isPost),
- method: method,
- params:isPost ? this.getParams() : null,
- isUpload: this.form.fileUpload
- }));
-
- }else if (o.clientValidation !== false){ // client validation failed
- this.failureType = Roo.form.Action.CLIENT_INVALID;
- this.form.afterAction(this, false);
- }
- },
-
- success : function(response){
- var result = this.processResponse(response);
- if(result === true || result.success){
- this.form.afterAction(this, true);
- return;
- }
- if(result.errors){
- this.form.markInvalid(result.errors);
- this.failureType = Roo.form.Action.SERVER_INVALID;
- }
- this.form.afterAction(this, false);
- },
-
- handleResponse : function(response){
- if(this.form.errorReader){
- var rs = this.form.errorReader.read(response);
- var errors = [];
- if(rs.records){
- for(var i = 0, len = rs.records.length; i < len; i++) {
- var r = rs.records[i];
- errors[i] = r.data;
- }
- }
- if(errors.length < 1){
- errors = null;
- }
- return {
- success : rs.success,
- errors : errors
- };
- }
- var ret = false;
- try {
- ret = Roo.decode(response.responseText);
- } catch (e) {
- ret = {
- success: false,
- errorMsg: "Failed to read server message: " + (response ? response.responseText : ' - no message'),
- errors : []
- };
- }
- return ret;
-
- }
-});
-
-
-Roo.form.Action.Load = function(form, options){
- Roo.form.Action.Load.superclass.constructor.call(this, form, options);
- this.reader = this.form.reader;
-};
-
-Roo.extend(Roo.form.Action.Load, Roo.form.Action, {
- type : 'load',
-
- run : function(){
- Roo.Ajax.request(Roo.apply(
- this.createCallback(), {
- method:this.getMethod(),
- url:this.getUrl(false),
- params:this.getParams()
- }));
- },
-
- success : function(response){
- var result = this.processResponse(response);
- if(result === true || !result.success || !result.data){
- this.failureType = Roo.form.Action.LOAD_FAILURE;
- this.form.afterAction(this, false);
- return;
- }
- this.form.clearInvalid();
- this.form.setValues(result.data);
- this.form.afterAction(this, true);
- },
-
- handleResponse : function(response){
- if(this.form.reader){
- var rs = this.form.reader.read(response);
- var data = rs.records && rs.records[0] ? rs.records[0].data : null;
- return {
- success : rs.success,
- data : data
- };
- }
- return Roo.decode(response.responseText);
- }
-});
-
-Roo.form.Action.ACTION_TYPES = {
- 'load' : Roo.form.Action.Load,
- 'submit' : Roo.form.Action.Submit
-};/*
- * Based on:
- * Ext JS Library 1.1.1
- * Copyright(c) 2006-2007, Ext JS, LLC.
- *
- * Originally Released Under LGPL - original licence link has changed is not relivant.
- *
- * Fork - LGPL
- * <script type="text/javascript">
- */
-
-/**
- * @class Roo.form.Layout
- * @extends Roo.Component
- * Creates a container for layout and rendering of fields in an {@link Roo.form.Form}.
- * @constructor
- * @param {Object} config Configuration options
- */
-Roo.form.Layout = function(config){
- var xitems = [];
- if (config.items) {
- xitems = config.items;
- delete config.items;
- }
- Roo.form.Layout.superclass.constructor.call(this, config);
- this.stack = [];
- Roo.each(xitems, this.addxtype, this);
-
-};
-
-Roo.extend(Roo.form.Layout, Roo.Component, {
- /**
- * @cfg {String/Object} autoCreate
- * A DomHelper element spec used to autocreate the layout (defaults to {tag: 'div', cls: 'x-form-ct'})
- */
- /**
- * @cfg {String/Object/Function} style
- * A style specification string, e.g. "width:100px", or object in the form {width:"100px"}, or
- * a function which returns such a specification.
- */
- /**
- * @cfg {String} labelAlign
- * Valid values are "left," "top" and "right" (defaults to "left")
- */
- /**
- * @cfg {Number} labelWidth
- * Fixed width in pixels of all field labels (defaults to undefined)
- */
- /**
- * @cfg {Boolean} clear
- * True to add a clearing element at the end of this layout, equivalent to CSS clear: both (defaults to true)
- */
- clear : true,
- /**
- * @cfg {String} labelSeparator
- * The separator to use after field labels (defaults to ':')
- */
- labelSeparator : ':',
- /**
- * @cfg {Boolean} hideLabels
- * True to suppress the display of field labels in this layout (defaults to false)
- */
- hideLabels : false,
-
- // private
- defaultAutoCreate : {tag: 'div', cls: 'x-form-ct'},
-
- isLayout : true,
-
- // private
- onRender : function(ct, position){
- if(this.el){ // from markup
- this.el = Roo.get(this.el);
- }else { // generate
- var cfg = this.getAutoCreate();
- this.el = ct.createChild(cfg, position);
- }
- if(this.style){
- this.el.applyStyles(this.style);
- }
- if(this.labelAlign){
- this.el.addClass('x-form-label-'+this.labelAlign);
- }
- if(this.hideLabels){
- this.labelStyle = "display:none";
- this.elementStyle = "padding-left:0;";
- }else{
- if(typeof this.labelWidth == 'number'){
- this.labelStyle = "width:"+this.labelWidth+"px;";
- this.elementStyle = "padding-left:"+((this.labelWidth+(typeof this.labelPad == 'number' ? this.labelPad : 5))+'px')+";";
- }
- if(this.labelAlign == 'top'){
- this.labelStyle = "width:auto;";
- this.elementStyle = "padding-left:0;";
- }
- }
- var stack = this.stack;
- var slen = stack.length;
- if(slen > 0){
- if(!this.fieldTpl){
- var t = new Roo.Template(
- '<div class="x-form-item {5}">',
- '<label for="{0}" style="{2}">{1}{4}</label>',
- '<div class="x-form-element" id="x-form-el-{0}" style="{3}">',
- '</div>',
- '</div><div class="x-form-clear-left"></div>'
- );
- t.disableFormats = true;
- t.compile();
- Roo.form.Layout.prototype.fieldTpl = t;
- }
- for(var i = 0; i < slen; i++) {
- if(stack[i].isFormField){
- this.renderField(stack[i]);
- }else{
- this.renderComponent(stack[i]);
- }
- }
- }
- if(this.clear){
- this.el.createChild({cls:'x-form-clear'});
- }
- },
-
- // private
- renderField : function(f){
- f.fieldEl = Roo.get(this.fieldTpl.append(this.el, [
- f.id, //0
- f.fieldLabel, //1
- f.labelStyle||this.labelStyle||'', //2
- this.elementStyle||'', //3
- typeof f.labelSeparator == 'undefined' ? this.labelSeparator : f.labelSeparator, //4
- f.itemCls||this.itemCls||'' //5
- ], true).getPrevSibling());
- },
-
- // private
- renderComponent : function(c){
- c.render(c.isLayout ? this.el : this.el.createChild());
- },
- /**
- * Adds a object form elements (using the xtype property as the factory method.)
- * Valid xtypes are: TextField, TextArea .... Button, Layout, FieldSet, Column
- * @param {Object} config
- */
- addxtype : function(o)
- {
- // create the lement.
- o.form = this.form;
- var fe = Roo.factory(o, Roo.form);
- this.form.allItems.push(fe);
- this.stack.push(fe);
-
- if (fe.isFormField) {
- this.form.items.add(fe);
- }
-
- return fe;
- }
-});
-
-/**
- * @class Roo.form.Column
- * @extends Roo.form.Layout
- * Creates a column container for layout and rendering of fields in an {@link Roo.form.Form}.
- * @constructor
- * @param {Object} config Configuration options
- */
-Roo.form.Column = function(config){
- Roo.form.Column.superclass.constructor.call(this, config);
-};
-
-Roo.extend(Roo.form.Column, Roo.form.Layout, {
- /**
- * @cfg {Number/String} width
- * The fixed width of the column in pixels or CSS value (defaults to "auto")
- */
- /**
- * @cfg {String/Object} autoCreate
- * A DomHelper element spec used to autocreate the column (defaults to {tag: 'div', cls: 'x-form-ct x-form-column'})
- */
-
- // private
- defaultAutoCreate : {tag: 'div', cls: 'x-form-ct x-form-column'},
-
- // private
- onRender : function(ct, position){
- Roo.form.Column.superclass.onRender.call(this, ct, position);
- if(this.width){
- this.el.setWidth(this.width);
- }
- }
-});
-
-
-/**
- * @class Roo.form.Row
- * @extends Roo.form.Layout
- * Creates a row container for layout and rendering of fields in an {@link Roo.form.Form}.
- * @constructor
- * @param {Object} config Configuration options
- */
-
-
-Roo.form.Row = function(config){
- Roo.form.Row.superclass.constructor.call(this, config);
-};
-
-Roo.extend(Roo.form.Row, Roo.form.Layout, {
- /**
- * @cfg {Number/String} width
- * The fixed width of the column in pixels or CSS value (defaults to "auto")
- */
- /**
- * @cfg {Number/String} height
- * The fixed height of the column in pixels or CSS value (defaults to "auto")
- */
- defaultAutoCreate : {tag: 'div', cls: 'x-form-ct x-form-row'},
-
- padWidth : 20,
- // private
- onRender : function(ct, position){
- //console.log('row render');
- if(!this.rowTpl){
- var t = new Roo.Template(
- '<div class="x-form-item {5}" style="float:left;width:{6}px">',
- '<label for="{0}" style="{2}">{1}{4}</label>',
- '<div class="x-form-element" id="x-form-el-{0}" style="{3}">',
- '</div>',
- '</div>'
- );
- t.disableFormats = true;
- t.compile();
- Roo.form.Layout.prototype.rowTpl = t;
- }
- this.fieldTpl = this.rowTpl;
-
- //console.log('lw' + this.labelWidth +', la:' + this.labelAlign);
- var labelWidth = 100;
-
- if ((this.labelAlign != 'top')) {
- if (typeof this.labelWidth == 'number') {
- labelWidth = this.labelWidth
- }
- this.padWidth = 20 + labelWidth;
-
- }
-
- Roo.form.Column.superclass.onRender.call(this, ct, position);
- if(this.width){
- this.el.setWidth(this.width);
- }
- if(this.height){
- this.el.setHeight(this.height);
- }
- },
-
- // private
- renderField : function(f){
- f.fieldEl = this.fieldTpl.append(this.el, [
- f.id, f.fieldLabel,
- f.labelStyle||this.labelStyle||'',
- this.elementStyle||'',
- typeof f.labelSeparator == 'undefined' ? this.labelSeparator : f.labelSeparator,
- f.itemCls||this.itemCls||'',
- f.width ? f.width + this.padWidth : 160 + this.padWidth
- ],true);
- }
-});
-
-
-/**
- * @class Roo.form.FieldSet
- * @extends Roo.form.Layout
- * Creates a fieldset container for layout and rendering of fields in an {@link Roo.form.Form}.
- * @constructor
- * @param {Object} config Configuration options
- */
-Roo.form.FieldSet = function(config){
- Roo.form.FieldSet.superclass.constructor.call(this, config);
-};
-
-Roo.extend(Roo.form.FieldSet, Roo.form.Layout, {
- /**
- * @cfg {String} legend
- * The text to display as the legend for the FieldSet (defaults to '')
- */
- /**
- * @cfg {String/Object} autoCreate
- * A DomHelper element spec used to autocreate the fieldset (defaults to {tag: 'fieldset', cn: {tag:'legend'}})
- */
-
- // private
- defaultAutoCreate : {tag: 'fieldset', cn: {tag:'legend'}},
-
- // private
- onRender : function(ct, position){
- Roo.form.FieldSet.superclass.onRender.call(this, ct, position);
- if(this.legend){
- this.setLegend(this.legend);
- }
- },
-
- // private
- setLegend : function(text){
- if(this.rendered){
- this.el.child('legend').update(text);
- }
- }
-});/*
- * Based on:
- * Ext JS Library 1.1.1
- * Copyright(c) 2006-2007, Ext JS, LLC.
- *
- * Originally Released Under LGPL - original licence link has changed is not relivant.
- *
- * Fork - LGPL
- * <script type="text/javascript">
- */
-/**
- * @class Roo.form.VTypes
- * Overridable validation definitions. The validations provided are basic and intended to be easily customizable and extended.
- * @singleton
- */
-Roo.form.VTypes = function(){
- // closure these in so they are only created once.
- var alpha = /^[a-zA-Z_]+$/;
- var alphanum = /^[a-zA-Z0-9_]+$/;
- var email = /^([\w]+)(.[\w]+)*@([\w-]+\.){1,5}([A-Za-z]){2,4}$/;
- var url = /(((https?)|(ftp)):\/\/([\-\w]+\.)+\w{2,3}(\/[%\-\w]+(\.\w{2,})?)*(([\w\-\.\?\\\/+@&#;`~=%!]*)(\.\w{2,})?)*\/?)/i;
-
- // All these messages and functions are configurable
- return {
- /**
- * The function used to validate email addresses
- * @param {String} value The email address
- */
- 'email' : function(v){
- return email.test(v);
- },
- /**
- * The error text to display when the email validation function returns false
- * @type String
- */
- 'emailText' : 'This field should be an e-mail address in the format "user@domain.com"',
- /**
- * The keystroke filter mask to be applied on email input
- * @type RegExp
- */
- 'emailMask' : /[a-z0-9_\.\-@]/i,
-
- /**
- * The function used to validate URLs
- * @param {String} value The URL
- */
- 'url' : function(v){
- return url.test(v);
- },
- /**
- * The error text to display when the url validation function returns false
- * @type String
- */
- 'urlText' : 'This field should be a URL in the format "http:/'+'/www.domain.com"',
-
- /**
- * The function used to validate alpha values
- * @param {String} value The value
- */
- 'alpha' : function(v){
- return alpha.test(v);
- },
- /**
- * The error text to display when the alpha validation function returns false
- * @type String
- */
- 'alphaText' : 'This field should only contain letters and _',
- /**
- * The keystroke filter mask to be applied on alpha input
- * @type RegExp
- */
- 'alphaMask' : /[a-z_]/i,
-
- /**
- * The function used to validate alphanumeric values
- * @param {String} value The value
- */
- 'alphanum' : function(v){
- return alphanum.test(v);
- },
- /**
- * The error text to display when the alphanumeric validation function returns false
- * @type String
- */
- 'alphanumText' : 'This field should only contain letters, numbers and _',
- /**
- * The keystroke filter mask to be applied on alphanumeric input
- * @type RegExp
- */
- 'alphanumMask' : /[a-z0-9_]/i
- };
-}();//<script type="text/javascript">
-
-/**
- * @class Roo.form.FCKeditor
- * @extends Roo.form.TextArea
- * Wrapper around the FCKEditor http://www.fckeditor.net
- * @constructor
- * Creates a new FCKeditor
- * @param {Object} config Configuration options
- */
-Roo.form.FCKeditor = function(config){
- Roo.form.FCKeditor.superclass.constructor.call(this, config);
- this.addEvents({
- /**
- * @event editorinit
- * Fired when the editor is initialized - you can add extra handlers here..
- * @param {FCKeditor} this
- * @param {Object} the FCK object.
- */
- editorinit : true
- });
-
-
-};
-Roo.form.FCKeditor.editors = { };
-Roo.extend(Roo.form.FCKeditor, Roo.form.TextArea,
-{
- //defaultAutoCreate : {
- // tag : "textarea",style : "width:100px;height:60px;" ,autocomplete : "off"
- //},
- // private
- /**
- * @cfg {Object} fck options - see fck manual for details.
- */
- fckconfig : false,
-
- /**
- * @cfg {Object} fck toolbar set (Basic or Default)
- */
- toolbarSet : 'Basic',
- /**
- * @cfg {Object} fck BasePath
- */
- basePath : '/fckeditor/',
-
-
- frame : false,
-
- value : '',
-
-
- onRender : function(ct, position)
- {
- if(!this.el){
- this.defaultAutoCreate = {
- tag: "textarea",
- style:"width:300px;height:60px;",
- autocomplete: "off"
- };
- }
- Roo.form.FCKeditor.superclass.onRender.call(this, ct, position);
- /*
- if(this.grow){
- this.textSizeEl = Roo.DomHelper.append(document.body, {tag: "pre", cls: "x-form-grow-sizer"});
- if(this.preventScrollbars){
- this.el.setStyle("overflow", "hidden");
- }
- this.el.setHeight(this.growMin);
- }
- */
- //console.log('onrender' + this.getId() );
- Roo.form.FCKeditor.editors[this.getId()] = this;
-
-
- this.replaceTextarea() ;
-
- },
-
- getEditor : function() {
- return this.fckEditor;
- },
- /**
- * Sets a data value into the field and validates it. To set the value directly without validation see {@link #setRawValue}.
- * @param {Mixed} value The value to set
- */
-
-
- setValue : function(value)
- {
- //console.log('setValue: ' + value);
-
- if(typeof(value) == 'undefined') { // not sure why this is happending...
- return;
- }
- Roo.form.FCKeditor.superclass.setValue.apply(this,[value]);
-
- //if(!this.el || !this.getEditor()) {
- // this.value = value;
- //this.setValue.defer(100,this,[value]);
- // return;
- //}
-
- if(!this.getEditor()) {
- return;
- }
-
- this.getEditor().SetData(value);
-
- //
-
- },
-
- /**
- * Returns the normalized data value (undefined or emptyText will be returned as ''). To return the raw value see {@link #getRawValue}.
- * @return {Mixed} value The field value
- */
- getValue : function()
- {
-
- if (this.frame && this.frame.dom.style.display == 'none') {
- return Roo.form.FCKeditor.superclass.getValue.call(this);
- }
-
- if(!this.el || !this.getEditor()) {
-
- // this.getValue.defer(100,this);
- return this.value;
- }
-
-
- var value=this.getEditor().GetData();
- Roo.form.FCKeditor.superclass.setValue.apply(this,[value]);
- return Roo.form.FCKeditor.superclass.getValue.call(this);
-
-
- },
-
- /**
- * Returns the raw data value which may or may not be a valid, defined value. To return a normalized value see {@link #getValue}.
- * @return {Mixed} value The field value
- */
- getRawValue : function()
- {
- if (this.frame && this.frame.dom.style.display == 'none') {
- return Roo.form.FCKeditor.superclass.getRawValue.call(this);
- }
-
- if(!this.el || !this.getEditor()) {
- //this.getRawValue.defer(100,this);
- return this.value;
- return;
- }
-
-
-
- var value=this.getEditor().GetData();
- Roo.form.FCKeditor.superclass.setRawValue.apply(this,[value]);
- return Roo.form.FCKeditor.superclass.getRawValue.call(this);
-
- },
-
- setSize : function(w,h) {
-
-
-
- //if (this.frame && this.frame.dom.style.display == 'none') {
- // Roo.form.FCKeditor.superclass.setSize.apply(this, [w, h]);
- // return;
- //}
- //if(!this.el || !this.getEditor()) {
- // this.setSize.defer(100,this, [w,h]);
- // return;
- //}
-
-
-
- Roo.form.FCKeditor.superclass.setSize.apply(this, [w, h]);
-
- this.frame.dom.setAttribute('width', w);
- this.frame.dom.setAttribute('height', h);
- this.frame.setSize(w,h);
-
- },
-
- toggleSourceEdit : function(value) {
-
-
-
- this.el.dom.style.display = value ? '' : 'none';
- this.frame.dom.style.display = value ? 'none' : '';
-
- },
-
-
- focus: function(tag)
- {
- if (this.frame.dom.style.display == 'none') {
- return Roo.form.FCKeditor.superclass.focus.call(this);
- }
- if(!this.el || !this.getEditor()) {
- this.focus.defer(100,this, [tag]);
- return;
- }
-
-
-
-
- var tgs = this.getEditor().EditorDocument.getElementsByTagName(tag);
- this.getEditor().Focus();
- if (tgs.length) {
- if (!this.getEditor().Selection.GetSelection()) {
- this.focus.defer(100,this, [tag]);
- return;
- }
-
-
- var r = this.getEditor().EditorDocument.createRange();
- r.setStart(tgs[0],0);
- r.setEnd(tgs[0],0);
- this.getEditor().Selection.GetSelection().removeAllRanges();
- this.getEditor().Selection.GetSelection().addRange(r);
- this.getEditor().Focus();
- }
-
- },
-
-
-
- replaceTextarea : function()
- {
- if ( document.getElementById( this.getId() + '___Frame' ) )
- return ;
- //if ( !this.checkBrowser || this._isCompatibleBrowser() )
- //{
- // We must check the elements firstly using the Id and then the name.
- var oTextarea = document.getElementById( this.getId() );
-
- var colElementsByName = document.getElementsByName( this.getId() ) ;
-
- oTextarea.style.display = 'none' ;
-
- if ( oTextarea.tabIndex ) {
- this.TabIndex = oTextarea.tabIndex ;
- }
-
- this._insertHtmlBefore( this._getConfigHtml(), oTextarea ) ;
- this._insertHtmlBefore( this._getIFrameHtml(), oTextarea ) ;
- this.frame = Roo.get(this.getId() + '___Frame')
- },
-
- _getConfigHtml : function()
- {
- var sConfig = '' ;
-
- for ( var o in this.fckconfig ) {
- sConfig += sConfig.length > 0 ? '&' : '';
- sConfig += encodeURIComponent( o ) + '=' + encodeURIComponent( this.fckconfig[o] ) ;
- }
-
- return '<input type="hidden" id="' + this.getId() + '___Config" value="' + sConfig + '" style="display:none" />' ;
- },
-
-
- _getIFrameHtml : function()
- {
- var sFile = 'fckeditor.html' ;
- /* no idea what this is about..
- try
- {
- if ( (/fcksource=true/i).test( window.top.location.search ) )
- sFile = 'fckeditor.original.html' ;
- }
- catch (e) {
- */
-
- var sLink = this.basePath + 'editor/' + sFile + '?InstanceName=' + encodeURIComponent( this.getId() ) ;
- sLink += this.toolbarSet ? ( '&Toolbar=' + this.toolbarSet) : '';
-
-
- var html = '<iframe id="' + this.getId() +
- '___Frame" src="' + sLink +
- '" width="' + this.width +
- '" height="' + this.height + '"' +
- (this.tabIndex ? ' tabindex="' + this.tabIndex + '"' :'' ) +
- ' frameborder="0" scrolling="no"></iframe>' ;
-
- return html ;
- },
-
- _insertHtmlBefore : function( html, element )
- {
- if ( element.insertAdjacentHTML ) {
- // IE
- element.insertAdjacentHTML( 'beforeBegin', html ) ;
- } else { // Gecko
- var oRange = document.createRange() ;
- oRange.setStartBefore( element ) ;
- var oFragment = oRange.createContextualFragment( html );
- element.parentNode.insertBefore( oFragment, element ) ;
- }
- }
-
-
-
-
-
-
-
-
-});
-
-//Roo.reg('fckeditor', Roo.form.FCKeditor);
-
-function FCKeditor_OnComplete(editorInstance){
- var f = Roo.form.FCKeditor.editors[editorInstance.Name];
- f.fckEditor = editorInstance;
- //console.log("loaded");
- f.fireEvent('editorinit', f, editorInstance);
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-//<script type="text/javascript">
-/**
- * @class Roo.form.GridField
- * @extends Roo.form.Field
- * Embed a grid (or editable grid into a form)
- * STATUS ALPHA
- *
- * This embeds a grid in a form, the value of the field should be the json encoded array of rows
- * it needs
- * xgrid.store = Roo.data.Store
- * xgrid.store.proxy = Roo.data.MemoryProxy (data = [] )
- * xgrid.store.reader = Roo.data.JsonReader
- *
- *
- * @constructor
- * Creates a new GridField
- * @param {Object} config Configuration options
- */
-Roo.form.GridField = function(config){
- Roo.form.GridField.superclass.constructor.call(this, config);
-
-};
-
-Roo.extend(Roo.form.GridField, Roo.form.Field, {
- /**
- * @cfg {Number} width - used to restrict width of grid..
- */
- width : 100,
- /**
- * @cfg {Number} height - used to restrict height of grid..
- */
- height : 50,
- /**
- * @cfg {Object} xgrid (xtype'd description of grid) { xtype : 'Grid', dataSource: .... }
- *
- *}
- */
- xgrid : false,
- /**
- * @cfg {String/Object} autoCreate A DomHelper element spec, or true for a default element spec (defaults to
- * {tag: "input", type: "checkbox", autocomplete: "off"})
- */
- // defaultAutoCreate : { tag: 'div' },
- defaultAutoCreate : { tag: 'input', type: 'hidden', autocomplete: 'off'},
- /**
- * @cfg {String} addTitle Text to include for adding a title.
- */
- addTitle : false,
- //
- onResize : function(){
- Roo.form.Field.superclass.onResize.apply(this, arguments);
- },
-
- initEvents : function(){
- // Roo.form.Checkbox.superclass.initEvents.call(this);
- // has no events...
-
- },
-
-
- getResizeEl : function(){
- return this.wrap;
- },
-
- getPositionEl : function(){
- return this.wrap;
- },
-
- // private
- onRender : function(ct, position){
-
- this.style = this.style || 'overflow: hidden; border:1px solid #c3daf9;';
- var style = this.style;
- delete this.style;
-
- Roo.form.GridField.superclass.onRender.call(this, ct, position);
- this.wrap = this.el.wrap({cls: ''}); // not sure why ive done thsi...
- this.viewEl = this.wrap.createChild({ tag: 'div' });
- if (style) {
- this.viewEl.applyStyles(style);
- }
- if (this.width) {
- this.viewEl.setWidth(this.width);
- }
- if (this.height) {
- this.viewEl.setHeight(this.height);
- }
- //if(this.inputValue !== undefined){
- //this.setValue(this.value);
-
-
- this.grid = new Roo.grid[this.xgrid.xtype](this.viewEl, this.xgrid);
-
-
- this.grid.render();
- this.grid.getDataSource().on('remove', this.refreshValue, this);
- this.grid.getDataSource().on('update', this.refreshValue, this);
- this.grid.on('afteredit', this.refreshValue, this);
-
- },
-
-
- /**
- * Sets the value of the item.
- * @param {String} either an object or a string..
- */
- setValue : function(v){
- //this.value = v;
- v = v || []; // empty set..
- // this does not seem smart - it really only affects memoryproxy grids..
- if (this.grid && this.grid.getDataSource() && typeof(v) != 'undefined') {
- var ds = this.grid.getDataSource();
- // assumes a json reader..
- var data = {}
- data[ds.reader.meta.root ] = typeof(v) == 'string' ? Roo.decode(v) : v;
- ds.loadData( data);
- }
- Roo.form.GridField.superclass.setValue.call(this, v);
- this.refreshValue();
- // should load data in the grid really....
- },
-
- // private
- refreshValue: function() {
- var val = [];
- this.grid.getDataSource().each(function(r) {
- val.push(r.data);
- });
- this.el.dom.value = Roo.encode(val);
- }
-
-
-
-
-});/*
- * Based on:
- * Ext JS Library 1.1.1
- * Copyright(c) 2006-2007, Ext JS, LLC.
- *
- * Originally Released Under LGPL - original licence link has changed is not relivant.
- *
- * Fork - LGPL
- * <script type="text/javascript">
- */
-/**
- * @class Roo.form.DisplayField
- * @extends Roo.form.Field
- * A generic Field to display non-editable data.
- * @constructor
- * Creates a new Display Field item.
- * @param {Object} config Configuration options
- */
-Roo.form.DisplayField = function(config){
- Roo.form.DisplayField.superclass.constructor.call(this, config);
-
-};
-
-Roo.extend(Roo.form.DisplayField, Roo.form.TextField, {
- inputType: 'hidden',
- allowBlank: true,
- readOnly: true,
-
-
- /**
- * @cfg {String} focusClass The CSS class to use when the checkbox receives focus (defaults to undefined)
- */
- focusClass : undefined,
- /**
- * @cfg {String} fieldClass The default CSS class for the checkbox (defaults to "x-form-field")
- */
- fieldClass: 'x-form-field',
-
- /**
- * @cfg {Function} valueRenderer The renderer for the field (so you can reformat output). should return raw HTML
- */
- valueRenderer: undefined,
-
- width: 100,
- /**
- * @cfg {String/Object} autoCreate A DomHelper element spec, or true for a default element spec (defaults to
- * {tag: "input", type: "checkbox", autocomplete: "off"})
- */
-
- // defaultAutoCreate : { tag: 'input', type: 'hidden', autocomplete: 'off'},
-
- onResize : function(){
- Roo.form.DisplayField.superclass.onResize.apply(this, arguments);
-
- },
-
- initEvents : function(){
- // Roo.form.Checkbox.superclass.initEvents.call(this);
- // has no events...
-
- },
-
-
- getResizeEl : function(){
- return this.wrap;
- },
-
- getPositionEl : function(){
- return this.wrap;
- },
-
- // private
- onRender : function(ct, position){
-
- Roo.form.DisplayField.superclass.onRender.call(this, ct, position);
- //if(this.inputValue !== undefined){
- this.wrap = this.el.wrap();
-
- this.viewEl = this.wrap.createChild({ tag: 'div'});
-
- if (this.bodyStyle) {
- this.viewEl.applyStyles(this.bodyStyle);
- }
- //this.viewEl.setStyle('padding', '2px');
-
- this.setValue(this.value);
-
- },
-/*
- // private
- initValue : Roo.emptyFn,
-
- */
-
- // private
- onClick : function(){
-
- },
-
- /**
- * Sets the checked state of the checkbox.
- * @param {Boolean/String} checked True, 'true', '1', or 'on' to check the checkbox, any other value will uncheck it.
- */
- setValue : function(v){
- this.value = v;
- var html = this.valueRenderer ? this.valueRenderer(v) : String.format('{0}', v);
- // this might be called before we have a dom element..
- if (!this.viewEl) {
- return;
- }
- this.viewEl.dom.innerHTML = html;
- Roo.form.DisplayField.superclass.setValue.call(this, v);
-
- }
-});//<script type="text/javasscript">
-
-
-/**
- * @class Roo.DDView
- * A DnD enabled version of Roo.View.
- * @param {Element/String} container The Element in which to create the View.
- * @param {String} tpl The template string used to create the markup for each element of the View
- * @param {Object} config The configuration properties. These include all the config options of
- * {@link Roo.View} plus some specific to this class.<br>
- * <p>
- * Drag/drop is implemented by adding {@link Roo.data.Record}s to the target DDView. If copying is
- * not being performed, the original {@link Roo.data.Record} is removed from the source DDView.<br>
- * <p>
- * The following extra CSS rules are needed to provide insertion point highlighting:<pre><code>
-.x-view-drag-insert-above {
- border-top:1px dotted #3366cc;
-}
-.x-view-drag-insert-below {
- border-bottom:1px dotted #3366cc;
-}
-</code></pre>
- *
- */
-
-Roo.DDView = function(container, tpl, config) {
- Roo.DDView.superclass.constructor.apply(this, arguments);
- this.getEl().setStyle("outline", "0px none");
- this.getEl().unselectable();
- if (this.dragGroup) {
- this.setDraggable(this.dragGroup.split(","));
- }
- if (this.dropGroup) {
- this.setDroppable(this.dropGroup.split(","));
- }
- if (this.deletable) {
- this.setDeletable();
- }
- this.isDirtyFlag = false;
- this.addEvents({
- "drop" : true
- });
-};
-
-Roo.extend(Roo.DDView, Roo.View, {
-/** @cfg {String/Array} dragGroup The ddgroup name(s) for the View's DragZone. */
-/** @cfg {String/Array} dropGroup The ddgroup name(s) for the View's DropZone. */
-/** @cfg {Boolean} copy Causes drag operations to copy nodes rather than move. */
-/** @cfg {Boolean} allowCopy Causes ctrl/drag operations to copy nodes rather than move. */
-
- isFormField: true,
-
- reset: Roo.emptyFn,
-
- clearInvalid: Roo.form.Field.prototype.clearInvalid,
-
- validate: function() {
- return true;
- },
-
- destroy: function() {
- this.purgeListeners();
- this.getEl.removeAllListeners();
- this.getEl().remove();
- if (this.dragZone) {
- if (this.dragZone.destroy) {
- this.dragZone.destroy();
- }
- }
- if (this.dropZone) {
- if (this.dropZone.destroy) {
- this.dropZone.destroy();
- }
- }
- },
-
-/** Allows this class to be an Roo.form.Field so it can be found using {@link Roo.form.BasicForm#findField}. */
- getName: function() {
- return this.name;
- },
-
-/** Loads the View from a JSON string representing the Records to put into the Store. */
- setValue: function(v) {
- if (!this.store) {
- throw "DDView.setValue(). DDView must be constructed with a valid Store";
- }
- var data = {};
- data[this.store.reader.meta.root] = v ? [].concat(v) : [];
- this.store.proxy = new Roo.data.MemoryProxy(data);
- this.store.load();
- },
-
-/** @return {String} a parenthesised list of the ids of the Records in the View. */
- getValue: function() {
- var result = '(';
- this.store.each(function(rec) {
- result += rec.id + ',';
- });
- return result.substr(0, result.length - 1) + ')';
- },
-
- getIds: function() {
- var i = 0, result = new Array(this.store.getCount());
- this.store.each(function(rec) {
- result[i++] = rec.id;
- });
- return result;
- },
-
- isDirty: function() {
- return this.isDirtyFlag;
- },
-
-/**
- * Part of the Roo.dd.DropZone interface. If no target node is found, the
- * whole Element becomes the target, and this causes the drop gesture to append.
- */
- getTargetFromEvent : function(e) {
- var target = e.getTarget();
- while ((target !== null) && (target.parentNode != this.el.dom)) {
- target = target.parentNode;
- }
- if (!target) {
- target = this.el.dom.lastChild || this.el.dom;
- }
- return target;
- },
-
-/**
- * Create the drag data which consists of an object which has the property "ddel" as
- * the drag proxy element.
- */
- getDragData : function(e) {
- var target = this.findItemFromChild(e.getTarget());
- if(target) {
- this.handleSelection(e);
- var selNodes = this.getSelectedNodes();
- var dragData = {
- source: this,
- copy: this.copy || (this.allowCopy && e.ctrlKey),
- nodes: selNodes,
- records: []
- };
- var selectedIndices = this.getSelectedIndexes();
- for (var i = 0; i < selectedIndices.length; i++) {
- dragData.records.push(this.store.getAt(selectedIndices[i]));
- }
- if (selNodes.length == 1) {
- dragData.ddel = target.cloneNode(true); // the div element
- } else {
- var div = document.createElement('div'); // create the multi element drag "ghost"
- div.className = 'multi-proxy';
- for (var i = 0, len = selNodes.length; i < len; i++) {
- div.appendChild(selNodes[i].cloneNode(true));
- }
- dragData.ddel = div;
- }
- //console.log(dragData)
- //console.log(dragData.ddel.innerHTML)
- return dragData;
- }
- //console.log('nodragData')
- return false;
- },
-
-/** Specify to which ddGroup items in this DDView may be dragged. */
- setDraggable: function(ddGroup) {
- if (ddGroup instanceof Array) {
- Roo.each(ddGroup, this.setDraggable, this);
- return;
- }
- if (this.dragZone) {
- this.dragZone.addToGroup(ddGroup);
- } else {
- this.dragZone = new Roo.dd.DragZone(this.getEl(), {
- containerScroll: true,
- ddGroup: ddGroup
-
- });
-// Draggability implies selection. DragZone's mousedown selects the element.
- if (!this.multiSelect) { this.singleSelect = true; }
-
-// Wire the DragZone's handlers up to methods in *this*
- this.dragZone.getDragData = this.getDragData.createDelegate(this);
- }
- },
-
-/** Specify from which ddGroup this DDView accepts drops. */
- setDroppable: function(ddGroup) {
- if (ddGroup instanceof Array) {
- Roo.each(ddGroup, this.setDroppable, this);
- return;
- }
- if (this.dropZone) {
- this.dropZone.addToGroup(ddGroup);
- } else {
- this.dropZone = new Roo.dd.DropZone(this.getEl(), {
- containerScroll: true,
- ddGroup: ddGroup
- });
-
-// Wire the DropZone's handlers up to methods in *this*
- this.dropZone.getTargetFromEvent = this.getTargetFromEvent.createDelegate(this);
- this.dropZone.onNodeEnter = this.onNodeEnter.createDelegate(this);
- this.dropZone.onNodeOver = this.onNodeOver.createDelegate(this);
- this.dropZone.onNodeOut = this.onNodeOut.createDelegate(this);
- this.dropZone.onNodeDrop = this.onNodeDrop.createDelegate(this);
- }
- },
-
-/** Decide whether to drop above or below a View node. */
- getDropPoint : function(e, n, dd){
- if (n == this.el.dom) { return "above"; }
- var t = Roo.lib.Dom.getY(n), b = t + n.offsetHeight;
- var c = t + (b - t) / 2;
- var y = Roo.lib.Event.getPageY(e);
- if(y <= c) {
- return "above";
- }else{
- return "below";
- }
- },
-
- onNodeEnter : function(n, dd, e, data){
- return false;
- },
-
- onNodeOver : function(n, dd, e, data){
- var pt = this.getDropPoint(e, n, dd);
- // set the insert point style on the target node
- var dragElClass = this.dropNotAllowed;
- if (pt) {
- var targetElClass;
- if (pt == "above"){
- dragElClass = n.previousSibling ? "x-tree-drop-ok-between" : "x-tree-drop-ok-above";
- targetElClass = "x-view-drag-insert-above";
- } else {
- dragElClass = n.nextSibling ? "x-tree-drop-ok-between" : "x-tree-drop-ok-below";
- targetElClass = "x-view-drag-insert-below";
- }
- if (this.lastInsertClass != targetElClass){
- Roo.fly(n).replaceClass(this.lastInsertClass, targetElClass);
- this.lastInsertClass = targetElClass;
- }
- }
- return dragElClass;
- },
-
- onNodeOut : function(n, dd, e, data){
- this.removeDropIndicators(n);
- },
-
- onNodeDrop : function(n, dd, e, data){
- if (this.fireEvent("drop", this, n, dd, e, data) === false) {
- return false;
- }
- var pt = this.getDropPoint(e, n, dd);
- var insertAt = (n == this.el.dom) ? this.nodes.length : n.nodeIndex;
- if (pt == "below") { insertAt++; }
- for (var i = 0; i < data.records.length; i++) {
- var r = data.records[i];
- var dup = this.store.getById(r.id);
- if (dup && (dd != this.dragZone)) {
- Roo.fly(this.getNode(this.store.indexOf(dup))).frame("red", 1);
- } else {
- if (data.copy) {
- this.store.insert(insertAt++, r.copy());
- } else {
- data.source.isDirtyFlag = true;
- r.store.remove(r);
- this.store.insert(insertAt++, r);
- }
- this.isDirtyFlag = true;
- }
- }
- this.dragZone.cachedTarget = null;
- return true;
- },
-
- removeDropIndicators : function(n){
- if(n){
- Roo.fly(n).removeClass([
- "x-view-drag-insert-above",
- "x-view-drag-insert-below"]);
- this.lastInsertClass = "_noclass";
- }
- },
-
-/**
- * Utility method. Add a delete option to the DDView's context menu.
- * @param {String} imageUrl The URL of the "delete" icon image.
- */
- setDeletable: function(imageUrl) {
- if (!this.singleSelect && !this.multiSelect) {
- this.singleSelect = true;
- }
- var c = this.getContextMenu();
- this.contextMenu.on("itemclick", function(item) {
- switch (item.id) {
- case "delete":
- this.remove(this.getSelectedIndexes());
- break;
- }
- }, this);
- this.contextMenu.add({
- icon: imageUrl,
- id: "delete",
- text: 'Delete'
- });
- },
-
-/** Return the context menu for this DDView. */
- getContextMenu: function() {
- if (!this.contextMenu) {
-// Create the View's context menu
- this.contextMenu = new Roo.menu.Menu({
- id: this.id + "-contextmenu"
- });
- this.el.on("contextmenu", this.showContextMenu, this);
- }
- return this.contextMenu;
- },
-
- disableContextMenu: function() {
- if (this.contextMenu) {
- this.el.un("contextmenu", this.showContextMenu, this);
- }
- },
-
- showContextMenu: function(e, item) {
- item = this.findItemFromChild(e.getTarget());
- if (item) {
- e.stopEvent();
- this.select(this.getNode(item), this.multiSelect && e.ctrlKey, true);
- this.contextMenu.showAt(e.getXY());
- }
- },
-
-/**
- * Remove {@link Roo.data.Record}s at the specified indices.
- * @param {Array/Number} selectedIndices The index (or Array of indices) of Records to remove.
- */
- remove: function(selectedIndices) {
- selectedIndices = [].concat(selectedIndices);
- for (var i = 0; i < selectedIndices.length; i++) {
- var rec = this.store.getAt(selectedIndices[i]);
- this.store.remove(rec);
- }
- },
-
-/**
- * Double click fires the event, but also, if this is draggable, and there is only one other
- * related DropZone, it transfers the selected node.
- */
- onDblClick : function(e){
- var item = this.findItemFromChild(e.getTarget());
- if(item){
- if (this.fireEvent("dblclick", this, this.indexOf(item), item, e) === false) {
- return false;
- }
- if (this.dragGroup) {
- var targets = Roo.dd.DragDropMgr.getRelated(this.dragZone, true);
- while (targets.indexOf(this.dropZone) > -1) {
- targets.remove(this.dropZone);
- }
- if (targets.length == 1) {
- this.dragZone.cachedTarget = null;
- var el = Roo.get(targets[0].getEl());
- var box = el.getBox(true);
- targets[0].onNodeDrop(el.dom, {
- target: el.dom,
- xy: [box.x, box.y + box.height - 1]
- }, null, this.getDragData(e));
- }
- }
- }
- },
-
- handleSelection: function(e) {
- this.dragZone.cachedTarget = null;
- var item = this.findItemFromChild(e.getTarget());
- if (!item) {
- this.clearSelections(true);
- return;
- }
- if (item && (this.multiSelect || this.singleSelect)){
- if(this.multiSelect && e.shiftKey && (!e.ctrlKey) && this.lastSelection){
- this.select(this.getNodes(this.indexOf(this.lastSelection), item.nodeIndex), false);
- }else if (this.isSelected(this.getNode(item)) && e.ctrlKey){
- this.unselect(item);
- } else {
- this.select(item, this.multiSelect && e.ctrlKey);
- this.lastSelection = item;
- }
- }
- },
-
- onItemClick : function(item, index, e){
- if(this.fireEvent("beforeclick", this, index, item, e) === false){
- return false;
- }
- return true;
- },
-
- unselect : function(nodeInfo, suppressEvent){
- var node = this.getNode(nodeInfo);
- if(node && this.isSelected(node)){
- if(this.fireEvent("beforeselect", this, node, this.selections) !== false){
- Roo.fly(node).removeClass(this.selectedClass);
- this.selections.remove(node);
- if(!suppressEvent){
- this.fireEvent("selectionchange", this, this.selections);
- }
- }
- }
- }
-});