this.sortInfo = meta.sortInfo || this.sortInfo;
this.modified = [];
this.fireEvent('metachange', this, this.reader.meta);
+ },
+
+ moveIndex : function(data, type)
+ {
+ var index = this.indexOf(data);
+
+ var newIndex = index + type;
+
+ this.remove(data);
+
+ this.insert(newIndex, data);
+
}
});/*
* Based on:
* Refreshes the view. - called by datachanged on the store. - do not call directly.
*/
refresh : function(){
+ Roo.log('refresh');
var t = this.tpl;
// if we are using something like 'domtemplate', then
this.nodes = el.dom.childNodes;
this.updateIndexes(0);
},
+
/**
* Function to override to reformat the data that is sent to
},
onUpdate : function(ds, record){
+ Roo.log('on update');
this.clearSelections();
var index = this.store.indexOf(record);
var n = this.nodes[index];
// --------- FIXME
onAdd : function(ds, records, index)
{
+ Roo.log(['on Add', ds, records, index] );
this.clearSelections();
if(this.nodes.length == 0){
this.refresh();
},
onRemove : function(ds, record, index){
+ Roo.log('onRemove');
this.clearSelections();
var el = this.dataName ?
this.el.child('.roo-tpl-' + this.dataName) :
this.el;
+
el.dom.removeChild(this.nodes[index]);
this.updateIndexes(index);
},
* onbeforeLoad - masks the loading area.
*
*/
- onBeforeLoad : function()
+ onBeforeLoad : function(store,opts)
{
- this.el.update("");
+ Roo.log('onBeforeLoad');
+ if (!opts.add) {
+ this.el.update("");
+ }
this.el.mask(this.mask ? this.mask : "Loading" );
},
onLoad : function ()
tag: "a", cls: "x-menu-focus", href: "#", onclick: "return false;", tabIndex:"-1"
});
var ul = el.createChild({tag: "ul", cls: "x-menu-list"});
- ul.on("click", this.onClick, this);
+ ul.on(Roo.isTouch ? 'touchstart' : 'click' , this.onClick, this);
+
ul.on("mouseover", this.onMouseOver, this);
ul.on("mouseout", this.onMouseOut, this);
this.items.each(function(item){
// private
onClick : function(e){
- var t;
- if(t = this.findTargetItem(e)){
- t.onClick(e);
- this.fireEvent("click", this, t, e);
+ Roo.log("menu.onClick");
+ var t = this.findTargetItem(e);
+ if(!t){
+ return;
+ }
+ Roo.log(e);
+ if (Roo.isTouch && e.type == 'touchstart' && t.menu && !t.disabled) {
+ if(t == this.activeItem && t.shouldDeactivate(e)){
+ this.activeItem.deactivate();
+ delete this.activeItem;
+ return;
+ }
+ if(t.canActivate){
+ this.setActiveItem(t, true);
+ }
+ return;
+
+
}
+
+ t.onClick(e);
+ this.fireEvent("click", this, t, e);
},
// private
Roo.form.ComboBoxArray = function(config)
{
+ this.addEvents({
+ /**
+ * @event remove
+ * Fires when remove the value from the list
+ * @param {Roo.form.ComboBox} combo This combo box
+ */
+ 'remove' : true
+
+
+ });
Roo.form.ComboBoxArray.superclass.constructor.call(this, config);
remove : function()
{
-
+ Roo.log(this);
this.cb.items.remove(this);
this.el.child('img').un('click', this.remove, this);
this.el.remove();
this.cb.updateHiddenEl();
+
+ Roo.log('remove?????');
+ this.fireEvent('remove', this);
}
});/*
* Based on:
});//<script type="text/javascript">
/*
- * Ext JS Library 1.1.1
+ * Based Ext JS Library 1.1.1
* Copyright(c) 2006-2007, Ext JS, LLC.
- * licensing@extjs.com
- *
- * http://www.extjs.com/license
+ * LGPL
+ *
*/
- /*
- *
- * Known bugs:
- * Default CSS appears to render it as fixed text by default (should really be Sans-Serif)
- * - IE ? - no idea how much works there.
- *
- *
- *
- */
-
-
/**
- * @class Ext.form.HtmlEditor
- * @extends Ext.form.Field
- * Provides a lightweight HTML Editor component.
+ * @class Roo.HtmlEditorCore
+ * @extends Roo.Component
+ * Provides a the editing component for the HTML editors in Roo. (bootstrap and Roo.form)
*
- * This has been tested on Fireforx / Chrome.. IE may not be so great..
- *
- * <br><br><b>Note: The focus/blur and validation marking functionality inherited from Ext.form.Field is NOT
- * supported by this editor.</b><br/><br/>
- * An Editor is a sensitive component that can't be used in all spots standard fields can be used. Putting an Editor within
* any element that has display set to 'none' can cause problems in Safari and Firefox.<br/><br/>
*/
-Roo.form.HtmlEditor = Roo.extend(Roo.form.Field, {
- /**
- * @cfg {Array} toolbars Array of toolbars. - defaults to just the Standard one
- */
- toolbars : false,
- /**
- * @cfg {String} createLinkText The default text for the create link prompt
- */
- createLinkText : 'Please enter the URL for the link:',
- /**
- * @cfg {String} defaultLinkValue The default value for the create link prompt (defaults to http:/ /)
+
+Roo.HtmlEditorCore = function(config){
+
+
+ Roo.HtmlEditorCore.superclass.constructor.call(this, config);
+ this.addEvents({
+ /**
+ * @event initialize
+ * Fires when the editor is fully initialized (including the iframe)
+ * @param {Roo.HtmlEditorCore} this
+ */
+ initialize: true,
+ /**
+ * @event activate
+ * Fires when the editor is first receives the focus. Any insertion must wait
+ * until after this event.
+ * @param {Roo.HtmlEditorCore} this
+ */
+ activate: true,
+ /**
+ * @event beforesync
+ * Fires before the textarea is updated with content from the editor iframe. Return false
+ * to cancel the sync.
+ * @param {Roo.HtmlEditorCore} this
+ * @param {String} html
+ */
+ beforesync: true,
+ /**
+ * @event beforepush
+ * Fires before the iframe editor is updated with content from the textarea. Return false
+ * to cancel the push.
+ * @param {Roo.HtmlEditorCore} this
+ * @param {String} html
+ */
+ beforepush: true,
+ /**
+ * @event sync
+ * Fires when the textarea is updated with content from the editor iframe.
+ * @param {Roo.HtmlEditorCore} this
+ * @param {String} html
+ */
+ sync: true,
+ /**
+ * @event push
+ * Fires when the iframe editor is updated with content from the textarea.
+ * @param {Roo.HtmlEditorCore} this
+ * @param {String} html
+ */
+ push: true,
+
+ /**
+ * @event editorevent
+ * Fires when on any editor (mouse up/down cursor movement etc.) - used for toolbar hooks.
+ * @param {Roo.HtmlEditorCore} this
+ */
+ editorevent: true
+ });
+
+};
+
+
+Roo.extend(Roo.HtmlEditorCore, Roo.Component, {
+
+
+ /**
+ * @cfg {Roo.form.HtmlEditor|Roo.bootstrap.HtmlEditor} the owner field
*/
- defaultLinkValue : 'http:/'+'/',
-
+
+ owner : false,
+
/**
* @cfg {String} resizable 's' or 'se' or 'e' - wrapps the element in a
* Roo.resizable.
iframePad:3,
hideMode:'offsets',
- defaultAutoCreate : { // modified by initCompnoent..
- tag: "textarea",
- style:"width:500px;height:300px;",
- autocomplete: "off"
- },
-
- // private
- initComponent : function(){
- this.addEvents({
- /**
- * @event initialize
- * Fires when the editor is fully initialized (including the iframe)
- * @param {HtmlEditor} this
- */
- initialize: true,
- /**
- * @event activate
- * Fires when the editor is first receives the focus. Any insertion must wait
- * until after this event.
- * @param {HtmlEditor} this
- */
- activate: true,
- /**
- * @event beforesync
- * Fires before the textarea is updated with content from the editor iframe. Return false
- * to cancel the sync.
- * @param {HtmlEditor} this
- * @param {String} html
- */
- beforesync: true,
- /**
- * @event beforepush
- * Fires before the iframe editor is updated with content from the textarea. Return false
- * to cancel the push.
- * @param {HtmlEditor} this
- * @param {String} html
- */
- beforepush: true,
- /**
- * @event sync
- * Fires when the textarea is updated with content from the editor iframe.
- * @param {HtmlEditor} this
- * @param {String} html
- */
- sync: true,
- /**
- * @event push
- * Fires when the iframe editor is updated with content from the textarea.
- * @param {HtmlEditor} this
- * @param {String} html
- */
- push: true,
- /**
- * @event editmodechange
- * Fires when the editor switches edit modes
- * @param {HtmlEditor} this
- * @param {Boolean} sourceEdit True if source edit, false if standard editing.
- */
- editmodechange: true,
- /**
- * @event editorevent
- * Fires when on any editor (mouse up/down cursor movement etc.) - used for toolbar hooks.
- * @param {HtmlEditor} this
- */
- editorevent: true
- });
- this.defaultAutoCreate = {
- tag: "textarea",
- style:'width: ' + this.width + 'px;height: ' + this.height + 'px;',
- autocomplete: "off"
- };
- },
-
- /**
- * Protected method that will not generally be called directly. It
- * is called when the editor creates its toolbar. Override this method if you need to
- * add custom toolbar buttons.
- * @param {HtmlEditor} editor
- */
- createToolbar : function(editor){
- if (!editor.toolbars || !editor.toolbars.length) {
- editor.toolbars = [ new Roo.form.HtmlEditor.ToolbarStandard() ]; // can be empty?
- }
-
- for (var i =0 ; i < editor.toolbars.length;i++) {
- editor.toolbars[i] = Roo.factory(
- typeof(editor.toolbars[i]) == 'string' ?
- { xtype: editor.toolbars[i]} : editor.toolbars[i],
- Roo.form.HtmlEditor);
- editor.toolbars[i].init(editor);
- }
-
-
- },
+ clearUp: true,
+
+
+
/**
* Protected method that will not generally be called directly. It
getDocMarkup : function(){
// body styles..
var st = '';
+ Roo.log(this.stylesheets);
+
+ // inherit styels from page...??
if (this.stylesheets === false) {
Roo.get(document.head).select('style').each(function(node) {
onRender : function(ct, position)
{
var _t = this;
- Roo.form.HtmlEditor.superclass.onRender.call(this, ct, position);
+ //Roo.HtmlEditorCore.superclass.onRender.call(this, ct, position);
+ this.el = this.owner.inputEl ? this.owner.inputEl() : this.owner.el;
+
+
this.el.dom.style.border = '0 none';
this.el.dom.setAttribute('tabIndex', -1);
- this.el.addClass('x-hidden');
+ this.el.addClass('x-hidden hide');
+
+
+
if(Roo.isIE){ // fix IE 1px bogus margin
this.el.applyStyles('margin-top:-1px;margin-bottom:-1px;')
}
- this.wrap = this.el.wrap({
- cls:'x-html-editor-wrap', cn:{cls:'x-html-editor-tb'}
- });
+
- if (this.resizable) {
- this.resizeEl = new Roo.Resizable(this.wrap, {
- pinned : true,
- wrap: true,
- dynamic : true,
- minHeight : this.height,
- height: this.height,
- handles : this.resizable,
- width: this.width,
- listeners : {
- resize : function(r, w, h) {
- _t.onResize(w,h); // -something
- }
- }
- });
-
- }
-
this.frameId = Roo.id();
- this.createToolbar(this);
-
-
+
- var iframe = this.wrap.createChild({
+ var iframe = this.owner.wrap.createChild({
tag: 'iframe',
+ cls: 'form-control', // bootstrap..
id: this.frameId,
name: this.frameId,
frameBorder : 'no',
}, this.el
);
- // console.log(iframe);
- //this.wrap.dom.appendChild(iframe);
-
+
this.iframe = iframe.dom;
this.assignDocWin();
}
},
interval : 10,
- duration:10000,
+ duration: 10000,
scope: this
};
Roo.TaskMgr.start(task);
- if(!this.width){
- this.setSize(this.wrap.getSize());
- }
- if (this.resizeEl) {
- this.resizeEl.resizeTo.defer(100, this.resizeEl,[ this.width,this.height ] );
- // should trigger onReize..
- }
+
+
},
// private
onResize : function(w, h)
{
- //Roo.log('resize: ' +w + ',' + h );
- Roo.form.HtmlEditor.superclass.onResize.apply(this, arguments);
- if(this.el && this.iframe){
- if(typeof w == 'number'){
- var aw = w - this.wrap.getFrameWidth('lr');
- this.el.setWidth(this.adjustWidth('textarea', aw));
- this.iframe.style.width = aw + 'px';
- }
- if(typeof h == 'number'){
- var tbh = 0;
- for (var i =0; i < this.toolbars.length;i++) {
- // fixme - ask toolbars for heights?
- tbh += this.toolbars[i].tb.el.getHeight();
- if (this.toolbars[i].footer) {
- tbh += this.toolbars[i].footer.el.getHeight();
- }
- }
-
-
-
-
- var ah = h - this.wrap.getFrameWidth('tb') - tbh;// this.tb.el.getHeight();
- ah -= 5; // knock a few pixes off for look..
- this.el.setHeight(this.adjustWidth('textarea', ah));
- this.iframe.style.height = ah + 'px';
- if(this.doc){
- (this.doc.body || this.doc.documentElement).style.height = (ah - (this.iframePad*2)) + 'px';
- }
+ Roo.log('resize: ' +w + ',' + h );
+ //Roo.HtmlEditorCore.superclass.onResize.apply(this, arguments);
+ if(!this.iframe){
+ return;
+ }
+ if(typeof w == 'number'){
+
+ this.iframe.style.width = w + 'px';
+ }
+ if(typeof h == 'number'){
+
+ this.iframe.style.height = h + 'px';
+ if(this.doc){
+ (this.doc.body || this.doc.documentElement).style.height = (h - (this.iframePad*2)) + 'px';
}
}
+
},
/**
this.sourceEditMode = sourceEditMode === true;
if(this.sourceEditMode){
-// Roo.log('in');
-// Roo.log(this.syncValue());
- this.syncValue();
- this.iframe.className = 'x-hidden';
- this.el.removeClass('x-hidden');
- this.el.dom.removeAttribute('tabIndex');
- this.el.focus();
+
+ Roo.get(this.iframe).addClass(['x-hidden','hide']); //FIXME - what's the BS styles for these
+
}else{
-// Roo.log('out')
-// Roo.log(this.pushValue());
- this.pushValue();
- this.iframe.className = '';
- this.el.addClass('x-hidden');
- this.el.dom.setAttribute('tabIndex', -1);
+ Roo.get(this.iframe).removeClass(['x-hidden','hide']);
+ //this.iframe.className = '';
this.deferFocus();
}
- this.setSize(this.wrap.getSize());
- this.fireEvent('editmodechange', this, this.sourceEditMode);
+ //this.setSize(this.owner.wrap.getSize());
+ //this.fireEvent('editmodechange', this, this.sourceEditMode);
},
- // private used internally
- createLink : function(){
- var url = prompt(this.createLinkText, this.defaultLinkValue);
- if(url && url != 'http:/'+'/'){
- this.relayCmd('createlink', url);
- }
- },
-
- // private (for BoxComponent)
- adjustSize : Roo.BoxComponent.prototype.adjustSize,
-
- // private (for BoxComponent)
- getResizeEl : function(){
- return this.wrap;
- },
-
- // private (for BoxComponent)
- getPositionEl : function(){
- return this.wrap;
- },
-
- // private
- initEvents : function(){
- this.originalValue = this.getValue();
- },
-
- /**
- * Overridden and disabled. The editor element does not support standard valid/invalid marking. @hide
- * @method
- */
- markInvalid : Roo.emptyFn,
- /**
- * Overridden and disabled. The editor element does not support standard valid/invalid marking. @hide
- * @method
- */
- clearInvalid : Roo.emptyFn,
-
- setValue : function(v){
- Roo.form.HtmlEditor.superclass.setValue.call(this, v);
- this.pushValue();
- },
+
+
/**
* Protected method that will not generally be called directly. If you need/want
},
/**
+ * HTML Editor -> Textarea
* Protected method that will not generally be called directly. Syncs the contents
* of the editor iframe with the textarea.
*/
var html = bd.innerHTML;
if(Roo.isSafari){
var bs = bd.getAttribute('style'); // Safari puts text-align styles on the body element!
- var m = bs.match(/text-align:(.*?);/i);
+ var m = bs ? bs.match(/text-align:(.*?);/i) : false;
if(m && m[1]){
html = '<div style="'+m[0]+'">' + html + '</div>';
}
}
return "&#"+cc+";"
});
- if(this.fireEvent('beforesync', this, html) !== false){
+ if(this.owner.fireEvent('beforesync', this, html) !== false){
this.el.dom.value = html;
- this.fireEvent('sync', this, html);
+ this.owner.fireEvent('sync', this, html);
}
}
},
*/
pushValue : function(){
if(this.initialized){
- var v = this.el.dom.value;
+ var v = this.el.dom.value.trim();
- if(v.length < 1){
- v = ' ';
- }
+// if(v.length < 1){
+// v = ' ';
+// }
- if(this.fireEvent('beforepush', this, v) !== false){
+ if(this.owner.fireEvent('beforepush', this, v) !== false){
var d = (this.doc.body || this.doc.documentElement);
d.innerHTML = v;
this.cleanUpPaste();
this.el.dom.value = d.innerHTML;
- this.fireEvent('push', this, v);
+ this.owner.fireEvent('push', this, v);
}
}
},
}
this.initialized = true;
- this.fireEvent('initialize', this);
+ this.owner.fireEvent('initialize', this);
this.pushValue();
},
if(this.rendered){
- for (var i =0; i < this.toolbars.length;i++) {
- // fixme - ask toolbars for heights?
- this.toolbars[i].onDestroy();
- }
+ //for (var i =0; i < this.toolbars.length;i++) {
+ // // fixme - ask toolbars for heights?
+ // this.toolbars[i].onDestroy();
+ // }
- this.wrap.dom.innerHTML = '';
- this.wrap.remove();
+ //this.wrap.dom.innerHTML = '';
+ //this.wrap.remove();
}
},
this.activated = true;
- for (var i =0; i < this.toolbars.length;i++) {
- this.toolbars[i].onFirstFocus();
- }
-
+
+
if(Roo.isGecko){ // prevent silly gecko errors
this.win.focus();
var s = this.win.getSelection();
this.execCmd('styleWithCSS', false);
}catch(e){}
}
- this.fireEvent('activate', this);
+ this.owner.fireEvent('activate', this);
},
// private
},
onEditorEvent : function(e){
- this.fireEvent('editorevent', this, e);
+ this.owner.fireEvent('editorevent', this, e);
// this.updateToolbar();
this.syncValue(); //we can not sync so often.. sync cleans, so this breaks stuff
},
range.insertNode(this.doc.createTextNode(txt));
} ,
- // private
- relayBtnCmd : function(btn){
- this.relayCmd(btn.cmd);
- },
+
/**
* Executes a Midas editor command on the editor document and performs necessary focus and
relayCmd : function(cmd, value){
this.win.focus();
this.execCmd(cmd, value);
- this.fireEvent('editorevent', this);
+ this.owner.fireEvent('editorevent', this);
//this.updateToolbar();
- this.deferFocus();
+ this.owner.deferFocus();
},
/**
cleanUpPaste : function()
{
// cleans up the whole document..
- Roo.log('cleanuppaste');
+ Roo.log('cleanuppaste');
+
this.cleanUpChildren(this.doc.body);
var clean = this.cleanWordChars(this.doc.body.innerHTML);
if (clean != this.doc.body.innerHTML) {
},
cleanWordChars : function(input) {// change the chars to hex code
- var he = Roo.form.HtmlEditor;
+ var he = Roo.HtmlEditorCore;
var output = input;
Roo.each(he.swapCodes, function(sw) {
return;
}
- if (Roo.form.HtmlEditor.black.indexOf(node.tagName.toLowerCase()) > -1) {
+ if (Roo.HtmlEditorCore.black.indexOf(node.tagName.toLowerCase()) > -1 && this.clearUp) {
// remove node.
node.parentNode.removeChild(node);
return;
}
- var remove_keep_children= Roo.form.HtmlEditor.remove.indexOf(node.tagName.toLowerCase()) > -1;
+ var remove_keep_children= Roo.HtmlEditorCore.remove.indexOf(node.tagName.toLowerCase()) > -1;
// remove <a name=....> as rendering on yahoo mailer is borked with this.
// this will have to be flaged elsewhere - perhaps ablack=name... on the mailer..
node.removeAttribute(n);
return;
}
- var cwhite = typeof(ed.cwhite) == 'undefined' ? Roo.form.HtmlEditor.cwhite : ed.cwhite;
- var cblack = typeof(ed.cblack) == 'undefined' ? Roo.form.HtmlEditor.cblack : ed.cblack;
+ var cwhite = typeof(ed.cwhite) == 'undefined' ? Roo.HtmlEditorCore.cwhite : ed.cwhite;
+ var cblack = typeof(ed.cblack) == 'undefined' ? Roo.HtmlEditorCore.cblack : ed.cblack;
var parts = v.split(/;/);
var l = p.split(':').shift().replace(/\s+/g,'');
l = l.replace(/^\s+/g,'').replace(/\s+$/g,'');
-
if ( cblack.indexOf(l) > -1) {
// Roo.log('(REMOVE CSS)' + node.tagName +'.' + n + ':'+l + '=' + v);
//node.removeAttribute(n);
node.removeAttribute(a.name);
continue;
}
- if (Roo.form.HtmlEditor.ablack.indexOf(a.name.toLowerCase()) > -1) {
+ if (Roo.HtmlEditorCore.ablack.indexOf(a.name.toLowerCase()) > -1) {
node.removeAttribute(a.name);
continue;
}
- if (Roo.form.HtmlEditor.aclean.indexOf(a.name.toLowerCase()) > -1) {
+ if (Roo.HtmlEditorCore.aclean.indexOf(a.name.toLowerCase()) > -1) {
cleanAttr(a.name,a.value); // fixme..
continue;
}
*/
});
-Roo.form.HtmlEditor.white = [
+Roo.HtmlEditorCore.white = [
'area', 'br', 'img', 'input', 'hr', 'wbr',
'address', 'blockquote', 'center', 'dd', 'dir', 'div',
];
-Roo.form.HtmlEditor.black = [
+Roo.HtmlEditorCore.black = [
// 'embed', 'object', // enable - backend responsiblity to clean thiese
'applet', //
'base', 'basefont', 'bgsound', 'blink', 'body',
'iframe', 'layer', 'link', 'meta', 'object',
'script', 'style' ,'title', 'xml' // clean later..
];
-Roo.form.HtmlEditor.clean = [
+Roo.HtmlEditorCore.clean = [
'script', 'style', 'title', 'xml'
];
-Roo.form.HtmlEditor.remove = [
+Roo.HtmlEditorCore.remove = [
'font'
];
// attributes..
-Roo.form.HtmlEditor.ablack = [
+Roo.HtmlEditorCore.ablack = [
'on'
];
-Roo.form.HtmlEditor.aclean = [
+Roo.HtmlEditorCore.aclean = [
'action', 'background', 'codebase', 'dynsrc', 'href', 'lowsrc'
];
// protocols..
-Roo.form.HtmlEditor.pwhite= [
+Roo.HtmlEditorCore.pwhite= [
'http', 'https', 'mailto'
];
// white listed style attributes.
-Roo.form.HtmlEditor.cwhite= [
+Roo.HtmlEditorCore.cwhite= [
// 'text-align', /// default is to allow most things..
];
// black listed style attributes.
-Roo.form.HtmlEditor.cblack= [
+Roo.HtmlEditorCore.cblack= [
// 'font-size' -- this can be set by the project
];
-Roo.form.HtmlEditor.swapCodes =[
+Roo.HtmlEditorCore.swapCodes =[
[ 8211, "--" ],
[ 8212, "--" ],
[ 8216, "'" ],
[ 8230, "..." ]
];
+ //<script type="text/javascript">
+
+/*
+ * Ext JS Library 1.1.1
+ * Copyright(c) 2006-2007, Ext JS, LLC.
+ * Licence LGPL
+ *
+ */
+
+
+Roo.form.HtmlEditor = function(config){
+
+
+
+ Roo.form.HtmlEditor.superclass.constructor.call(this, config);
+
+ if (!this.toolbars) {
+ this.toolbars = [];
+ }
+ this.editorcore = new Roo.HtmlEditorCore(Roo.apply({ owner : this} , config));
+
+
+};
+
+/**
+ * @class Roo.form.HtmlEditor
+ * @extends Roo.form.Field
+ * Provides a lightweight HTML Editor component.
+ *
+ * This has been tested on Fireforx / Chrome.. IE may not be so great..
+ *
+ * <br><br><b>Note: The focus/blur and validation marking functionality inherited from Ext.form.Field is NOT
+ * supported by this editor.</b><br/><br/>
+ * An Editor is a sensitive component that can't be used in all spots standard fields can be used. Putting an Editor within
+ * any element that has display set to 'none' can cause problems in Safari and Firefox.<br/><br/>
+ */
+Roo.extend(Roo.form.HtmlEditor, Roo.form.Field, {
+ /**
+ * @cfg {Boolean} clearUp
+ */
+ clearUp : true,
+ /**
+ * @cfg {Array} toolbars Array of toolbars. - defaults to just the Standard one
+ */
+ toolbars : false,
+
+ /**
+ * @cfg {String} resizable 's' or 'se' or 'e' - wrapps the element in a
+ * Roo.resizable.
+ */
+ resizable : false,
+ /**
+ * @cfg {Number} height (in pixels)
+ */
+ height: 300,
+ /**
+ * @cfg {Number} width (in pixels)
+ */
+ width: 500,
+
+ /**
+ * @cfg {Array} stylesheets url of stylesheets. set to [] to disable stylesheets.
+ *
+ */
+ stylesheets: false,
+
+ // id of frame..
+ frameId: false,
+
+ // private properties
+ validationEvent : false,
+ deferHeight: true,
+ initialized : false,
+ activated : false,
+
+ onFocus : Roo.emptyFn,
+ iframePad:3,
+ hideMode:'offsets',
+
+ defaultAutoCreate : { // modified by initCompnoent..
+ tag: "textarea",
+ style:"width:500px;height:300px;",
+ autocomplete: "off"
+ },
+
+ // private
+ initComponent : function(){
+ this.addEvents({
+ /**
+ * @event initialize
+ * Fires when the editor is fully initialized (including the iframe)
+ * @param {HtmlEditor} this
+ */
+ initialize: true,
+ /**
+ * @event activate
+ * Fires when the editor is first receives the focus. Any insertion must wait
+ * until after this event.
+ * @param {HtmlEditor} this
+ */
+ activate: true,
+ /**
+ * @event beforesync
+ * Fires before the textarea is updated with content from the editor iframe. Return false
+ * to cancel the sync.
+ * @param {HtmlEditor} this
+ * @param {String} html
+ */
+ beforesync: true,
+ /**
+ * @event beforepush
+ * Fires before the iframe editor is updated with content from the textarea. Return false
+ * to cancel the push.
+ * @param {HtmlEditor} this
+ * @param {String} html
+ */
+ beforepush: true,
+ /**
+ * @event sync
+ * Fires when the textarea is updated with content from the editor iframe.
+ * @param {HtmlEditor} this
+ * @param {String} html
+ */
+ sync: true,
+ /**
+ * @event push
+ * Fires when the iframe editor is updated with content from the textarea.
+ * @param {HtmlEditor} this
+ * @param {String} html
+ */
+ push: true,
+ /**
+ * @event editmodechange
+ * Fires when the editor switches edit modes
+ * @param {HtmlEditor} this
+ * @param {Boolean} sourceEdit True if source edit, false if standard editing.
+ */
+ editmodechange: true,
+ /**
+ * @event editorevent
+ * Fires when on any editor (mouse up/down cursor movement etc.) - used for toolbar hooks.
+ * @param {HtmlEditor} this
+ */
+ editorevent: true,
+ /**
+ * @event firstfocus
+ * Fires when on first focus - needed by toolbars..
+ * @param {HtmlEditor} this
+ */
+ firstfocus: true,
+ /**
+ * @event autosave
+ * Auto save the htmlEditor value as a file into Events
+ * @param {HtmlEditor} this
+ */
+ autosave: true,
+ /**
+ * @event savedpreview
+ * preview the saved version of htmlEditor
+ * @param {HtmlEditor} this
+ */
+ savedpreview: true
+ });
+ this.defaultAutoCreate = {
+ tag: "textarea",
+ style:'width: ' + this.width + 'px;height: ' + this.height + 'px;',
+ autocomplete: "off"
+ };
+ },
+
+ /**
+ * Protected method that will not generally be called directly. It
+ * is called when the editor creates its toolbar. Override this method if you need to
+ * add custom toolbar buttons.
+ * @param {HtmlEditor} editor
+ */
+ createToolbar : function(editor){
+ Roo.log("create toolbars");
+ if (!editor.toolbars || !editor.toolbars.length) {
+ editor.toolbars = [ new Roo.form.HtmlEditor.ToolbarStandard() ]; // can be empty?
+ }
+
+ for (var i =0 ; i < editor.toolbars.length;i++) {
+ editor.toolbars[i] = Roo.factory(
+ typeof(editor.toolbars[i]) == 'string' ?
+ { xtype: editor.toolbars[i]} : editor.toolbars[i],
+ Roo.form.HtmlEditor);
+ editor.toolbars[i].init(editor);
+ }
+
+
+ },
+
+
+ // private
+ onRender : function(ct, position)
+ {
+ var _t = this;
+ Roo.form.HtmlEditor.superclass.onRender.call(this, ct, position);
+
+ this.wrap = this.el.wrap({
+ cls:'x-html-editor-wrap', cn:{cls:'x-html-editor-tb'}
+ });
+
+ this.editorcore.onRender(ct, position);
+
+ if (this.resizable) {
+ this.resizeEl = new Roo.Resizable(this.wrap, {
+ pinned : true,
+ wrap: true,
+ dynamic : true,
+ minHeight : this.height,
+ height: this.height,
+ handles : this.resizable,
+ width: this.width,
+ listeners : {
+ resize : function(r, w, h) {
+ _t.onResize(w,h); // -something
+ }
+ }
+ });
+
+ }
+ this.createToolbar(this);
+
+
+ if(!this.width){
+ this.setSize(this.wrap.getSize());
+ }
+ if (this.resizeEl) {
+ this.resizeEl.resizeTo.defer(100, this.resizeEl,[ this.width,this.height ] );
+ // should trigger onReize..
+ }
+
+// if(this.autosave && this.w){
+// this.autoSaveFn = setInterval(this.autosave, 1000);
+// }
+ },
+
+ // private
+ onResize : function(w, h)
+ {
+ //Roo.log('resize: ' +w + ',' + h );
+ Roo.form.HtmlEditor.superclass.onResize.apply(this, arguments);
+ var ew = false;
+ var eh = false;
+
+ if(this.el ){
+ if(typeof w == 'number'){
+ var aw = w - this.wrap.getFrameWidth('lr');
+ this.el.setWidth(this.adjustWidth('textarea', aw));
+ ew = aw;
+ }
+ if(typeof h == 'number'){
+ var tbh = 0;
+ for (var i =0; i < this.toolbars.length;i++) {
+ // fixme - ask toolbars for heights?
+ tbh += this.toolbars[i].tb.el.getHeight();
+ if (this.toolbars[i].footer) {
+ tbh += this.toolbars[i].footer.el.getHeight();
+ }
+ }
+
+
+
+
+ var ah = h - this.wrap.getFrameWidth('tb') - tbh;// this.tb.el.getHeight();
+ ah -= 5; // knock a few pixes off for look..
+ this.el.setHeight(this.adjustWidth('textarea', ah));
+ var eh = ah;
+ }
+ }
+ Roo.log('onResize:' + [w,h,ew,eh].join(',') );
+ this.editorcore.onResize(ew,eh);
+
+ },
+
+ /**
+ * Toggles the editor between standard and source edit mode.
+ * @param {Boolean} sourceEdit (optional) True for source edit, false for standard
+ */
+ toggleSourceEdit : function(sourceEditMode)
+ {
+ this.editorcore.toggleSourceEdit(sourceEditMode);
+
+ if(this.editorcore.sourceEditMode){
+ Roo.log('editor - showing textarea');
+
+// Roo.log('in');
+// Roo.log(this.syncValue());
+ this.editorcore.syncValue();
+ this.el.removeClass('x-hidden');
+ this.el.dom.removeAttribute('tabIndex');
+ this.el.focus();
+ }else{
+ Roo.log('editor - hiding textarea');
+// Roo.log('out')
+// Roo.log(this.pushValue());
+ this.editorcore.pushValue();
+
+ this.el.addClass('x-hidden');
+ this.el.dom.setAttribute('tabIndex', -1);
+ //this.deferFocus();
+ }
+
+ this.setSize(this.wrap.getSize());
+ this.fireEvent('editmodechange', this, this.editorcore.sourceEditMode);
+ },
+
+ // private (for BoxComponent)
+ adjustSize : Roo.BoxComponent.prototype.adjustSize,
+
+ // private (for BoxComponent)
+ getResizeEl : function(){
+ return this.wrap;
+ },
+
+ // private (for BoxComponent)
+ getPositionEl : function(){
+ return this.wrap;
+ },
+
+ // private
+ initEvents : function(){
+ this.originalValue = this.getValue();
+ },
+
+ /**
+ * Overridden and disabled. The editor element does not support standard valid/invalid marking. @hide
+ * @method
+ */
+ markInvalid : Roo.emptyFn,
+ /**
+ * Overridden and disabled. The editor element does not support standard valid/invalid marking. @hide
+ * @method
+ */
+ clearInvalid : Roo.emptyFn,
+
+ setValue : function(v){
+ Roo.form.HtmlEditor.superclass.setValue.call(this, v);
+ this.editorcore.pushValue();
+ },
+
+
+ // private
+ deferFocus : function(){
+ this.focus.defer(10, this);
+ },
+
+ // doc'ed in Field
+ focus : function(){
+ this.editorcore.focus();
+
+ },
+
+
+ // private
+ onDestroy : function(){
+
+
+
+ if(this.rendered){
+
+ for (var i =0; i < this.toolbars.length;i++) {
+ // fixme - ask toolbars for heights?
+ this.toolbars[i].onDestroy();
+ }
+
+ this.wrap.dom.innerHTML = '';
+ this.wrap.remove();
+ }
+ },
+
+ // private
+ onFirstFocus : function(){
+ //Roo.log("onFirstFocus");
+ this.editorcore.onFirstFocus();
+ for (var i =0; i < this.toolbars.length;i++) {
+ this.toolbars[i].onFirstFocus();
+ }
+
+ },
+
+ // private
+ syncValue : function()
+ {
+ this.editorcore.syncValue();
+ },
+
+ pushValue : function()
+ {
+ this.editorcore.pushValue();
+ }
+
+
+ // hide stuff that is not compatible
+ /**
+ * @event blur
+ * @hide
+ */
+ /**
+ * @event change
+ * @hide
+ */
+ /**
+ * @event focus
+ * @hide
+ */
+ /**
+ * @event specialkey
+ * @hide
+ */
+ /**
+ * @cfg {String} fieldClass @hide
+ */
+ /**
+ * @cfg {String} focusClass @hide
+ */
+ /**
+ * @cfg {String} autoCreate @hide
+ */
+ /**
+ * @cfg {String} inputType @hide
+ */
+ /**
+ * @cfg {String} invalidClass @hide
+ */
+ /**
+ * @cfg {String} invalidText @hide
+ */
+ /**
+ * @cfg {String} msgFx @hide
+ */
+ /**
+ * @cfg {String} validateOnBlur @hide
+ */
+});
+
// <script type="text/javascript">
/*
* Based on
rendered: false,
editor : false,
+ editorcore : false,
/**
* @cfg {Object} disable List of toolbar elements to disable
*/
disable : false,
+
+
+ /**
+ * @cfg {String} createLinkText The default text for the create link prompt
+ */
+ createLinkText : 'Please enter the URL for the link:',
+ /**
+ * @cfg {String} defaultLinkValue The default value for the create link prompt (defaults to http:/ /)
+ */
+ defaultLinkValue : 'http:/'+'/',
+
+
/**
* @cfg {Array} fontFamilies An array of available font families
*/
init : function(editor)
{
this.editor = editor;
+ this.editorcore = editor.editorcore ? editor.editorcore : editor;
+ var editorcore = this.editorcore;
+ var _t = this;
- var fid = editor.frameId;
+ var fid = editorcore.frameId;
var etb = this;
function btn(id, toggle, handler){
var xid = fid + '-'+ id ;
cmd : id,
cls : 'x-btn-icon x-edit-'+id,
enableToggle:toggle !== false,
- scope: editor, // was editor...
- handler:handler||editor.relayBtnCmd,
+ scope: _t, // was editor...
+ handler:handler||_t.relayBtnCmd,
clickEvent:'mousedown',
tooltip: etb.buttonTips[id] || undefined, ///tips ???
tabIndex:-1
width:135,
listeners : {
'select': function(c, r, i) {
- editor.insertTag(r.get('tag'));
+ editorcore.insertTag(r.get('tag'));
editor.focus();
}
}
'-',
- btn('increasefontsize', false, editor.adjustFont),
- btn('decreasefontsize', false, editor.adjustFont)
+ btn('increasefontsize', false, editorcore.adjustFont),
+ btn('decreasefontsize', false, editorcore.adjustFont)
);
};
if(!this.disable.colors){
tb.add(
'-', {
- id:editor.frameId +'-forecolor',
+ id:editorcore.frameId +'-forecolor',
cls:'x-btn-icon x-edit-forecolor',
clickEvent:'mousedown',
tooltip: this.buttonTips['forecolor'] || undefined,
value:'000000',
plain:true,
selectHandler: function(cp, color){
- editor.execCmd('forecolor', Roo.isSafari || Roo.isIE ? '#'+color : color);
+ editorcore.execCmd('forecolor', Roo.isSafari || Roo.isIE ? '#'+color : color);
editor.deferFocus();
},
- scope: editor,
+ scope: editorcore,
clickEvent:'mousedown'
})
}, {
- id:editor.frameId +'backcolor',
+ id:editorcore.frameId +'backcolor',
cls:'x-btn-icon x-edit-backcolor',
clickEvent:'mousedown',
tooltip: this.buttonTips['backcolor'] || undefined,
allowReselect: true,
selectHandler: function(cp, color){
if(Roo.isGecko){
- editor.execCmd('useCSS', false);
- editor.execCmd('hilitecolor', color);
- editor.execCmd('useCSS', true);
+ editorcore.execCmd('useCSS', false);
+ editorcore.execCmd('hilitecolor', color);
+ editorcore.execCmd('useCSS', true);
editor.deferFocus();
}else{
- editor.execCmd(Roo.isOpera ? 'hilitecolor' : 'backcolor',
+ editorcore.execCmd(Roo.isOpera ? 'hilitecolor' : 'backcolor',
Roo.isSafari || Roo.isIE ? '#'+color : color);
editor.deferFocus();
}
},
- scope:editor,
+ scope:editorcore,
clickEvent:'mousedown'
})
}
if(!this.disable.links){
tb.add(
'-',
- btn('createlink', false, editor.createLink) /// MOVE TO HERE?!!?!?!?!
+ btn('createlink', false, this.createLink) /// MOVE TO HERE?!!?!?!?!
);
};
tb.add(
'-',
btn('sourceedit', true, function(btn){
+ Roo.log(this);
this.toggleSourceEdit(btn.pressed);
})
);
html: this.specialChars[i],
handler: function(a,b) {
- editor.insertAtCursor(String.fromCharCode(a.html.replace('&#','').replace(';', '')));
+ editorcore.insertAtCursor(String.fromCharCode(a.html.replace('&#','').replace(';', '')));
//editor.insertAtCursor(a.html);
},
handler: function(a,b) {
Roo.log(a);
Roo.log(b);
- var c = Roo.get(editor.doc.body);
+ var c = Roo.get(editorcore.doc.body);
c.select('[style]').each(function(s) {
s.dom.style.removeProperty(a.actiontype);
});
for(var i =0; i< this.btns.length;i++) {
var b = Roo.factory(this.btns[i],Roo.form);
b.cls = 'x-edit-none';
- b.scope = editor;
+ b.scope = editorcore;
tb.add(b);
}
// disable everything...
this.tb.items.each(function(item){
- if(item.id != editor.frameId+ '-sourceedit'){
+ if(item.id != editorcore.frameId+ '-sourceedit'){
item.disable();
}
});
},
+ relayBtnCmd : function(btn) {
+ this.editorcore.relayCmd(btn.cmd);
+ },
+ // private used internally
+ createLink : function(){
+ Roo.log("create link?");
+ var url = prompt(this.createLinkText, this.defaultLinkValue);
+ if(url && url != 'http:/'+'/'){
+ this.editorcore.relayCmd('createlink', url);
+ }
+ },
+
/**
* Protected method that will not generally be called directly. It triggers
*/
updateToolbar: function(){
- if(!this.editor.activated){
+ if(!this.editorcore.activated){
this.editor.onFirstFocus();
return;
}
var btns = this.tb.items.map,
- doc = this.editor.doc,
- frameId = this.editor.frameId;
+ doc = this.editorcore.doc,
+ frameId = this.editorcore.frameId;
if(!this.disable.font && !Roo.isSafari){
/*
btns[frameId + '-insertunorderedlist'].toggle(doc.queryCommandState('insertunorderedlist'));
}
- var ans = this.editor.getAllAncestors();
+ var ans = this.editorcore.getAllAncestors();
if (this.formatCombo) {
},
toggleSourceEdit : function(sourceEditMode){
+
+ Roo.log("toolbar toogle");
if(sourceEditMode === undefined){
sourceEditMode = !this.sourceEditMode;
}
this.sourceEditMode = sourceEditMode === true;
- var btn = this.tb.items.get(this.editor.frameId +'-sourceedit');
+ var btn = this.tb.items.get(this.editorcore.frameId +'-sourceedit');
// just toggle the button?
- if(btn.pressed !== this.editor.sourceEditMode){
- btn.toggle(this.editor.sourceEditMode);
+ if(btn.pressed !== this.sourceEditMode){
+ btn.toggle(this.sourceEditMode);
return;
}
- if(this.sourceEditMode){
+ if(sourceEditMode){
+ Roo.log("disabling buttons");
this.tb.items.each(function(item){
if(item.cmd != 'sourceedit'){
item.disable();
});
}else{
- if(this.initialized){
+ Roo.log("enabling buttons");
+ if(this.editorcore.initialized){
this.tb.items.each(function(item){
item.enable();
});
}
}
+ Roo.log("calling toggole on editor");
// tell the editor that it's been pressed..
this.editor.toggleSourceEdit(sourceEditMode);
rendered: false,
editor : false,
+ editorcore : false,
/**
* @cfg {Object} disable List of toolbar elements to disable
init : function(editor)
{
this.editor = editor;
+ this.editorcore = editor.editorcore ? editor.editorcore : editor;
+ var editorcore = this.editorcore;
-
- var fid = editor.frameId;
+ var fid = editorcore.frameId;
var etb = this;
function btn(id, toggle, handler){
var xid = fid + '-'+ id ;
cmd : id,
cls : 'x-btn-icon x-edit-'+id,
enableToggle:toggle !== false,
- scope: editor, // was editor...
- handler:handler||editor.relayBtnCmd,
+ scope: editorcore, // was editor...
+ handler:handler||editorcore.relayBtnCmd,
clickEvent:'mousedown',
tooltip: etb.buttonTips[id] || undefined, ///tips ???
tabIndex:-1
//Roo.log(ev);
// capture mouse up - this is handy for selecting images..
// perhaps should go somewhere else...
- if(!this.editor.activated){
+ if(!this.editorcore.activated){
this.editor.onFirstFocus();
return;
}
nodeRange.selectNodeContents(sel);
}
//nodeRange.collapse(true);
- var s = editor.win.getSelection();
+ var s = this.editorcore.win.getSelection();
s.removeAllRanges();
s.addRange(nodeRange);
}
var updateFooter = sel ? false : true;
- var ans = this.editor.getAllAncestors();
+ var ans = this.editorcore.getAllAncestors();
// pick
var ty= Roo.form.HtmlEditor.ToolbarContext.types;
if (!sel) {
- 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;
+ sel = ans.length ? (ans[0] ? ans[0] : ans[1]) : this.editorcore.doc.body;
+ sel = sel ? sel : this.editorcore.doc.body;
+ sel = sel.tagName.length ? sel : this.editorcore.doc.body;
}
// pick a menu that exists..
buildToolbar: function(tlist, nm)
{
var editor = this.editor;
+ var editorcore = this.editorcore;
// create a new element.
var wdiv = editor.wrap.createChild({
tag: 'div'
'select': function(c, r, i) {
// initial support only for on class per el..
tb.selectedNode.className = r ? r.get('val') : '';
- editor.syncValue();
+ editorcore.syncValue();
}
}
}
pn.removeChild(sn);
- var range = editor.createRange();
+ var range = editorcore.createRange();
range.setStart(stn,0);
range.setEnd(en,0); //????
//range.selectNode(sel);
- var selection = editor.getSelection();
+ var selection = editorcore.getSelection();
selection.removeAllRanges();
selection.addRange(range);
var sel = ans[n];
// pick
- var range = this.editor.createRange();
+ var range = this.editorcore.createRange();
range.selectNodeContents(sel);
//range.selectNode(sel);
- var selection = this.editor.getSelection();
+ var selection = this.editorcore.getSelection();
selection.removeAllRanges();
selection.addRange(range);
var v = this.view;
var header = v.findHeaderIndex(t);
if(header !== false){
- this.fireEvent("header" + (name == 'touchstart' ? 'click' : name), this, header, e);
+ var ename = name == 'touchstart' ? 'click' : name;
+
+ this.fireEvent("header" + ename, this, header, e);
}else{
var row = v.findRowIndex(t);
var cell = v.findCellIndex(t);
hdClass : "x-grid-hd",
splitClass : "x-grid-hd-split",
- init: function(grid){
+ init: function(grid){
this.grid = grid;
var cid = this.grid.getGridEl().id;
this.colSelector = "#" + cid + " ." + this.cellClass + "-";
this.splitSelector = "#" + cid + " ." + this.splitClass + "-";
},
- getColumnRenderers : function(){
+ getColumnRenderers : function(){
var renderers = [];
var cm = this.grid.colModel;
var colCount = cm.getColumnCount();
},
- handleHeaderClick : function(g, index){
+ handleHeaderClick : function(g, index,e){
+
+ Roo.log("header click");
+
+ if (Roo.isTouch) {
+ // touch events on header are handled by context
+ this.handleHdCtx(g,index,e);
+ return;
+ }
+
+
if(this.headersDisabled){
return;
}
cm.setLocked(index, false);
}
break;
+ case 'wider': // used to expand cols on touch..
+ case 'narrow':
+ var cw = cm.getColumnWidth(index);
+ cw += (item.id == 'wider' ? 1 : -1) * 50;
+ cw = Math.max(0, cw);
+ cw = Math.min(cw,4000);
+ cm.setColumnWidth(index, cw);
+ break;
+
default:
index = cm.getIndexById(item.id.substr(4));
if(index != -1){
{id:"unlock", text: this.unlockText, cls: "xg-hmenu-unlock"}
);
}
+ if (Roo.isTouch) {
+ this.hmenu.add('-',
+ {id:"wider", text: this.columnsWiderText},
+ {id:"narrow", text: this.columnsNarrowText }
+ );
+
+
+ }
+
if(this.grid.enableColumnHide !== false){
this.colMenu = new Roo.menu.Menu({id:this.grid.id + "-hcols-menu"});
sortDescText : "Sort Descending",
lockText : "Lock Column",
unlockText : "Unlock Column",
- columnsText : "Columns"
+ columnsText : "Columns",
+
+ columnsWiderText : "Wider",
+ columnsNarrowText : "Thinner"
});
if (this.eventStore) {
this.eventStore= Roo.factory(this.eventStore, Roo.data);
this.eventStore.on('load',this.onLoad, this);
+ this.eventStore.on('beforeload',this.clearEvents, this);
}
* @param {Calendar} this
* @param {event}
*/
- 'eventclick': true
+ 'eventclick': true,
+ /**
+ * @event eventrender
+ * Fires before each cell is rendered, so you can modify the contents, like cls / title / qtip
+ * @param {Calendar} this
+ * @param {data} data to be modified
+ */
+ 'eventrender': true
+
});
Roo.grid.Grid.superclass.constructor.call(this);
},this);
+ if (!Roo.grid.Calendar.style) {
+ Roo.grid.Calendar.style = Roo.util.CSS.createStyleSheet({
+
+
+ '.x-grid-cal .x-grid-col' : {
+ height: 'auto !important',
+ 'vertical-align': 'top'
+ },
+ '.x-grid-cal .fc-event-hori' : {
+ height: '14px'
+ }
+
+
+ }, Roo.id());
+ }
+
+
+
};
Roo.extend(Roo.grid.Calendar, Roo.grid.Grid, {
/**
return ret;
},
- findCells : function(ev) {
- var s = ev.start_dt.clone().clearTime().getTime();
+ findCells : function(rec) {
+ var s = rec.data.start_dt.clone().clearTime().getTime();
// Roo.log(s);
- var e= ev.end_dt.clone().clearTime().getTime();
+ var e= rec.data.end_dt.clone().clearTime().getTime();
// Roo.log(e);
var ret = [];
this.cells.each(function(c){
},
- addItem : function(ev)
+ addItem : function(rec)
{
// look for vertical location slot in
- var cells = this.findCells(ev);
+ var cells = this.findCells(rec);
- ev.row = this.findBestRow(cells);
+ rec.row = this.findBestRow(cells);
// work out the location.
}
rows.push(crow);
- ev.els = [];
- ev.rows = rows;
- ev.cells = cells;
+ rec.els = [];
+ rec.rows = rows;
+ rec.cells = cells;
for (var i = 0; i < cells.length;i++) {
- cells[i].rows = Math.max(cells[i].rows || 0 , ev.row + 1 );
+ cells[i].rows = Math.max(cells[i].rows || 0 , rec.row + 1 );
}
- this.calevents.push(ev);
+
},
clearEvents: function() {
- if(!this.calevents){
+ if (!this.eventStore.getCount()) {
return;
}
-
+ // reset number of rows in cells.
Roo.each(this.cells.elements, function(c){
c.rows = 0;
});
- Roo.each(this.calevents, function(e) {
- Roo.each(e.els, function(el) {
+ this.eventStore.each(function(e) {
+ this.clearEvent(e);
+ },this);
+
+ },
+
+ clearEvent : function(ev)
+ {
+ if (ev.els) {
+ Roo.each(ev.els, function(el) {
el.un('mouseenter' ,this.onEventEnter, this);
el.un('mouseleave' ,this.onEventLeave, this);
el.remove();
},this);
- },this);
+ ev.els = [];
+ }
+ },
+
+
+ renderEvent : function(ev,ctr) {
+ if (!ctr) {
+ ctr = this.view.el.select('.fc-event-container',true).first();
+ }
+
+ this.clearEvent(ev);
+ //code
+
+
+
+ ev.els = [];
+ var cells = ev.cells;
+ var rows = ev.rows;
+ this.fireEvent('eventrender', this, ev);
+
+ for(var i =0; i < rows.length; i++) {
+
+ cls = '';
+ if (i == 0) {
+ cls += ' fc-event-start';
+ }
+ if ((i+1) == rows.length) {
+ cls += ' fc-event-end';
+ }
+
+ //Roo.log(ev.data);
+ // how many rows should it span..
+ var cg = this.eventTmpl.append(ctr,Roo.apply({
+ fccls : cls
+
+ }, ev.data) , true);
+
+
+ cg.on('mouseenter' ,this.onEventEnter, this, ev);
+ cg.on('mouseleave' ,this.onEventLeave, this, ev);
+ cg.on('click', this.onEventClick, this, ev);
+
+ ev.els.push(cg);
+
+ var sbox = rows[i].start.select('.fc-day-content',true).first().getBox();
+ var ebox = rows[i].end.select('.fc-day-content',true).first().getBox();
+ //Roo.log(cg);
+
+ cg.setXY([sbox.x +2, sbox.y +(ev.row * 20)]);
+ cg.setWidth(ebox.right - sbox.x -2);
+ }
},
renderEvents: function()
{
// first make sure there is enough space..
+ if (!this.eventTmpl) {
+ this.eventTmpl = new Roo.Template(
+ '<div class="roo-dynamic fc-event fc-event-hori fc-event-draggable ui-draggable {fccls} {cls}" style="position: absolute" unselectable="on">' +
+ '<div class="fc-event-inner">' +
+ '<span class="fc-event-time">{time}</span>' +
+ '<span class="fc-event-title" qtip="{qtip}">{title}</span>' +
+ '</div>' +
+ '<div class="ui-resizable-heandle ui-resizable-e"> </div>' +
+ '</div>'
+ );
+
+ }
+
+
+
this.cells.each(function(c) {
- Roo.log(c.select('.fc-day-content div',true).first());
+ //Roo.log(c.select('.fc-day-content div',true).first());
c.select('.fc-day-content div',true).first().setHeight(Math.max(34, (c.rows || 1) * 20));
});
- for (var e = 0; e < this.calevents.length; e++) {
- var ev = this.calevents[e];
- var cells = ev.cells;
- var rows = ev.rows;
-
- for(var i =0; i < rows.length; i++) {
-
-
- // how many rows should it span..
-
- var cfg = {
- cls : 'roo-dynamic fc-event fc-event-hori fc-event-draggable ui-draggable',
- style : 'position: absolute', // left: 387px; width: 121px; top: 359px;
-
- unselectable : "on",
- cn : [
- {
- cls: 'fc-event-inner',
- cn : [
- {
- tag:'span',
- cls: 'fc-event-time',
- html : cells.length > 1 ? '' : ev.start_dt.format('h:ia')
- },
- {
- tag:'span',
- cls: 'fc-event-title',
- html : String.format('{0}', ev.title),
- qtip: String.format('{0} - {1}', ev.title,ev.description || '')
- }
-
-
- ]
- },
- {
- cls: 'ui-resizable-handle ui-resizable-e',
- html : '  '
- }
-
- ]
- };
- if (i == 0) {
- cfg.cls += ' fc-event-start';
- }
- if ((i+1) == rows.length) {
- cfg.cls += ' fc-event-end';
- }
-
- var ctr = this.view.el.select('.fc-event-container',true).first();
- var cg = ctr.createChild(cfg);
-
- cg.on('mouseenter' ,this.onEventEnter, this, ev);
- cg.on('mouseleave' ,this.onEventLeave, this, ev);
- cg.on('click', this.onEventClick, this, ev);
-
- ev.els.push(cg);
-
- var sbox = rows[i].start.select('.fc-day-content',true).first().getBox();
- var ebox = rows[i].end.select('.fc-day-content',true).first().getBox();
- //Roo.log(cg);
-
- Roo.log()
-
- cg.setXY([sbox.x +2, sbox.y +(ev.row * 20)]);
- cg.setWidth(ebox.right - sbox.x -2);
- }
-
+ var ctr = this.view.el.select('.fc-event-container',true).first();
+
+ var cls;
+ this.eventStore.each(function(ev){
- }
+ this.renderEvent(ev);
+
+
+ }, this);
this.view.layout();
},
onLoad: function () {
- this.clearEvents();
//Roo.log('calendar onload');
-//
- this.calevents = [];
-
+//
if(this.eventStore.getCount() > 0){
- this.eventStore.data.each(function(d){
+ this.eventStore.each(function(d){
// FIXME..
- var add = Roo.apply({}, d.data);
+ var add = d.data;
if (typeof(add.end_dt) == 'undefined') {
Roo.log("Missing End time in calendar data: ");
Roo.log(d);
add.end_dt = typeof(add.end_dt) == 'string' ? Date.parseDate(add.end_dt,'Y-m-d H:i:s') : add.end_dt,
add.id = add.id || d.id;
add.title = add.title || '??';
- this.addItem(add);
-
-
- // other than the 'required' coluns, we should just pass the data from the store.
+ this.addItem(d);
- /*cal.addItem({
- id : d.data.id,
- start: new Date(d.data.start_dt),
- end : new Date(d.data.end_dt),
- time : d.data.start_time,
- title : d.data.title,
- description : d.data.description,
- venue : d.data.venue
- });*/
+
},this);
}