isWindows = (ua.indexOf("windows") != -1 || ua.indexOf("win32") != -1),
isMac = (ua.indexOf("macintosh") != -1 || ua.indexOf("mac os x") != -1),
isLinux = (ua.indexOf("linux") != -1),
- isSecure = window.location.href.toLowerCase().indexOf("https") === 0;
-
+ isSecure = window.location.href.toLowerCase().indexOf("https") === 0,
+ isTouch = 'ontouchstart' in window || window.DocumentTouch && document instanceof DocumentTouch;
// remove css image flicker
if(isIE && !isIE7){
try{
BLANK_IMAGE_URL : "http:/"+"/localhost/s.gif",
emptyFn : function(){},
-
+
/**
* Copies all the properties of config to obj if they don't already exist.
* @param {Object} obj The receiver of the properties
isLinux : isLinux,
/** @type Boolean */
isMac : isMac,
+ /** @type Boolean */
+ isTouch : isTouch,
/**
* By default, Ext intelligently decides whether floating elements should be shimmed. If you are using flash,
getTarget: function(ev, resolveTextNode) {
ev = ev.browserEvent || ev;
+ ev = ev.touches ? (ev.touches[0] || ev.changedTouches[0] || ev ) : ev;
var t = ev.target || ev.srcElement;
return this.resolveTextNode(t);
},
getPageX: function(ev) {
ev = ev.browserEvent || ev;
+ ev = ev.touches ? (ev.touches[0] || ev.changedTouches[0] || ev ) : ev;
var x = ev.pageX;
if (!x && 0 !== x) {
x = ev.clientX || 0;
getPageY: function(ev) {
ev = ev.browserEvent || ev;
+ ev = ev.touches ? (ev.touches[0] || ev.changedTouches[0] || ev ) : ev;
var y = ev.pageY;
if (!y && 0 !== y) {
y = ev.clientY || 0;
getXY: function(ev) {
ev = ev.browserEvent || ev;
+ ev = ev.touches ? (ev.touches[0] || ev.changedTouches[0] || ev ) : ev;
return [this.getPageX(ev), this.getPageY(ev)];
},
getRelatedTarget: function(ev) {
ev = ev.browserEvent || ev;
+ ev = ev.touches ? (ev.touches[0] || ev.changedTouches[0] || ev ) : ev;
var t = ev.relatedTarget;
if (!t) {
if (ev.type == "mouseout") {
getTime: function(ev) {
ev = ev.browserEvent || ev;
+ ev = ev.touches ? (ev.touches[0] || ev.changedTouches[0] || ev ) : ev;
if (!ev.time) {
var t = new Date().getTime();
try {
Roo.lib.AnimMgr = new function() {
- var thread = null;
+ var thread = null;
- var queue = [];
+ var queue = [];
- var tweenCount = 0;
+ var tweenCount = 0;
- this.fps = 1000;
+ this.fps = 1000;
- this.delay = 1;
+ this.delay = 1;
- this.registerElement = function(tween) {
- queue[queue.length] = tween;
- tweenCount += 1;
- tween._onStart.fire();
- this.start();
- };
+ this.registerElement = function(tween) {
+ queue[queue.length] = tween;
+ tweenCount += 1;
+ tween._onStart.fire();
+ this.start();
+ };
- this.unRegister = function(tween, index) {
- tween._onComplete.fire();
- index = index || getIndex(tween);
- if (index != -1) {
- queue.splice(index, 1);
- }
+ this.unRegister = function(tween, index) {
+ tween._onComplete.fire();
+ index = index || getIndex(tween);
+ if (index != -1) {
+ queue.splice(index, 1);
+ }
- tweenCount -= 1;
- if (tweenCount <= 0) {
- this.stop();
- }
- };
+ tweenCount -= 1;
+ if (tweenCount <= 0) {
+ this.stop();
+ }
+ };
- this.start = function() {
- if (thread === null) {
- thread = setInterval(this.run, this.delay);
- }
- };
+ this.start = function() {
+ if (thread === null) {
+ thread = setInterval(this.run, this.delay);
+ }
+ };
- this.stop = function(tween) {
- if (!tween) {
- clearInterval(thread);
+ this.stop = function(tween) {
+ if (!tween) {
+ clearInterval(thread);
- for (var i = 0, len = queue.length; i < len; ++i) {
- if (queue[0].isAnimated()) {
- this.unRegister(queue[0], 0);
- }
+ for (var i = 0, len = queue.length; i < len; ++i) {
+ if (queue[0].isAnimated()) {
+ this.unRegister(queue[0], 0);
}
-
- queue = [];
- thread = null;
- tweenCount = 0;
- }
- else {
- this.unRegister(tween);
}
- };
+ queue = [];
+ thread = null;
+ tweenCount = 0;
+ }
+ else {
+ this.unRegister(tween);
+ }
+ };
- this.run = function() {
- for (var i = 0, len = queue.length; i < len; ++i) {
- var tween = queue[i];
- if (!tween || !tween.isAnimated()) {
- continue;
- }
- if (tween.currentFrame < tween.totalFrames || tween.totalFrames === null)
- {
- tween.currentFrame += 1;
+ this.run = function() {
+ for (var i = 0, len = queue.length; i < len; ++i) {
+ var tween = queue[i];
+ if (!tween || !tween.isAnimated()) {
+ continue;
+ }
- if (tween.useSeconds) {
- correctFrame(tween);
- }
- tween._onTween.fire();
- }
- else {
- Roo.lib.AnimMgr.stop(tween, i);
+ if (tween.currentFrame < tween.totalFrames || tween.totalFrames === null)
+ {
+ tween.currentFrame += 1;
+
+ if (tween.useSeconds) {
+ correctFrame(tween);
}
+ tween._onTween.fire();
}
- };
+ else {
+ Roo.lib.AnimMgr.stop(tween, i);
+ }
+ }
+ };
- var getIndex = function(anim) {
- for (var i = 0, len = queue.length; i < len; ++i) {
- if (queue[i] == anim) {
- return i;
- }
+ var getIndex = function(anim) {
+ for (var i = 0, len = queue.length; i < len; ++i) {
+ if (queue[i] == anim) {
+ return i;
}
- return -1;
- };
+ }
+ return -1;
+ };
- var correctFrame = function(tween) {
- var frames = tween.totalFrames;
- var frame = tween.currentFrame;
- var expected = (tween.currentFrame * tween.duration * 1000 / tween.totalFrames);
- var elapsed = (new Date() - tween.getStartTime());
- var tweak = 0;
+ var correctFrame = function(tween) {
+ var frames = tween.totalFrames;
+ var frame = tween.currentFrame;
+ var expected = (tween.currentFrame * tween.duration * 1000 / tween.totalFrames);
+ var elapsed = (new Date() - tween.getStartTime());
+ var tweak = 0;
- if (elapsed < tween.duration * 1000) {
- tweak = Math.round((elapsed / expected - 1) * tween.currentFrame);
- } else {
+ if (elapsed < tween.duration * 1000) {
+ tweak = Math.round((elapsed / expected - 1) * tween.currentFrame);
+ } else {
+ tweak = frames - (frame + 1);
+ }
+ if (tweak > 0 && isFinite(tweak)) {
+ if (tween.currentFrame + tweak >= frames) {
tweak = frames - (frame + 1);
}
- if (tweak > 0 && isFinite(tweak)) {
- if (tween.currentFrame + tweak >= frames) {
- tweak = frames - (frame + 1);
- }
- tween.currentFrame += tweak;
- }
- };
- };/*
+ tween.currentFrame += tweak;
+ }
+ };
+};
+
+ /*
* Portions of this file are based on pieces of Yahoo User Interface Library
* Copyright (c) 2007, Yahoo! Inc. All rights reserved.
* YUI licensed under the BSD License:
* Fork - LGPL
* <script type="text/javascript">
*/
+
-
-
-/*
- * These classes are derivatives of the similarly named classes in the YUI Library.
- * The original license:
- * Copyright (c) 2006, Yahoo! Inc. All rights reserved.
- * Code licensed under the BSD License:
- * http://developer.yahoo.net/yui/license.txt
+/**
+ * @class Roo.ComponentMgr
+ * Provides a common registry of all components on a page so that they can be easily accessed by component id (see {@link Roo.getCmp}).
+ * @singleton
*/
+Roo.ComponentMgr = function(){
+ var all = new Roo.util.MixedCollection();
-(function() {
+ return {
+ /**
+ * Registers a component.
+ * @param {Roo.Component} c The component
+ */
+ register : function(c){
+ all.add(c);
+ },
-var Event=Roo.EventManager;
-var Dom=Roo.lib.Dom;
+ /**
+ * Unregisters a component.
+ * @param {Roo.Component} c The component
+ */
+ unregister : function(c){
+ all.remove(c);
+ },
+ /**
+ * Returns a component by id
+ * @param {String} id The component id
+ */
+ get : function(id){
+ return all.get(id);
+ },
+
+ /**
+ * Registers a function that will be called when a specified component is added to ComponentMgr
+ * @param {String} id The component id
+ * @param {Funtction} fn The callback function
+ * @param {Object} scope The scope of the callback
+ */
+ onAvailable : function(id, fn, scope){
+ all.on("add", function(index, o){
+ if(o.id == id){
+ fn.call(scope || o, o);
+ all.un("add", fn, scope);
+ }
+ });
+ }
+ };
+}();/*
+ * 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.dd.DragDrop
+ * @class Roo.Component
* @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.
- * Up to three html elements can be associated with a DragDrop instance:
- * <ul>
- * <li>linked element: the element that is passed into the constructor.
- * This is the element which defines the boundaries for interaction with
- * other DragDrop objects.</li>
- * <li>handle element(s): The drag operation only occurs if the element that
- * was clicked matches a handle element. By default this is the linked
- * element, but there are times that you will want only a portion of the
- * linked element to initiate the drag operation, and the setHandleElId()
- * method provides a way to define this.</li>
- * <li>drag element: this represents the element that would be moved along
- * with the cursor during a drag operation. By default, this is the linked
- * element itself as in {@link Roo.dd.DD}. setDragElId() lets you define
- * a separate element that would be moved, as in {@link Roo.dd.DDProxy}.
- * </li>
- * </ul>
- * This class should not be instantiated until the onload event to ensure that
- * the associated elements are available.
- * The following would define a DragDrop obj that would interact with any
- * other DragDrop obj in the "group1" group:
- * <pre>
- * dd = new Roo.dd.DragDrop("div1", "group1");
- * </pre>
- * Since none of the event handlers have been implemented, nothing would
- * actually happen if you were to run the code above. Normally you would
- * override this class or one of the default implementations, but you can
- * also override the methods you want on an instance of the class...
- * <pre>
- * dd.onDragDrop = function(e, id) {
- * alert("dd was dropped on " + id);
- * }
- * </pre>
+ * Base class for all major Roo components. All subclasses of Component can automatically participate in the standard
+ * Roo component lifecycle of creation, rendering and destruction. They also have automatic support for basic hide/show
+ * and enable/disable behavior. Component allows any subclass to be lazy-rendered into any {@link Roo.Container} and
+ * to be automatically registered with the {@link Roo.ComponentMgr} so that it can be referenced at any time via {@link Roo.getCmp}.
+ * All visual components (widgets) that require rendering into a layout should subclass Component.
* @constructor
- * @param {String} id of the element that is linked to this instance
- * @param {String} sGroup the group of related DragDrop objects
- * @param {object} config an object containing configurable attributes
- * Valid properties for DragDrop:
- * padding, isTarget, maintainOffset, primaryButtonOnly
+ * @param {Roo.Element/String/Object} config The configuration options. If an element is passed, it is set as the internal
+ * element and its id used as the component id. If a string is passed, it is assumed to be the id of an existing element
+ * and is used as the component id. Otherwise, it is assumed to be a standard config object and is applied to the component.
*/
-Roo.dd.DragDrop = function(id, sGroup, config) {
- if (id) {
- this.init(id, sGroup, config);
+Roo.Component = function(config){
+ config = config || {};
+ if(config.tagName || config.dom || typeof config == "string"){ // element object
+ config = {el: config, id: config.id || config};
+ }
+ this.initialConfig = config;
+
+ Roo.apply(this, config);
+ this.addEvents({
+ /**
+ * @event disable
+ * Fires after the component is disabled.
+ * @param {Roo.Component} this
+ */
+ disable : true,
+ /**
+ * @event enable
+ * Fires after the component is enabled.
+ * @param {Roo.Component} this
+ */
+ enable : true,
+ /**
+ * @event beforeshow
+ * Fires before the component is shown. Return false to stop the show.
+ * @param {Roo.Component} this
+ */
+ beforeshow : true,
+ /**
+ * @event show
+ * Fires after the component is shown.
+ * @param {Roo.Component} this
+ */
+ show : true,
+ /**
+ * @event beforehide
+ * Fires before the component is hidden. Return false to stop the hide.
+ * @param {Roo.Component} this
+ */
+ beforehide : true,
+ /**
+ * @event hide
+ * Fires after the component is hidden.
+ * @param {Roo.Component} this
+ */
+ hide : true,
+ /**
+ * @event beforerender
+ * Fires before the component is rendered. Return false to stop the render.
+ * @param {Roo.Component} this
+ */
+ beforerender : true,
+ /**
+ * @event render
+ * Fires after the component is rendered.
+ * @param {Roo.Component} this
+ */
+ render : true,
+ /**
+ * @event beforedestroy
+ * Fires before the component is destroyed. Return false to stop the destroy.
+ * @param {Roo.Component} this
+ */
+ beforedestroy : true,
+ /**
+ * @event destroy
+ * Fires after the component is destroyed.
+ * @param {Roo.Component} this
+ */
+ destroy : true
+ });
+ if(!this.id){
+ this.id = "ext-comp-" + (++Roo.Component.AUTO_ID);
+ }
+ Roo.ComponentMgr.register(this);
+ Roo.Component.superclass.constructor.call(this);
+ this.initComponent();
+ if(this.renderTo){ // not supported by all components yet. use at your own risk!
+ this.render(this.renderTo);
+ delete this.renderTo;
}
-
};
-Roo.extend(Roo.dd.DragDrop, Roo.util.Observable , {
+/** @private */
+Roo.Component.AUTO_ID = 1000;
+Roo.extend(Roo.Component, Roo.util.Observable, {
/**
- * The id of the element associated with this object. This is what we
- * refer to as the "linked element" because the size and position of
- * this element is used to determine when the drag and drop objects have
- * interacted.
- * @property id
- * @type String
+ * @scope Roo.Component.prototype
+ * @type {Boolean}
+ * true if this component is hidden. Read-only.
*/
- id: null,
-
+ hidden : false,
/**
- * Configuration attributes passed into the constructor
- * @property config
- * @type object
+ * @type {Boolean}
+ * true if this component is disabled. Read-only.
*/
- config: null,
-
+ disabled : false,
/**
- * The id of the element that will be dragged. By default this is same
- * as the linked element , but could be changed to another element. Ex:
- * Roo.dd.DDProxy
- * @property dragElId
- * @type String
- * @private
+ * @type {Boolean}
+ * true if this component has been rendered. Read-only.
*/
- dragElId: null,
-
- /**
- * the id of the element that initiates the drag operation. By default
- * this is the linked element, but could be changed to be a child of this
- * element. This lets us do things like only starting the drag when the
- * header element within the linked html element is clicked.
- * @property handleElId
- * @type String
- * @private
+ rendered : false,
+
+ /** @cfg {String} disableClass
+ * CSS class added to the component when it is disabled (defaults to "x-item-disabled").
*/
- handleElId: null,
-
- /**
- * An associative array of HTML tags that will be ignored if clicked.
- * @property invalidHandleTypes
- * @type {string: string}
+ disabledClass : "x-item-disabled",
+ /** @cfg {Boolean} allowDomMove
+ * Whether the component can move the Dom node when rendering (defaults to true).
+ */
+ allowDomMove : true,
+ /** @cfg {String} hideMode
+ * How this component should hidden. Supported values are
+ * "visibility" (css visibility), "offsets" (negative offset position) and
+ * "display" (css display) - defaults to "display".
*/
- invalidHandleTypes: null,
+ hideMode: 'display',
- /**
- * An associative array of ids for elements that will be ignored if clicked
- * @property invalidHandleIds
- * @type {string: string}
- */
- invalidHandleIds: null,
+ /** @private */
+ ctype : "Roo.Component",
/**
- * An indexted array of css class names for elements that will be ignored
- * if clicked.
- * @property invalidHandleClasses
- * @type string[]
+ * @cfg {String} actionMode
+ * which property holds the element that used for hide() / show() / disable() / enable()
+ * default is 'el'
*/
- invalidHandleClasses: null,
+ actionMode : "el",
- /**
- * The linked element's absolute X position at the time the drag was
- * started
- * @property startPageX
- * @type int
- * @private
- */
- startPageX: 0,
+ /** @private */
+ getActionEl : function(){
+ return this[this.actionMode];
+ },
+ initComponent : Roo.emptyFn,
/**
- * The linked element's absolute X position at the time the drag was
- * started
- * @property startPageY
- * @type int
- * @private
+ * If this is a lazy rendering component, render it to its container element.
+ * @param {String/HTMLElement/Element} container (optional) The element this component should be rendered into. If it is being applied to existing markup, this should be left off.
*/
- startPageY: 0,
+ render : function(container, position){
+ if(!this.rendered && this.fireEvent("beforerender", this) !== false){
+ if(!container && this.el){
+ this.el = Roo.get(this.el);
+ container = this.el.dom.parentNode;
+ this.allowDomMove = false;
+ }
+ this.container = Roo.get(container);
+ this.rendered = true;
+ if(position !== undefined){
+ if(typeof position == 'number'){
+ position = this.container.dom.childNodes[position];
+ }else{
+ position = Roo.getDom(position);
+ }
+ }
+ this.onRender(this.container, position || null);
+ if(this.cls){
+ this.el.addClass(this.cls);
+ delete this.cls;
+ }
+ if(this.style){
+ this.el.applyStyles(this.style);
+ delete this.style;
+ }
+ this.fireEvent("render", this);
+ this.afterRender(this.container);
+ if(this.hidden){
+ this.hide();
+ }
+ if(this.disabled){
+ this.disable();
+ }
+ }
+ return this;
+ },
- /**
- * The group defines a logical collection of DragDrop objects that are
- * related. Instances only get events when interacting with other
- * DragDrop object in the same group. This lets us define multiple
- * groups using a single DragDrop subclass if we want.
- * @property groups
- * @type {string: string}
- */
- groups: null,
+ /** @private */
+ // default function is not really useful
+ onRender : function(ct, position){
+ if(this.el){
+ this.el = Roo.get(this.el);
+ if(this.allowDomMove !== false){
+ ct.dom.insertBefore(this.el.dom, position);
+ }
+ }
+ },
- /**
- * Individual drag/drop instances can be locked. This will prevent
- * onmousedown start drag.
- * @property locked
- * @type boolean
- * @private
- */
- locked: false,
+ /** @private */
+ getAutoCreate : function(){
+ var cfg = typeof this.autoCreate == "object" ?
+ this.autoCreate : Roo.apply({}, this.defaultAutoCreate);
+ if(this.id && !cfg.id){
+ cfg.id = this.id;
+ }
+ return cfg;
+ },
- /**
- * Lock this instance
- * @method lock
- */
- lock: function() { this.locked = true; },
+ /** @private */
+ afterRender : Roo.emptyFn,
/**
- * Unlock this instace
- * @method unlock
+ * Destroys this component by purging any event listeners, removing the component's element from the DOM,
+ * removing the component from its {@link Roo.Container} (if applicable) and unregistering it from {@link Roo.ComponentMgr}.
*/
- unlock: function() { this.locked = false; },
+ destroy : function(){
+ if(this.fireEvent("beforedestroy", this) !== false){
+ this.purgeListeners();
+ this.beforeDestroy();
+ if(this.rendered){
+ this.el.removeAllListeners();
+ this.el.remove();
+ if(this.actionMode == "container"){
+ this.container.remove();
+ }
+ }
+ this.onDestroy();
+ Roo.ComponentMgr.unregister(this);
+ this.fireEvent("destroy", this);
+ }
+ },
- /**
- * By default, all insances can be a drop target. This can be disabled by
- * setting isTarget to false.
- * @method isTarget
- * @type boolean
- */
- isTarget: true,
+ /** @private */
+ beforeDestroy : function(){
- /**
- * The padding configured for this drag and drop object for calculating
- * the drop zone intersection with this object.
- * @method padding
- * @type int[]
- */
- padding: null,
+ },
- /**
- * Cached reference to the linked element
- * @property _domRef
- * @private
- */
- _domRef: null,
+ /** @private */
+ onDestroy : function(){
+
+ },
/**
- * Internal typeof flag
- * @property __ygDragDrop
- * @private
+ * Returns the underlying {@link Roo.Element}.
+ * @return {Roo.Element} The element
*/
- __ygDragDrop: true,
+ getEl : function(){
+ return this.el;
+ },
/**
- * Set to true when horizontal contraints are applied
- * @property constrainX
- * @type boolean
- * @private
+ * Returns the id of this component.
+ * @return {String}
*/
- constrainX: false,
+ getId : function(){
+ return this.id;
+ },
/**
- * Set to true when vertical contraints are applied
- * @property constrainY
- * @type boolean
- * @private
+ * Try to focus this component.
+ * @param {Boolean} selectText True to also select the text in this component (if applicable)
+ * @return {Roo.Component} this
*/
- constrainY: false,
+ focus : function(selectText){
+ if(this.rendered){
+ this.el.focus();
+ if(selectText === true){
+ this.el.dom.select();
+ }
+ }
+ return this;
+ },
- /**
- * The left constraint
- * @property minX
- * @type int
- * @private
- */
- minX: 0,
+ /** @private */
+ blur : function(){
+ if(this.rendered){
+ this.el.blur();
+ }
+ return this;
+ },
/**
- * The right constraint
- * @property maxX
- * @type int
- * @private
+ * Disable this component.
+ * @return {Roo.Component} this
*/
- maxX: 0,
+ disable : function(){
+ if(this.rendered){
+ this.onDisable();
+ }
+ this.disabled = true;
+ this.fireEvent("disable", this);
+ return this;
+ },
- /**
- * The up constraint
- * @property minY
- * @type int
- * @type int
- * @private
- */
- minY: 0,
+ // private
+ onDisable : function(){
+ this.getActionEl().addClass(this.disabledClass);
+ this.el.dom.disabled = true;
+ },
/**
- * The down constraint
- * @property maxY
- * @type int
- * @private
+ * Enable this component.
+ * @return {Roo.Component} this
*/
- maxY: 0,
+ enable : function(){
+ if(this.rendered){
+ this.onEnable();
+ }
+ this.disabled = false;
+ this.fireEvent("enable", this);
+ return this;
+ },
- /**
- * Maintain offsets when we resetconstraints. Set to true when you want
- * the position of the element relative to its parent to stay the same
- * when the page changes
- *
- * @property maintainOffset
- * @type boolean
- */
- maintainOffset: false,
+ // private
+ onEnable : function(){
+ this.getActionEl().removeClass(this.disabledClass);
+ this.el.dom.disabled = false;
+ },
/**
- * Array of pixel locations the element will snap to if we specified a
- * horizontal graduation/interval. This array is generated automatically
- * when you define a tick interval.
- * @property xTicks
- * @type int[]
+ * Convenience function for setting disabled/enabled by boolean.
+ * @param {Boolean} disabled
*/
- xTicks: null,
+ setDisabled : function(disabled){
+ this[disabled ? "disable" : "enable"]();
+ },
/**
- * Array of pixel locations the element will snap to if we specified a
- * vertical graduation/interval. This array is generated automatically
- * when you define a tick interval.
- * @property yTicks
- * @type int[]
+ * Show this component.
+ * @return {Roo.Component} this
*/
- yTicks: null,
+ show: function(){
+ if(this.fireEvent("beforeshow", this) !== false){
+ this.hidden = false;
+ if(this.rendered){
+ this.onShow();
+ }
+ this.fireEvent("show", this);
+ }
+ return this;
+ },
- /**
- * By default the drag and drop instance will only respond to the primary
- * button click (left button for a right-handed mouse). Set to true to
- * allow drag and drop to start with any mouse click that is propogated
- * by the browser
- * @property primaryButtonOnly
- * @type boolean
- */
- primaryButtonOnly: true,
+ // private
+ onShow : function(){
+ var ae = this.getActionEl();
+ if(this.hideMode == 'visibility'){
+ ae.dom.style.visibility = "visible";
+ }else if(this.hideMode == 'offsets'){
+ ae.removeClass('x-hidden');
+ }else{
+ ae.dom.style.display = "";
+ }
+ },
/**
- * The availabe property is false until the linked dom element is accessible.
- * @property available
- * @type boolean
+ * Hide this component.
+ * @return {Roo.Component} this
*/
- available: false,
+ hide: function(){
+ if(this.fireEvent("beforehide", this) !== false){
+ this.hidden = true;
+ if(this.rendered){
+ this.onHide();
+ }
+ this.fireEvent("hide", this);
+ }
+ return this;
+ },
- /**
- * By default, drags can only be initiated if the mousedown occurs in the
- * region the linked element is. This is done in part to work around a
- * bug in some browsers that mis-report the mousedown if the previous
- * mouseup happened outside of the window. This property is set to true
- * if outer handles are defined.
- *
- * @property hasOuterHandles
- * @type boolean
- * @default false
- */
- hasOuterHandles: false,
+ // private
+ onHide : function(){
+ var ae = this.getActionEl();
+ if(this.hideMode == 'visibility'){
+ ae.dom.style.visibility = "hidden";
+ }else if(this.hideMode == 'offsets'){
+ ae.addClass('x-hidden');
+ }else{
+ ae.dom.style.display = "none";
+ }
+ },
/**
- * Code that executes immediately before the startDrag event
- * @method b4StartDrag
- * @private
+ * Convenience function to hide or show this component by boolean.
+ * @param {Boolean} visible True to show, false to hide
+ * @return {Roo.Component} this
*/
- b4StartDrag: function(x, y) { },
+ setVisible: function(visible){
+ if(visible) {
+ this.show();
+ }else{
+ this.hide();
+ }
+ return this;
+ },
/**
- * Abstract method called after a drag/drop object is clicked
- * and the drag or mousedown time thresholds have beeen met.
- * @method startDrag
- * @param {int} X click location
- * @param {int} Y click location
+ * Returns true if this component is visible.
*/
- startDrag: function(x, y) { /* override this */ },
+ isVisible : function(){
+ return this.getActionEl().isVisible();
+ },
- /**
- * Code that executes immediately before the onDrag event
- * @method b4Drag
- * @private
- */
- b4Drag: function(e) { },
+ cloneConfig : function(overrides){
+ overrides = overrides || {};
+ var id = overrides.id || Roo.id();
+ var cfg = Roo.applyIf(overrides, this.initialConfig);
+ cfg.id = id; // prevent dup id
+ return new this.constructor(cfg);
+ }
+});/*
+ * 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">
+ */
- /**
- * Abstract method called during the onMouseMove event while dragging an
- * object.
- * @method onDrag
- * @param {Event} e the mousemove event
- */
- onDrag: function(e) { /* override this */ },
+/**
+ * @class Roo.BoxComponent
+ * @extends Roo.Component
+ * Base class for any visual {@link Roo.Component} that uses a box container. BoxComponent provides automatic box
+ * model adjustments for sizing and positioning and will work correctly withnin the Component rendering model. All
+ * container classes should subclass BoxComponent so that they will work consistently when nested within other Ext
+ * layout containers.
+ * @constructor
+ * @param {Roo.Element/String/Object} config The configuration options.
+ */
+Roo.BoxComponent = function(config){
+ Roo.Component.call(this, config);
+ this.addEvents({
+ /**
+ * @event resize
+ * Fires after the component is resized.
+ * @param {Roo.Component} this
+ * @param {Number} adjWidth The box-adjusted width that was set
+ * @param {Number} adjHeight The box-adjusted height that was set
+ * @param {Number} rawWidth The width that was originally specified
+ * @param {Number} rawHeight The height that was originally specified
+ */
+ resize : true,
+ /**
+ * @event move
+ * Fires after the component is moved.
+ * @param {Roo.Component} this
+ * @param {Number} x The new x position
+ * @param {Number} y The new y position
+ */
+ move : true
+ });
+};
- /**
- * Abstract method called when this element fist begins hovering over
- * another DragDrop obj
- * @method onDragEnter
- * @param {Event} e the mousemove event
- * @param {String|DragDrop[]} id In POINT mode, the element
- * id this is hovering over. In INTERSECT mode, an array of one or more
- * dragdrop items being hovered over.
+Roo.extend(Roo.BoxComponent, Roo.Component, {
+ // private, set in afterRender to signify that the component has been rendered
+ boxReady : false,
+ // private, used to defer height settings to subclasses
+ deferHeight: false,
+ /** @cfg {Number} width
+ * width (optional) size of component
*/
- onDragEnter: function(e, id) { /* override this */ },
-
- /**
- * Code that executes immediately before the onDragOver event
- * @method b4DragOver
- * @private
+ /** @cfg {Number} height
+ * height (optional) size of component
*/
- b4DragOver: function(e) { },
-
+
/**
- * Abstract method called when this element is hovering over another
- * DragDrop obj
- * @method onDragOver
- * @param {Event} e the mousemove event
- * @param {String|DragDrop[]} id In POINT mode, the element
- * id this is hovering over. In INTERSECT mode, an array of dd items
- * being hovered over.
+ * Sets the width and height of the component. This method fires the resize event. This method can accept
+ * either width and height as separate numeric arguments, or you can pass a size object like {width:10, height:20}.
+ * @param {Number/Object} width The new width to set, or a size object in the format {width, height}
+ * @param {Number} height The new height to set (not required if a size object is passed as the first arg)
+ * @return {Roo.BoxComponent} this
*/
- onDragOver: function(e, id) { /* override this */ },
+ setSize : function(w, h){
+ // support for standard size objects
+ if(typeof w == 'object'){
+ h = w.height;
+ w = w.width;
+ }
+ // not rendered
+ if(!this.boxReady){
+ this.width = w;
+ this.height = h;
+ return this;
+ }
- /**
- * Code that executes immediately before the onDragOut event
- * @method b4DragOut
- * @private
- */
- b4DragOut: function(e) { },
+ // prevent recalcs when not needed
+ if(this.lastSize && this.lastSize.width == w && this.lastSize.height == h){
+ return this;
+ }
+ this.lastSize = {width: w, height: h};
- /**
- * Abstract method called when we are no longer hovering over an element
- * @method onDragOut
- * @param {Event} e the mousemove event
- * @param {String|DragDrop[]} id In POINT mode, the element
- * id this was hovering over. In INTERSECT mode, an array of dd items
- * that the mouse is no longer over.
- */
- onDragOut: function(e, id) { /* override this */ },
+ var adj = this.adjustSize(w, h);
+ var aw = adj.width, ah = adj.height;
+ if(aw !== undefined || ah !== undefined){ // this code is nasty but performs better with floaters
+ var rz = this.getResizeEl();
+ if(!this.deferHeight && aw !== undefined && ah !== undefined){
+ rz.setSize(aw, ah);
+ }else if(!this.deferHeight && ah !== undefined){
+ rz.setHeight(ah);
+ }else if(aw !== undefined){
+ rz.setWidth(aw);
+ }
+ this.onResize(aw, ah, w, h);
+ this.fireEvent('resize', this, aw, ah, w, h);
+ }
+ return this;
+ },
/**
- * Code that executes immediately before the onDragDrop event
- * @method b4DragDrop
- * @private
+ * Gets the current size of the component's underlying element.
+ * @return {Object} An object containing the element's size {width: (element width), height: (element height)}
*/
- b4DragDrop: function(e) { },
+ getSize : function(){
+ return this.el.getSize();
+ },
/**
- * Abstract method called when this item is dropped on another DragDrop
- * obj
- * @method onDragDrop
- * @param {Event} e the mouseup event
- * @param {String|DragDrop[]} id In POINT mode, the element
- * id this was dropped on. In INTERSECT mode, an array of dd items this
- * was dropped on.
+ * Gets the current XY position of the component's underlying element.
+ * @param {Boolean} local (optional) If true the element's left and top are returned instead of page XY (defaults to false)
+ * @return {Array} The XY position of the element (e.g., [100, 200])
*/
- onDragDrop: function(e, id) { /* override this */ },
+ getPosition : function(local){
+ if(local === true){
+ return [this.el.getLeft(true), this.el.getTop(true)];
+ }
+ return this.xy || this.el.getXY();
+ },
/**
- * Abstract method called when this item is dropped on an area with no
- * drop target
- * @method onInvalidDrop
- * @param {Event} e the mouseup event
+ * Gets the current box measurements of the component's underlying element.
+ * @param {Boolean} local (optional) If true the element's left and top are returned instead of page XY (defaults to false)
+ * @returns {Object} box An object in the format {x, y, width, height}
*/
- onInvalidDrop: function(e) { /* override this */ },
+ getBox : function(local){
+ var s = this.el.getSize();
+ if(local){
+ s.x = this.el.getLeft(true);
+ s.y = this.el.getTop(true);
+ }else{
+ var xy = this.xy || this.el.getXY();
+ s.x = xy[0];
+ s.y = xy[1];
+ }
+ return s;
+ },
/**
- * Code that executes immediately before the endDrag event
- * @method b4EndDrag
- * @private
+ * Sets the current box measurements of the component's underlying element.
+ * @param {Object} box An object in the format {x, y, width, height}
+ * @returns {Roo.BoxComponent} this
*/
- b4EndDrag: function(e) { },
+ updateBox : function(box){
+ this.setSize(box.width, box.height);
+ this.setPagePosition(box.x, box.y);
+ return this;
+ },
- /**
- * Fired when we are done dragging the object
- * @method endDrag
- * @param {Event} e the mouseup event
- */
- endDrag: function(e) { /* override this */ },
+ // protected
+ getResizeEl : function(){
+ return this.resizeEl || this.el;
+ },
- /**
- * Code executed immediately before the onMouseDown event
- * @method b4MouseDown
- * @param {Event} e the mousedown event
- * @private
- */
- b4MouseDown: function(e) { },
+ // protected
+ getPositionEl : function(){
+ return this.positionEl || this.el;
+ },
/**
- * Event handler that fires when a drag/drop obj gets a mousedown
- * @method onMouseDown
- * @param {Event} e the mousedown event
+ * Sets the left and top of the component. To set the page XY position instead, use {@link #setPagePosition}.
+ * This method fires the move event.
+ * @param {Number} left The new left
+ * @param {Number} top The new top
+ * @returns {Roo.BoxComponent} this
*/
- onMouseDown: function(e) { /* override this */ },
+ setPosition : function(x, y){
+ this.x = x;
+ this.y = y;
+ if(!this.boxReady){
+ return this;
+ }
+ var adj = this.adjustPosition(x, y);
+ var ax = adj.x, ay = adj.y;
- /**
- * Event handler that fires when a drag/drop obj gets a mouseup
- * @method onMouseUp
- * @param {Event} e the mouseup event
- */
- onMouseUp: function(e) { /* override this */ },
+ var el = this.getPositionEl();
+ if(ax !== undefined || ay !== undefined){
+ if(ax !== undefined && ay !== undefined){
+ el.setLeftTop(ax, ay);
+ }else if(ax !== undefined){
+ el.setLeft(ax);
+ }else if(ay !== undefined){
+ el.setTop(ay);
+ }
+ this.onPosition(ax, ay);
+ this.fireEvent('move', this, ax, ay);
+ }
+ return this;
+ },
/**
- * Override the onAvailable method to do what is needed after the initial
- * position was determined.
- * @method onAvailable
+ * Sets the page XY position of the component. To set the left and top instead, use {@link #setPosition}.
+ * This method fires the move event.
+ * @param {Number} x The new x position
+ * @param {Number} y The new y position
+ * @returns {Roo.BoxComponent} this
*/
- onAvailable: function () {
+ setPagePosition : function(x, y){
+ this.pageX = x;
+ this.pageY = y;
+ if(!this.boxReady){
+ return;
+ }
+ if(x === undefined || y === undefined){ // cannot translate undefined points
+ return;
+ }
+ var p = this.el.translatePoints(x, y);
+ this.setPosition(p.left, p.top);
+ return this;
},
- /*
- * Provides default constraint padding to "constrainTo" elements (defaults to {left: 0, right:0, top:0, bottom:0}).
- * @type Object
- */
- defaultPadding : {left:0, right:0, top:0, bottom:0},
+ // private
+ onRender : function(ct, position){
+ Roo.BoxComponent.superclass.onRender.call(this, ct, position);
+ if(this.resizeEl){
+ this.resizeEl = Roo.get(this.resizeEl);
+ }
+ if(this.positionEl){
+ this.positionEl = Roo.get(this.positionEl);
+ }
+ },
- /*
- * Initializes the drag drop object's constraints to restrict movement to a certain element.
- *
- * Usage:
- <pre><code>
- var dd = new Roo.dd.DDProxy("dragDiv1", "proxytest",
- { dragElId: "existingProxyDiv" });
- dd.startDrag = function(){
- this.constrainTo("parent-id");
- };
- </code></pre>
+ // private
+ afterRender : function(){
+ Roo.BoxComponent.superclass.afterRender.call(this);
+ this.boxReady = true;
+ this.setSize(this.width, this.height);
+ if(this.x || this.y){
+ this.setPosition(this.x, this.y);
+ }
+ if(this.pageX || this.pageY){
+ this.setPagePosition(this.pageX, this.pageY);
+ }
+ },
+
+ /**
+ * Force the component's size to recalculate based on the underlying element's current height and width.
+ * @returns {Roo.BoxComponent} this
+ */
+ syncSize : function(){
+ delete this.lastSize;
+ this.setSize(this.el.getWidth(), this.el.getHeight());
+ return this;
+ },
+
+ /**
+ * Called after the component is resized, this method is empty by default but can be implemented by any
+ * subclass that needs to perform custom logic after a resize occurs.
+ * @param {Number} adjWidth The box-adjusted width that was set
+ * @param {Number} adjHeight The box-adjusted height that was set
+ * @param {Number} rawWidth The width that was originally specified
+ * @param {Number} rawHeight The height that was originally specified
+ */
+ onResize : function(adjWidth, adjHeight, rawWidth, rawHeight){
+
+ },
+
+ /**
+ * Called after the component is moved, this method is empty by default but can be implemented by any
+ * subclass that needs to perform custom logic after a move occurs.
+ * @param {Number} x The new x position
+ * @param {Number} y The new y position
+ */
+ onPosition : function(x, y){
+
+ },
+
+ // private
+ adjustSize : function(w, h){
+ if(this.autoWidth){
+ w = 'auto';
+ }
+ if(this.autoHeight){
+ h = 'auto';
+ }
+ return {width : w, height: h};
+ },
+
+ // private
+ adjustPosition : function(x, y){
+ return {x : x, y: y};
+ }
+});/*
+ * Original code for Roojs - LGPL
+ * <script type="text/javascript">
+ */
+
+/**
+ * @class Roo.XComponent
+ * A delayed Element creator...
+ * Or a way to group chunks of interface together.
+ *
+ * Mypart.xyx = new Roo.XComponent({
+
+ parent : 'Mypart.xyz', // empty == document.element.!!
+ order : '001',
+ name : 'xxxx'
+ region : 'xxxx'
+ disabled : function() {}
+
+ tree : function() { // return an tree of xtype declared components
+ var MODULE = this;
+ return
+ {
+ xtype : 'NestedLayoutPanel',
+ // technicall
+ }
+ ]
+ *})
+ *
+ *
+ * It can be used to build a big heiracy, with parent etc.
+ * or you can just use this to render a single compoent to a dom element
+ * MYPART.render(Roo.Element | String(id) | dom_element )
+ *
+ * @extends Roo.util.Observable
+ * @constructor
+ * @param cfg {Object} configuration of component
+ *
+ */
+Roo.XComponent = function(cfg) {
+ Roo.apply(this, cfg);
+ this.addEvents({
+ /**
+ * @event built
+ * Fires when this the componnt is built
+ * @param {Roo.XComponent} c the component
+ */
+ 'built' : true
+
+ });
+ this.region = this.region || 'center'; // default..
+ Roo.XComponent.register(this);
+ this.modules = false;
+ this.el = false; // where the layout goes..
+
+
+}
+Roo.extend(Roo.XComponent, Roo.util.Observable, {
+ /**
+ * @property el
+ * The created element (with Roo.factory())
+ * @type {Roo.Layout}
+ */
+ el : false,
+
+ /**
+ * @property el
+ * for BC - use el in new code
+ * @type {Roo.Layout}
+ */
+ panel : false,
+
+ /**
+ * @property layout
+ * for BC - use el in new code
+ * @type {Roo.Layout}
+ */
+ layout : false,
+
+ /**
+ * @cfg {Function|boolean} disabled
+ * If this module is disabled by some rule, return true from the funtion
+ */
+ disabled : false,
+
+ /**
+ * @cfg {String} parent
+ * Name of parent element which it get xtype added to..
+ */
+ parent: false,
+
+ /**
+ * @cfg {String} order
+ * Used to set the order in which elements are created (usefull for multiple tabs)
+ */
+
+ order : false,
+ /**
+ * @cfg {String} name
+ * String to display while loading.
+ */
+ name : false,
+ /**
+ * @cfg {String} region
+ * Region to render component to (defaults to center)
+ */
+ region : 'center',
+
+ /**
+ * @cfg {Array} items
+ * A single item array - the first element is the root of the tree..
+ * It's done this way to stay compatible with the Xtype system...
+ */
+ items : false,
+
+ /**
+ * @property _tree
+ * The method that retuns the tree of parts that make up this compoennt
+ * @type {function}
+ */
+ _tree : false,
+
+ /**
+ * render
+ * render element to dom or tree
+ * @param {Roo.Element|String|DomElement} optional render to if parent is not set.
+ */
+
+ render : function(el)
+ {
+
+ el = el || false;
+ var hp = this.parent ? 1 : 0;
+
+ if (!el && typeof(this.parent) == 'string' && this.parent.substring(0,1) == '#') {
+ // if parent is a '#.....' string, then let's use that..
+ var ename = this.parent.substr(1)
+ this.parent = (this.parent == '#bootstrap') ? { el : true} : false; // flags it as a top module...
+ el = Roo.get(ename);
+ if (!el && !this.parent) {
+ Roo.log("Warning - element can not be found :#" + ename );
+ return;
+ }
+ }
+
+
+ if (!this.parent) {
+
+ el = el ? Roo.get(el) : false;
+
+ // it's a top level one..
+ this.parent = {
+ el : new Roo.BorderLayout(el || document.body, {
+
+ center: {
+ titlebar: false,
+ autoScroll:false,
+ closeOnTab: true,
+ tabPosition: 'top',
+ //resizeTabs: true,
+ alwaysShowTabs: el && hp? false : true,
+ hideTabs: el || !hp ? true : false,
+ minTabWidth: 140
+ }
+ })
+ }
+ }
+
+ if (!this.parent.el) {
+ // probably an old style ctor, which has been disabled.
+ return;
+
+ }
+ // The 'tree' method is '_tree now'
+
+ var tree = this._tree ? this._tree() : this.tree();
+ tree.region = tree.region || this.region;
+ if (this.parent.el === true) {
+ // bootstrap... - body..
+ this.parent.el = Roo.factory(tree);
+ }
+ this.el = this.parent.el.addxtype(tree);
+ this.fireEvent('built', this);
+
+ this.panel = this.el;
+ this.layout = this.panel.layout;
+ this.parentLayout = this.parent.layout || false;
+
+ }
+
+});
+
+Roo.apply(Roo.XComponent, {
+ /**
+ * @property hideProgress
+ * true to disable the building progress bar.. usefull on single page renders.
+ * @type Boolean
+ */
+ hideProgress : false,
+ /**
+ * @property buildCompleted
+ * True when the builder has completed building the interface.
+ * @type Boolean
+ */
+ buildCompleted : false,
+
+ /**
+ * @property topModule
+ * the upper most module - uses document.element as it's constructor.
+ * @type Object
+ */
+
+ topModule : false,
+
+ /**
+ * @property modules
+ * array of modules to be created by registration system.
+ * @type {Array} of Roo.XComponent
+ */
+
+ modules : [],
+ /**
+ * @property elmodules
+ * array of modules to be created by which use #ID
+ * @type {Array} of Roo.XComponent
+ */
+
+ elmodules : [],
+
+
+ /**
+ * Register components to be built later.
+ *
+ * This solves the following issues
+ * - Building is not done on page load, but after an authentication process has occured.
+ * - Interface elements are registered on page load
+ * - Parent Interface elements may not be loaded before child, so this handles that..
+ *
+ *
+ * example:
+ *
+ * MyApp.register({
+ order : '000001',
+ module : 'Pman.Tab.projectMgr',
+ region : 'center',
+ parent : 'Pman.layout',
+ disabled : false, // or use a function..
+ })
+
+ * * @param {Object} details about module
+ */
+ register : function(obj) {
+
+ Roo.XComponent.event.fireEvent('register', obj);
+ switch(typeof(obj.disabled) ) {
+
+ case 'undefined':
+ break;
+
+ case 'function':
+ if ( obj.disabled() ) {
+ return;
+ }
+ break;
+
+ default:
+ if (obj.disabled) {
+ return;
+ }
+ break;
+ }
+
+ this.modules.push(obj);
+
+ },
+ /**
+ * convert a string to an object..
+ * eg. 'AAA.BBB' -> finds AAA.BBB
+
+ */
+
+ toObject : function(str)
+ {
+ if (!str || typeof(str) == 'object') {
+ return str;
+ }
+ if (str.substring(0,1) == '#') {
+ return str;
+ }
+
+ var ar = str.split('.');
+ var rt, o;
+ rt = ar.shift();
+ /** eval:var:o */
+ try {
+ eval('if (typeof ' + rt + ' == "undefined"){ o = false;} o = ' + rt + ';');
+ } catch (e) {
+ throw "Module not found : " + str;
+ }
+
+ if (o === false) {
+ throw "Module not found : " + str;
+ }
+ Roo.each(ar, function(e) {
+ if (typeof(o[e]) == 'undefined') {
+ throw "Module not found : " + str;
+ }
+ o = o[e];
+ });
+
+ return o;
+
+ },
+
+
+ /**
+ * move modules into their correct place in the tree..
+ *
+ */
+ preBuild : function ()
+ {
+ var _t = this;
+ Roo.each(this.modules , function (obj)
+ {
+ Roo.XComponent.event.fireEvent('beforebuild', obj);
+
+ var opar = obj.parent;
+ try {
+ obj.parent = this.toObject(opar);
+ } catch(e) {
+ Roo.log("parent:toObject failed: " + e.toString());
+ return;
+ }
+
+ if (!obj.parent) {
+ Roo.debug && Roo.log("GOT top level module");
+ Roo.debug && Roo.log(obj);
+ obj.modules = new Roo.util.MixedCollection(false,
+ function(o) { return o.order + '' }
+ );
+ this.topModule = obj;
+ return;
+ }
+ // parent is a string (usually a dom element name..)
+ if (typeof(obj.parent) == 'string') {
+ this.elmodules.push(obj);
+ return;
+ }
+ if (obj.parent.constructor != Roo.XComponent) {
+ Roo.log("Warning : Object Parent is not instance of XComponent:" + obj.name)
+ }
+ if (!obj.parent.modules) {
+ obj.parent.modules = new Roo.util.MixedCollection(false,
+ function(o) { return o.order + '' }
+ );
+ }
+ if (obj.parent.disabled) {
+ obj.disabled = true;
+ }
+ obj.parent.modules.add(obj);
+ }, this);
+ },
+
+ /**
+ * make a list of modules to build.
+ * @return {Array} list of modules.
+ */
+
+ buildOrder : function()
+ {
+ var _this = this;
+ var cmp = function(a,b) {
+ return String(a).toUpperCase() > String(b).toUpperCase() ? 1 : -1;
+ };
+ if ((!this.topModule || !this.topModule.modules) && !this.elmodules.length) {
+ throw "No top level modules to build";
+ }
+
+ // make a flat list in order of modules to build.
+ var mods = this.topModule ? [ this.topModule ] : [];
+
+
+ // elmodules (is a list of DOM based modules )
+ Roo.each(this.elmodules, function(e) {
+ mods.push(e);
+ if (!this.topModule &&
+ typeof(e.parent) == 'string' &&
+ e.parent.substring(0,1) == '#' &&
+ Roo.get(e.parent.substr(1))
+ ) {
+
+ _this.topModule = e;
+ }
+
+ });
+
+
+ // add modules to their parents..
+ var addMod = function(m) {
+ Roo.debug && Roo.log("build Order: add: " + m.name);
+
+ mods.push(m);
+ if (m.modules && !m.disabled) {
+ Roo.debug && Roo.log("build Order: " + m.modules.length + " child modules");
+ m.modules.keySort('ASC', cmp );
+ Roo.debug && Roo.log("build Order: " + m.modules.length + " child modules (after sort)");
+
+ m.modules.each(addMod);
+ } else {
+ Roo.debug && Roo.log("build Order: no child modules");
+ }
+ // not sure if this is used any more..
+ if (m.finalize) {
+ m.finalize.name = m.name + " (clean up) ";
+ mods.push(m.finalize);
+ }
+
+ }
+ if (this.topModule && this.topModule.modules) {
+ this.topModule.modules.keySort('ASC', cmp );
+ this.topModule.modules.each(addMod);
+ }
+ return mods;
+ },
+
+ /**
+ * Build the registered modules.
+ * @param {Object} parent element.
+ * @param {Function} optional method to call after module has been added.
+ *
+ */
+
+ build : function()
+ {
+
+ this.preBuild();
+ var mods = this.buildOrder();
+
+ //this.allmods = mods;
+ //Roo.debug && Roo.log(mods);
+ //return;
+ if (!mods.length) { // should not happen
+ throw "NO modules!!!";
+ }
+
+
+ var msg = "Building Interface...";
+ // flash it up as modal - so we store the mask!?
+ if (!this.hideProgress && Roo.MessageBox) {
+ Roo.MessageBox.show({ title: 'loading' });
+ Roo.MessageBox.show({
+ title: "Please wait...",
+ msg: msg,
+ width:450,
+ progress:true,
+ closable:false,
+ modal: false
+
+ });
+ }
+ var total = mods.length;
+
+ var _this = this;
+ var progressRun = function() {
+ if (!mods.length) {
+ Roo.debug && Roo.log('hide?');
+ if (!this.hideProgress && Roo.MessageBox) {
+ Roo.MessageBox.hide();
+ }
+ Roo.XComponent.event.fireEvent('buildcomplete', _this.topModule);
+
+ // THE END...
+ return false;
+ }
+
+ var m = mods.shift();
+
+
+ Roo.debug && Roo.log(m);
+ // not sure if this is supported any more.. - modules that are are just function
+ if (typeof(m) == 'function') {
+ m.call(this);
+ return progressRun.defer(10, _this);
+ }
+
+
+ msg = "Building Interface " + (total - mods.length) +
+ " of " + total +
+ (m.name ? (' - ' + m.name) : '');
+ Roo.debug && Roo.log(msg);
+ if (!this.hideProgress && Roo.MessageBox) {
+ Roo.MessageBox.updateProgress( (total - mods.length)/total, msg );
+ }
+
+
+ // is the module disabled?
+ var disabled = (typeof(m.disabled) == 'function') ?
+ m.disabled.call(m.module.disabled) : m.disabled;
+
+
+ if (disabled) {
+ return progressRun(); // we do not update the display!
+ }
+
+ // now build
+
+
+
+ m.render();
+ // it's 10 on top level, and 1 on others??? why...
+ return progressRun.defer(10, _this);
+
+ }
+ progressRun.defer(1, _this);
+
+
+
+ },
+
+
+ /**
+ * Event Object.
+ *
+ *
+ */
+ event: false,
+ /**
+ * wrapper for event.on - aliased later..
+ * Typically use to register a event handler for register:
+ *
+ * eg. Roo.XComponent.on('register', function(comp) { comp.disable = true } );
+ *
+ */
+ on : false
+
+
+
+});
+
+Roo.XComponent.event = new Roo.util.Observable({
+ events : {
+ /**
+ * @event register
+ * Fires when an Component is registered,
+ * set the disable property on the Component to stop registration.
+ * @param {Roo.XComponent} c the component being registerd.
+ *
+ */
+ 'register' : true,
+ /**
+ * @event beforebuild
+ * Fires before each Component is built
+ * can be used to apply permissions.
+ * @param {Roo.XComponent} c the component being registerd.
+ *
+ */
+ 'beforebuild' : true,
+ /**
+ * @event buildcomplete
+ * Fires on the top level element when all elements have been built
+ * @param {Roo.XComponent} the top level component.
+ */
+ 'buildcomplete' : true
+
+ }
+});
+
+Roo.XComponent.on = Roo.XComponent.event.on.createDelegate(Roo.XComponent.event);
+ /*
+ * 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">
+ */
+
+
+
+/*
+ * These classes are derivatives of the similarly named classes in the YUI Library.
+ * The original license:
+ * Copyright (c) 2006, Yahoo! Inc. All rights reserved.
+ * Code licensed under the BSD License:
+ * http://developer.yahoo.net/yui/license.txt
+ */
+
+(function() {
+
+var Event=Roo.EventManager;
+var Dom=Roo.lib.Dom;
+
+/**
+ * @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.
+ * Up to three html elements can be associated with a DragDrop instance:
+ * <ul>
+ * <li>linked element: the element that is passed into the constructor.
+ * This is the element which defines the boundaries for interaction with
+ * other DragDrop objects.</li>
+ * <li>handle element(s): The drag operation only occurs if the element that
+ * was clicked matches a handle element. By default this is the linked
+ * element, but there are times that you will want only a portion of the
+ * linked element to initiate the drag operation, and the setHandleElId()
+ * method provides a way to define this.</li>
+ * <li>drag element: this represents the element that would be moved along
+ * with the cursor during a drag operation. By default, this is the linked
+ * element itself as in {@link Roo.dd.DD}. setDragElId() lets you define
+ * a separate element that would be moved, as in {@link Roo.dd.DDProxy}.
+ * </li>
+ * </ul>
+ * This class should not be instantiated until the onload event to ensure that
+ * the associated elements are available.
+ * The following would define a DragDrop obj that would interact with any
+ * other DragDrop obj in the "group1" group:
+ * <pre>
+ * dd = new Roo.dd.DragDrop("div1", "group1");
+ * </pre>
+ * Since none of the event handlers have been implemented, nothing would
+ * actually happen if you were to run the code above. Normally you would
+ * override this class or one of the default implementations, but you can
+ * also override the methods you want on an instance of the class...
+ * <pre>
+ * dd.onDragDrop = function(e, id) {
+ * alert("dd was dropped on " + id);
+ * }
+ * </pre>
+ * @constructor
+ * @param {String} id of the element that is linked to this instance
+ * @param {String} sGroup the group of related DragDrop objects
+ * @param {object} config an object containing configurable attributes
+ * Valid properties for DragDrop:
+ * padding, isTarget, maintainOffset, primaryButtonOnly
+ */
+Roo.dd.DragDrop = function(id, sGroup, config) {
+ if (id) {
+ this.init(id, sGroup, config);
+ }
+
+};
+
+Roo.extend(Roo.dd.DragDrop, Roo.util.Observable , {
+
+ /**
+ * The id of the element associated with this object. This is what we
+ * refer to as the "linked element" because the size and position of
+ * this element is used to determine when the drag and drop objects have
+ * interacted.
+ * @property id
+ * @type String
+ */
+ id: null,
+
+ /**
+ * Configuration attributes passed into the constructor
+ * @property config
+ * @type object
+ */
+ config: null,
+
+ /**
+ * The id of the element that will be dragged. By default this is same
+ * as the linked element , but could be changed to another element. Ex:
+ * Roo.dd.DDProxy
+ * @property dragElId
+ * @type String
+ * @private
+ */
+ dragElId: null,
+
+ /**
+ * the id of the element that initiates the drag operation. By default
+ * this is the linked element, but could be changed to be a child of this
+ * element. This lets us do things like only starting the drag when the
+ * header element within the linked html element is clicked.
+ * @property handleElId
+ * @type String
+ * @private
+ */
+ handleElId: null,
+
+ /**
+ * An associative array of HTML tags that will be ignored if clicked.
+ * @property invalidHandleTypes
+ * @type {string: string}
+ */
+ invalidHandleTypes: null,
+
+ /**
+ * An associative array of ids for elements that will be ignored if clicked
+ * @property invalidHandleIds
+ * @type {string: string}
+ */
+ invalidHandleIds: null,
+
+ /**
+ * An indexted array of css class names for elements that will be ignored
+ * if clicked.
+ * @property invalidHandleClasses
+ * @type string[]
+ */
+ invalidHandleClasses: null,
+
+ /**
+ * The linked element's absolute X position at the time the drag was
+ * started
+ * @property startPageX
+ * @type int
+ * @private
+ */
+ startPageX: 0,
+
+ /**
+ * The linked element's absolute X position at the time the drag was
+ * started
+ * @property startPageY
+ * @type int
+ * @private
+ */
+ startPageY: 0,
+
+ /**
+ * The group defines a logical collection of DragDrop objects that are
+ * related. Instances only get events when interacting with other
+ * DragDrop object in the same group. This lets us define multiple
+ * groups using a single DragDrop subclass if we want.
+ * @property groups
+ * @type {string: string}
+ */
+ groups: null,
+
+ /**
+ * Individual drag/drop instances can be locked. This will prevent
+ * onmousedown start drag.
+ * @property locked
+ * @type boolean
+ * @private
+ */
+ locked: false,
+
+ /**
+ * Lock this instance
+ * @method lock
+ */
+ lock: function() { this.locked = true; },
+
+ /**
+ * Unlock this instace
+ * @method unlock
+ */
+ unlock: function() { this.locked = false; },
+
+ /**
+ * By default, all insances can be a drop target. This can be disabled by
+ * setting isTarget to false.
+ * @method isTarget
+ * @type boolean
+ */
+ isTarget: true,
+
+ /**
+ * The padding configured for this drag and drop object for calculating
+ * the drop zone intersection with this object.
+ * @method padding
+ * @type int[]
+ */
+ padding: null,
+
+ /**
+ * Cached reference to the linked element
+ * @property _domRef
+ * @private
+ */
+ _domRef: null,
+
+ /**
+ * Internal typeof flag
+ * @property __ygDragDrop
+ * @private
+ */
+ __ygDragDrop: true,
+
+ /**
+ * Set to true when horizontal contraints are applied
+ * @property constrainX
+ * @type boolean
+ * @private
+ */
+ constrainX: false,
+
+ /**
+ * Set to true when vertical contraints are applied
+ * @property constrainY
+ * @type boolean
+ * @private
+ */
+ constrainY: false,
+
+ /**
+ * The left constraint
+ * @property minX
+ * @type int
+ * @private
+ */
+ minX: 0,
+
+ /**
+ * The right constraint
+ * @property maxX
+ * @type int
+ * @private
+ */
+ maxX: 0,
+
+ /**
+ * The up constraint
+ * @property minY
+ * @type int
+ * @type int
+ * @private
+ */
+ minY: 0,
+
+ /**
+ * The down constraint
+ * @property maxY
+ * @type int
+ * @private
+ */
+ maxY: 0,
+
+ /**
+ * Maintain offsets when we resetconstraints. Set to true when you want
+ * the position of the element relative to its parent to stay the same
+ * when the page changes
+ *
+ * @property maintainOffset
+ * @type boolean
+ */
+ maintainOffset: false,
+
+ /**
+ * Array of pixel locations the element will snap to if we specified a
+ * horizontal graduation/interval. This array is generated automatically
+ * when you define a tick interval.
+ * @property xTicks
+ * @type int[]
+ */
+ xTicks: null,
+
+ /**
+ * Array of pixel locations the element will snap to if we specified a
+ * vertical graduation/interval. This array is generated automatically
+ * when you define a tick interval.
+ * @property yTicks
+ * @type int[]
+ */
+ yTicks: null,
+
+ /**
+ * By default the drag and drop instance will only respond to the primary
+ * button click (left button for a right-handed mouse). Set to true to
+ * allow drag and drop to start with any mouse click that is propogated
+ * by the browser
+ * @property primaryButtonOnly
+ * @type boolean
+ */
+ primaryButtonOnly: true,
+
+ /**
+ * The availabe property is false until the linked dom element is accessible.
+ * @property available
+ * @type boolean
+ */
+ available: false,
+
+ /**
+ * By default, drags can only be initiated if the mousedown occurs in the
+ * region the linked element is. This is done in part to work around a
+ * bug in some browsers that mis-report the mousedown if the previous
+ * mouseup happened outside of the window. This property is set to true
+ * if outer handles are defined.
+ *
+ * @property hasOuterHandles
+ * @type boolean
+ * @default false
+ */
+ hasOuterHandles: false,
+
+ /**
+ * Code that executes immediately before the startDrag event
+ * @method b4StartDrag
+ * @private
+ */
+ b4StartDrag: function(x, y) { },
+
+ /**
+ * Abstract method called after a drag/drop object is clicked
+ * and the drag or mousedown time thresholds have beeen met.
+ * @method startDrag
+ * @param {int} X click location
+ * @param {int} Y click location
+ */
+ startDrag: function(x, y) { /* override this */ },
+
+ /**
+ * Code that executes immediately before the onDrag event
+ * @method b4Drag
+ * @private
+ */
+ b4Drag: function(e) { },
+
+ /**
+ * Abstract method called during the onMouseMove event while dragging an
+ * object.
+ * @method onDrag
+ * @param {Event} e the mousemove event
+ */
+ onDrag: function(e) { /* override this */ },
+
+ /**
+ * Abstract method called when this element fist begins hovering over
+ * another DragDrop obj
+ * @method onDragEnter
+ * @param {Event} e the mousemove event
+ * @param {String|DragDrop[]} id In POINT mode, the element
+ * id this is hovering over. In INTERSECT mode, an array of one or more
+ * dragdrop items being hovered over.
+ */
+ onDragEnter: function(e, id) { /* override this */ },
+
+ /**
+ * Code that executes immediately before the onDragOver event
+ * @method b4DragOver
+ * @private
+ */
+ b4DragOver: function(e) { },
+
+ /**
+ * Abstract method called when this element is hovering over another
+ * DragDrop obj
+ * @method onDragOver
+ * @param {Event} e the mousemove event
+ * @param {String|DragDrop[]} id In POINT mode, the element
+ * id this is hovering over. In INTERSECT mode, an array of dd items
+ * being hovered over.
+ */
+ onDragOver: function(e, id) { /* override this */ },
+
+ /**
+ * Code that executes immediately before the onDragOut event
+ * @method b4DragOut
+ * @private
+ */
+ b4DragOut: function(e) { },
+
+ /**
+ * Abstract method called when we are no longer hovering over an element
+ * @method onDragOut
+ * @param {Event} e the mousemove event
+ * @param {String|DragDrop[]} id In POINT mode, the element
+ * id this was hovering over. In INTERSECT mode, an array of dd items
+ * that the mouse is no longer over.
+ */
+ onDragOut: function(e, id) { /* override this */ },
+
+ /**
+ * Code that executes immediately before the onDragDrop event
+ * @method b4DragDrop
+ * @private
+ */
+ b4DragDrop: function(e) { },
+
+ /**
+ * Abstract method called when this item is dropped on another DragDrop
+ * obj
+ * @method onDragDrop
+ * @param {Event} e the mouseup event
+ * @param {String|DragDrop[]} id In POINT mode, the element
+ * id this was dropped on. In INTERSECT mode, an array of dd items this
+ * was dropped on.
+ */
+ onDragDrop: function(e, id) { /* override this */ },
+
+ /**
+ * Abstract method called when this item is dropped on an area with no
+ * drop target
+ * @method onInvalidDrop
+ * @param {Event} e the mouseup event
+ */
+ onInvalidDrop: function(e) { /* override this */ },
+
+ /**
+ * Code that executes immediately before the endDrag event
+ * @method b4EndDrag
+ * @private
+ */
+ b4EndDrag: function(e) { },
+
+ /**
+ * Fired when we are done dragging the object
+ * @method endDrag
+ * @param {Event} e the mouseup event
+ */
+ endDrag: function(e) { /* override this */ },
+
+ /**
+ * Code executed immediately before the onMouseDown event
+ * @method b4MouseDown
+ * @param {Event} e the mousedown event
+ * @private
+ */
+ b4MouseDown: function(e) { },
+
+ /**
+ * Event handler that fires when a drag/drop obj gets a mousedown
+ * @method onMouseDown
+ * @param {Event} e the mousedown event
+ */
+ onMouseDown: function(e) { /* override this */ },
+
+ /**
+ * Event handler that fires when a drag/drop obj gets a mouseup
+ * @method onMouseUp
+ * @param {Event} e the mouseup event
+ */
+ onMouseUp: function(e) { /* override this */ },
+
+ /**
+ * Override the onAvailable method to do what is needed after the initial
+ * position was determined.
+ * @method onAvailable
+ */
+ onAvailable: function () {
+ },
+
+ /*
+ * Provides default constraint padding to "constrainTo" elements (defaults to {left: 0, right:0, top:0, bottom:0}).
+ * @type Object
+ */
+ defaultPadding : {left:0, right:0, top:0, bottom:0},
+
+ /*
+ * Initializes the drag drop object's constraints to restrict movement to a certain element.
+ *
+ * Usage:
+ <pre><code>
+ var dd = new Roo.dd.DDProxy("dragDiv1", "proxytest",
+ { dragElId: "existingProxyDiv" });
+ dd.startDrag = function(){
+ this.constrainTo("parent-id");
+ };
+ </code></pre>
* Or you can initalize it using the {@link Roo.Element} object:
<pre><code>
Roo.get("dragDiv1").initDDProxy("proxytest", {dragElId: "existingProxyDiv"}, {
*/
init: function(id, sGroup, config) {
this.initTarget(id, sGroup, config);
- Event.on(this.id, "mousedown", this.handleMouseDown, this);
+ if (!Roo.isTouch) {
+ Event.on(this.id, "mousedown", this.handleMouseDown, this);
+ }
+ Event.on(this.id, "touchstart", this.handleMouseDown, this);
// Event.on(this.id, "selectstart", Event.preventDefault);
},
unreg: function() {
Event.un(this.id, "mousedown",
this.handleMouseDown);
+ Event.un(this.id, "touchstart",
+ this.handleMouseDown);
this._domRef = null;
this.DDM._remove(this);
},
* @private
*/
handleMouseDown: function(e, oDD){
- if (this.primaryButtonOnly && e.button != 0) {
+
+ if (!Roo.isTouch && this.primaryButtonOnly && e.button != 0) {
+ //Roo.log('not touch/ button !=0');
return;
}
+ if (e.browserEvent.touches && e.browserEvent.touches.length != 1) {
+ return; // double touch..
+ }
+
if (this.isLocked()) {
+ //Roo.log('locked');
return;
}
this.DDM.refreshCache(this.groups);
-
+// Roo.log([Roo.lib.Event.getPageX(e), Roo.lib.Event.getPageY(e)]);
var pt = new Roo.lib.Point(Roo.lib.Event.getPageX(e), Roo.lib.Event.getPageY(e));
if (!this.hasOuterHandles && !this.DDM.isOverTarget(pt, this) ) {
+ //Roo.log('no outer handes or not over target');
+ // do nothing.
} else {
+// Roo.log('check validator');
if (this.clickValidator(e)) {
-
+// Roo.log('validate success');
// set the initial element position
this.setStartPosition();
this.init();
-
- Event.on(document, "mouseup", this.handleMouseUp, this, true);
- Event.on(document, "mousemove", this.handleMouseMove, this, true);
+ if (!Roo.isTouch) {
+ Event.on(document, "mouseup", this.handleMouseUp, this, true);
+ Event.on(document, "mousemove", this.handleMouseMove, this, true);
+ }
+ Event.on(document, "touchend", this.handleMouseUp, this, true);
+ Event.on(document, "touchmove", this.handleMouseMove, this, true);
+
Event.on(window, "unload", this._onUnload, this, true);
Event.on(window, "resize", this._onResize, this, true);
// Event.on(window, "mouseout", this._test);
* Fork - LGPL
* <script type="text/javascript">
*/
-
-
-/**
- * @class Roo.ComponentMgr
- * Provides a common registry of all components on a page so that they can be easily accessed by component id (see {@link Roo.getCmp}).
- * @singleton
- */
-Roo.ComponentMgr = function(){
- var all = new Roo.util.MixedCollection();
-
- return {
- /**
- * Registers a component.
- * @param {Roo.Component} c The component
- */
- register : function(c){
- all.add(c);
- },
-
- /**
- * Unregisters a component.
- * @param {Roo.Component} c The component
- */
- unregister : function(c){
- all.remove(c);
- },
-
- /**
- * Returns a component by id
- * @param {String} id The component id
- */
- get : function(id){
- return all.get(id);
- },
-
- /**
- * Registers a function that will be called when a specified component is added to ComponentMgr
- * @param {String} id The component id
- * @param {Funtction} fn The callback function
- * @param {Object} scope The scope of the callback
- */
- onAvailable : function(id, fn, scope){
- all.on("add", function(index, o){
- if(o.id == id){
- fn.call(scope || o, o);
- all.un("add", fn, scope);
- }
- });
- }
- };
-}();/*
- * 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.Component
- * @extends Roo.util.Observable
- * Base class for all major Roo components. All subclasses of Component can automatically participate in the standard
- * Roo component lifecycle of creation, rendering and destruction. They also have automatic support for basic hide/show
- * and enable/disable behavior. Component allows any subclass to be lazy-rendered into any {@link Roo.Container} and
- * to be automatically registered with the {@link Roo.ComponentMgr} so that it can be referenced at any time via {@link Roo.getCmp}.
- * All visual components (widgets) that require rendering into a layout should subclass Component.
- * @constructor
- * @param {Roo.Element/String/Object} config The configuration options. If an element is passed, it is set as the internal
- * element and its id used as the component id. If a string is passed, it is assumed to be the id of an existing element
- * and is used as the component id. Otherwise, it is assumed to be a standard config object and is applied to the component.
- */
-Roo.Component = function(config){
- config = config || {};
- if(config.tagName || config.dom || typeof config == "string"){ // element object
- config = {el: config, id: config.id || config};
- }
- this.initialConfig = config;
-
- Roo.apply(this, config);
- this.addEvents({
- /**
- * @event disable
- * Fires after the component is disabled.
- * @param {Roo.Component} this
- */
- disable : true,
- /**
- * @event enable
- * Fires after the component is enabled.
- * @param {Roo.Component} this
- */
- enable : true,
- /**
- * @event beforeshow
- * Fires before the component is shown. Return false to stop the show.
- * @param {Roo.Component} this
- */
- beforeshow : true,
- /**
- * @event show
- * Fires after the component is shown.
- * @param {Roo.Component} this
- */
- show : true,
- /**
- * @event beforehide
- * Fires before the component is hidden. Return false to stop the hide.
- * @param {Roo.Component} this
- */
- beforehide : true,
- /**
- * @event hide
- * Fires after the component is hidden.
- * @param {Roo.Component} this
- */
- hide : true,
- /**
- * @event beforerender
- * Fires before the component is rendered. Return false to stop the render.
- * @param {Roo.Component} this
- */
- beforerender : true,
- /**
- * @event render
- * Fires after the component is rendered.
- * @param {Roo.Component} this
- */
- render : true,
- /**
- * @event beforedestroy
- * Fires before the component is destroyed. Return false to stop the destroy.
- * @param {Roo.Component} this
- */
- beforedestroy : true,
- /**
- * @event destroy
- * Fires after the component is destroyed.
- * @param {Roo.Component} this
- */
- destroy : true
- });
- if(!this.id){
- this.id = "ext-comp-" + (++Roo.Component.AUTO_ID);
- }
- Roo.ComponentMgr.register(this);
- Roo.Component.superclass.constructor.call(this);
- this.initComponent();
- if(this.renderTo){ // not supported by all components yet. use at your own risk!
- this.render(this.renderTo);
- delete this.renderTo;
- }
-};
-
-/** @private */
-Roo.Component.AUTO_ID = 1000;
-
-Roo.extend(Roo.Component, Roo.util.Observable, {
- /**
- * @scope Roo.Component.prototype
- * @type {Boolean}
- * true if this component is hidden. Read-only.
- */
- hidden : false,
- /**
- * @type {Boolean}
- * true if this component is disabled. Read-only.
- */
- disabled : false,
- /**
- * @type {Boolean}
- * true if this component has been rendered. Read-only.
- */
- rendered : false,
-
- /** @cfg {String} disableClass
- * CSS class added to the component when it is disabled (defaults to "x-item-disabled").
- */
- disabledClass : "x-item-disabled",
- /** @cfg {Boolean} allowDomMove
- * Whether the component can move the Dom node when rendering (defaults to true).
- */
- allowDomMove : true,
- /** @cfg {String} hideMode
- * How this component should hidden. Supported values are
- * "visibility" (css visibility), "offsets" (negative offset position) and
- * "display" (css display) - defaults to "display".
- */
- hideMode: 'display',
-
- /** @private */
- ctype : "Roo.Component",
-
- /**
- * @cfg {String} actionMode
- * which property holds the element that used for hide() / show() / disable() / enable()
- * default is 'el'
- */
- actionMode : "el",
-
- /** @private */
- getActionEl : function(){
- return this[this.actionMode];
- },
-
- initComponent : Roo.emptyFn,
- /**
- * If this is a lazy rendering component, render it to its container element.
- * @param {String/HTMLElement/Element} container (optional) The element this component should be rendered into. If it is being applied to existing markup, this should be left off.
- */
- render : function(container, position){
- if(!this.rendered && this.fireEvent("beforerender", this) !== false){
- if(!container && this.el){
- this.el = Roo.get(this.el);
- container = this.el.dom.parentNode;
- this.allowDomMove = false;
- }
- this.container = Roo.get(container);
- this.rendered = true;
- if(position !== undefined){
- if(typeof position == 'number'){
- position = this.container.dom.childNodes[position];
- }else{
- position = Roo.getDom(position);
- }
- }
- this.onRender(this.container, position || null);
- if(this.cls){
- this.el.addClass(this.cls);
- delete this.cls;
- }
- if(this.style){
- this.el.applyStyles(this.style);
- delete this.style;
- }
- this.fireEvent("render", this);
- this.afterRender(this.container);
- if(this.hidden){
- this.hide();
- }
- if(this.disabled){
- this.disable();
- }
- }
- return this;
- },
-
- /** @private */
- // default function is not really useful
- onRender : function(ct, position){
- if(this.el){
- this.el = Roo.get(this.el);
- if(this.allowDomMove !== false){
- ct.dom.insertBefore(this.el.dom, position);
- }
- }
- },
-
- /** @private */
- getAutoCreate : function(){
- var cfg = typeof this.autoCreate == "object" ?
- this.autoCreate : Roo.apply({}, this.defaultAutoCreate);
- if(this.id && !cfg.id){
- cfg.id = this.id;
- }
- return cfg;
- },
-
- /** @private */
- afterRender : Roo.emptyFn,
-
- /**
- * Destroys this component by purging any event listeners, removing the component's element from the DOM,
- * removing the component from its {@link Roo.Container} (if applicable) and unregistering it from {@link Roo.ComponentMgr}.
- */
- destroy : function(){
- if(this.fireEvent("beforedestroy", this) !== false){
- this.purgeListeners();
- this.beforeDestroy();
- if(this.rendered){
- this.el.removeAllListeners();
- this.el.remove();
- if(this.actionMode == "container"){
- this.container.remove();
- }
- }
- this.onDestroy();
- Roo.ComponentMgr.unregister(this);
- this.fireEvent("destroy", this);
- }
- },
-
- /** @private */
- beforeDestroy : function(){
-
- },
-
- /** @private */
- onDestroy : function(){
-
- },
-
- /**
- * Returns the underlying {@link Roo.Element}.
- * @return {Roo.Element} The element
- */
- getEl : function(){
- return this.el;
- },
-
- /**
- * Returns the id of this component.
- * @return {String}
- */
- getId : function(){
- return this.id;
- },
-
- /**
- * Try to focus this component.
- * @param {Boolean} selectText True to also select the text in this component (if applicable)
- * @return {Roo.Component} this
- */
- focus : function(selectText){
- if(this.rendered){
- this.el.focus();
- if(selectText === true){
- this.el.dom.select();
- }
- }
- return this;
- },
-
- /** @private */
- blur : function(){
- if(this.rendered){
- this.el.blur();
- }
- return this;
- },
-
- /**
- * Disable this component.
- * @return {Roo.Component} this
- */
- disable : function(){
- if(this.rendered){
- this.onDisable();
- }
- this.disabled = true;
- this.fireEvent("disable", this);
- return this;
- },
-
- // private
- onDisable : function(){
- this.getActionEl().addClass(this.disabledClass);
- this.el.dom.disabled = true;
- },
-
- /**
- * Enable this component.
- * @return {Roo.Component} this
- */
- enable : function(){
- if(this.rendered){
- this.onEnable();
- }
- this.disabled = false;
- this.fireEvent("enable", this);
- return this;
- },
-
- // private
- onEnable : function(){
- this.getActionEl().removeClass(this.disabledClass);
- this.el.dom.disabled = false;
- },
-
- /**
- * Convenience function for setting disabled/enabled by boolean.
- * @param {Boolean} disabled
- */
- setDisabled : function(disabled){
- this[disabled ? "disable" : "enable"]();
- },
-
- /**
- * Show this component.
- * @return {Roo.Component} this
- */
- show: function(){
- if(this.fireEvent("beforeshow", this) !== false){
- this.hidden = false;
- if(this.rendered){
- this.onShow();
- }
- this.fireEvent("show", this);
- }
- return this;
- },
-
- // private
- onShow : function(){
- var ae = this.getActionEl();
- if(this.hideMode == 'visibility'){
- ae.dom.style.visibility = "visible";
- }else if(this.hideMode == 'offsets'){
- ae.removeClass('x-hidden');
- }else{
- ae.dom.style.display = "";
- }
- },
-
- /**
- * Hide this component.
- * @return {Roo.Component} this
- */
- hide: function(){
- if(this.fireEvent("beforehide", this) !== false){
- this.hidden = true;
- if(this.rendered){
- this.onHide();
- }
- this.fireEvent("hide", this);
- }
- return this;
- },
-
- // private
- onHide : function(){
- var ae = this.getActionEl();
- if(this.hideMode == 'visibility'){
- ae.dom.style.visibility = "hidden";
- }else if(this.hideMode == 'offsets'){
- ae.addClass('x-hidden');
- }else{
- ae.dom.style.display = "none";
- }
- },
-
- /**
- * Convenience function to hide or show this component by boolean.
- * @param {Boolean} visible True to show, false to hide
- * @return {Roo.Component} this
- */
- setVisible: function(visible){
- if(visible) {
- this.show();
- }else{
- this.hide();
- }
- return this;
- },
-
- /**
- * Returns true if this component is visible.
- */
- isVisible : function(){
- return this.getActionEl().isVisible();
- },
-
- cloneConfig : function(overrides){
- overrides = overrides || {};
- var id = overrides.id || Roo.id();
- var cfg = Roo.applyIf(overrides, this.initialConfig);
- cfg.id = id; // prevent dup id
- return new this.constructor(cfg);
- }
-});/*
- * 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">
- */
(function(){
/**
* @class Roo.Layer
* <script type="text/javascript">
*/
-/**
- * @class Roo.BoxComponent
- * @extends Roo.Component
- * Base class for any visual {@link Roo.Component} that uses a box container. BoxComponent provides automatic box
- * model adjustments for sizing and positioning and will work correctly withnin the Component rendering model. All
- * container classes should subclass BoxComponent so that they will work consistently when nested within other Ext
- * layout containers.
- * @constructor
- * @param {Roo.Element/String/Object} config The configuration options.
- */
-Roo.BoxComponent = function(config){
- Roo.Component.call(this, config);
- this.addEvents({
- /**
- * @event resize
- * Fires after the component is resized.
- * @param {Roo.Component} this
- * @param {Number} adjWidth The box-adjusted width that was set
- * @param {Number} adjHeight The box-adjusted height that was set
- * @param {Number} rawWidth The width that was originally specified
- * @param {Number} rawHeight The height that was originally specified
- */
- resize : true,
- /**
- * @event move
- * Fires after the component is moved.
- * @param {Roo.Component} this
- * @param {Number} x The new x position
- * @param {Number} y The new y position
- */
- move : true
- });
-};
-
-Roo.extend(Roo.BoxComponent, Roo.Component, {
- // private, set in afterRender to signify that the component has been rendered
- boxReady : false,
- // private, used to defer height settings to subclasses
- deferHeight: false,
- /** @cfg {Number} width
- * width (optional) size of component
- */
- /** @cfg {Number} height
- * height (optional) size of component
- */
-
- /**
- * Sets the width and height of the component. This method fires the resize event. This method can accept
- * either width and height as separate numeric arguments, or you can pass a size object like {width:10, height:20}.
- * @param {Number/Object} width The new width to set, or a size object in the format {width, height}
- * @param {Number} height The new height to set (not required if a size object is passed as the first arg)
- * @return {Roo.BoxComponent} this
- */
- setSize : function(w, h){
- // support for standard size objects
- if(typeof w == 'object'){
- h = w.height;
- w = w.width;
- }
- // not rendered
- if(!this.boxReady){
- this.width = w;
- this.height = h;
- return this;
- }
-
- // prevent recalcs when not needed
- if(this.lastSize && this.lastSize.width == w && this.lastSize.height == h){
- return this;
- }
- this.lastSize = {width: w, height: h};
-
- var adj = this.adjustSize(w, h);
- var aw = adj.width, ah = adj.height;
- if(aw !== undefined || ah !== undefined){ // this code is nasty but performs better with floaters
- var rz = this.getResizeEl();
- if(!this.deferHeight && aw !== undefined && ah !== undefined){
- rz.setSize(aw, ah);
- }else if(!this.deferHeight && ah !== undefined){
- rz.setHeight(ah);
- }else if(aw !== undefined){
- rz.setWidth(aw);
- }
- this.onResize(aw, ah, w, h);
- this.fireEvent('resize', this, aw, ah, w, h);
- }
- return this;
- },
-
- /**
- * Gets the current size of the component's underlying element.
- * @return {Object} An object containing the element's size {width: (element width), height: (element height)}
- */
- getSize : function(){
- return this.el.getSize();
- },
-
- /**
- * Gets the current XY position of the component's underlying element.
- * @param {Boolean} local (optional) If true the element's left and top are returned instead of page XY (defaults to false)
- * @return {Array} The XY position of the element (e.g., [100, 200])
- */
- getPosition : function(local){
- if(local === true){
- return [this.el.getLeft(true), this.el.getTop(true)];
- }
- return this.xy || this.el.getXY();
- },
-
- /**
- * Gets the current box measurements of the component's underlying element.
- * @param {Boolean} local (optional) If true the element's left and top are returned instead of page XY (defaults to false)
- * @returns {Object} box An object in the format {x, y, width, height}
- */
- getBox : function(local){
- var s = this.el.getSize();
- if(local){
- s.x = this.el.getLeft(true);
- s.y = this.el.getTop(true);
- }else{
- var xy = this.xy || this.el.getXY();
- s.x = xy[0];
- s.y = xy[1];
- }
- return s;
- },
-
- /**
- * Sets the current box measurements of the component's underlying element.
- * @param {Object} box An object in the format {x, y, width, height}
- * @returns {Roo.BoxComponent} this
- */
- updateBox : function(box){
- this.setSize(box.width, box.height);
- this.setPagePosition(box.x, box.y);
- return this;
- },
-
- // protected
- getResizeEl : function(){
- return this.resizeEl || this.el;
- },
-
- // protected
- getPositionEl : function(){
- return this.positionEl || this.el;
- },
-
- /**
- * Sets the left and top of the component. To set the page XY position instead, use {@link #setPagePosition}.
- * This method fires the move event.
- * @param {Number} left The new left
- * @param {Number} top The new top
- * @returns {Roo.BoxComponent} this
- */
- setPosition : function(x, y){
- this.x = x;
- this.y = y;
- if(!this.boxReady){
- return this;
- }
- var adj = this.adjustPosition(x, y);
- var ax = adj.x, ay = adj.y;
-
- var el = this.getPositionEl();
- if(ax !== undefined || ay !== undefined){
- if(ax !== undefined && ay !== undefined){
- el.setLeftTop(ax, ay);
- }else if(ax !== undefined){
- el.setLeft(ax);
- }else if(ay !== undefined){
- el.setTop(ay);
- }
- this.onPosition(ax, ay);
- this.fireEvent('move', this, ax, ay);
- }
- return this;
- },
-
- /**
- * Sets the page XY position of the component. To set the left and top instead, use {@link #setPosition}.
- * This method fires the move event.
- * @param {Number} x The new x position
- * @param {Number} y The new y position
- * @returns {Roo.BoxComponent} this
- */
- setPagePosition : function(x, y){
- this.pageX = x;
- this.pageY = y;
- if(!this.boxReady){
- return;
- }
- if(x === undefined || y === undefined){ // cannot translate undefined points
- return;
- }
- var p = this.el.translatePoints(x, y);
- this.setPosition(p.left, p.top);
- return this;
- },
-
- // private
- onRender : function(ct, position){
- Roo.BoxComponent.superclass.onRender.call(this, ct, position);
- if(this.resizeEl){
- this.resizeEl = Roo.get(this.resizeEl);
- }
- if(this.positionEl){
- this.positionEl = Roo.get(this.positionEl);
- }
- },
-
- // private
- afterRender : function(){
- Roo.BoxComponent.superclass.afterRender.call(this);
- this.boxReady = true;
- this.setSize(this.width, this.height);
- if(this.x || this.y){
- this.setPosition(this.x, this.y);
- }
- if(this.pageX || this.pageY){
- this.setPagePosition(this.pageX, this.pageY);
- }
- },
-
- /**
- * Force the component's size to recalculate based on the underlying element's current height and width.
- * @returns {Roo.BoxComponent} this
- */
- syncSize : function(){
- delete this.lastSize;
- this.setSize(this.el.getWidth(), this.el.getHeight());
- return this;
- },
-
- /**
- * Called after the component is resized, this method is empty by default but can be implemented by any
- * subclass that needs to perform custom logic after a resize occurs.
- * @param {Number} adjWidth The box-adjusted width that was set
- * @param {Number} adjHeight The box-adjusted height that was set
- * @param {Number} rawWidth The width that was originally specified
- * @param {Number} rawHeight The height that was originally specified
- */
- onResize : function(adjWidth, adjHeight, rawWidth, rawHeight){
-
- },
-
- /**
- * Called after the component is moved, this method is empty by default but can be implemented by any
- * subclass that needs to perform custom logic after a move occurs.
- * @param {Number} x The new x position
- * @param {Number} y The new y position
- */
- onPosition : function(x, y){
-
- },
-
- // private
- adjustSize : function(w, h){
- if(this.autoWidth){
- w = 'auto';
- }
- if(this.autoHeight){
- h = 'auto';
- }
- return {width : w, height: h};
- },
-
- // private
- adjustPosition : function(x, y){
- return {x : x, y: y};
- }
-});/*
- * 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.SplitBar
this.tpl = depreciated_tpl;
Roo.apply(this, depreciated_config);
}
-
+ this.wrapEl = this.el.wrap().wrap();
+ ///this.el = this.wrapEla.appendChild(document.createElement("div"));
+
if(typeof(this.tpl) == "string"){
this.tpl = new Roo.Template(this.tpl);
this.tpl.compile();
-
+
+
/** @private */
this.addEvents({
* @param {Object} data to be rendered (change this)
*/
"preparedata" : true
+
+
});
+
+
this.el.on({
"click": this.onClick,
"dblclick": this.onDblClick,
this.store = Roo.factory(this.store, Roo.data);
this.setStore(this.store, true);
}
- Roo.View.superclass.constructor.call(this);
+ if ( this.footer && this.footer.xtype) {
+
+ var fctr = this.wrapEl.appendChild(document.createElement("div"));
+
+ this.footer.dataSource = this.store
+ this.footer.container = fctr;
+ this.footer = Roo.factory(this.footer, Roo);
+ fctr.insertFirst(this.el);
+
+ // this is a bit insane - as the paging toolbar seems to detach the el..
+// dom.parentNode.parentNode.parentNode
+ // they get detached?
+ }
+
+
+ Roo.View.superclass.constructor.call(this);
-
};
* @return {Roo.Element}
*/
getEl : function(){
- return this.el;
+ return this.wrapEl;
},
- render : function(a,b, panel)
- {
- if (this.footer && this.footer.xtype) {
-
-
- Roo.log("this.el.parentNode()");
- Roo.log(panel.el.dom );
-
- this.footer.dataSource = this.store
- this.footer.container = panel.el;
- this.footer = Roo.factory(this.footer, Roo);
- }
-
- },
/**
* @param {Roo.EventObject} e The mousedown event
*/
"beforeresize" : true,
+ /**
+ * @event resizing
+ * Fired a resizing.
+ * @param {Roo.Resizable} this
+ * @param {Number} x The new x position
+ * @param {Number} y The new y position
+ * @param {Number} w The new w width
+ * @param {Number} h The new h hight
+ * @param {Roo.EventObject} e The mouseup event
+ */
+ "resizing" : true,
/**
* @event resize
* Fired after a resize.
// private
updateChildSize : function(){
+
if(this.resizeChild){
var el = this.el;
var child = this.resizeChild;
// private
onMouseMove : function(e){
+
if(this.enabled){
try{// try catch so if something goes wrong the user doesn't get hung
}
}catch(e){}
}
+ this.fireEvent("resizing", this, x, y, w, h, e);
},
// private
getResizeChild : function(){
return this.resizeChild;
},
-
+ groupHandler : function()
+ {
+
+ },
/**
* Destroys this resizable. If the element was wrapped and
* removeEl is not true then the element remains.
* Resets the current field value to the originally loaded value and clears any validation messages
*/
reset : function(){
- this.setValue(this.originalValue);
+ this.setValue(this.resetValue);
this.clearInvalid();
},
// reference to original value for reset
this.originalValue = this.getValue();
+ this.resetValue = this.getValue();
},
// private
if(!this.rendered || this.preventMark){ // not rendered
return;
}
- this.el.addClass(this.invalidClass);
+
+ var obj = (typeof(this.combo) != 'undefined') ? this.combo : this; // fix the combox array!!
+
+ obj.el.addClass(this.invalidClass);
msg = msg || this.invalidText;
switch(this.msgTarget){
case 'qtip':
- this.el.dom.qtip = msg;
- this.el.dom.qclass = 'x-form-invalid-tip';
+ obj.el.dom.qtip = msg;
+ obj.el.dom.qclass = 'x-form-invalid-tip';
if(Roo.QuickTips){ // fix for floating editors interacting with DND
Roo.QuickTips.enable();
}
if(!this.rendered || this.preventMark){ // not rendered
return;
}
- this.el.removeClass(this.invalidClass);
+ var obj = (typeof(this.combo) != 'undefined') ? this.combo : this; // fix the combox array!!
+
+ obj.el.removeClass(this.invalidClass);
switch(this.msgTarget){
case 'qtip':
- this.el.dom.qtip = '';
+ obj.el.dom.qtip = '';
break;
case 'title':
this.el.dom.title = '';
if(tag == 'input'){
return w + 2;
}
- if(tag = 'textarea'){
+ if(tag == 'textarea'){
return w-2;
}
}else if(Roo.isOpera){
if(tag == 'input'){
return w + 2;
}
- if(tag = 'textarea'){
+ if(tag == 'textarea'){
return w-2;
}
}
// private
reset : function(){
// overridden so that last data is reset..
- this.setValue(this.originalValue);
+ this.setValue(this.resetValue);
this.clearInvalid();
this.lastData = false;
if (this.view) {
},
+ /**
+ * Validates the combox array value
+ * @return {Boolean} True if the value is valid, else false
+ */
+ validate : function(){
+ if(this.disabled || this.validateValue(this.processValue(this.getValue()))){
+ this.clearInvalid();
+ return true;
+ }
+ return false;
+ },
validateValue : function(value){
return Roo.form.ComboBoxArray.superclass.validateValue.call(this, this.getValue());
this.el.child('img').un('click', this.remove, this);
this.el.remove();
this.cb.updateHiddenEl();
- }
+ },
+ /*@
+ * overide
+ *
+ */
+ isDirty : function() {
+ if(this.disabled) {
+ return false;
+ }
+
+ try {
+ var d = Roo.decode(String(this.originalValue));
+ } catch (e) {
+ return String(this.getValue()) !== String(this.originalValue);
+ }
+
+ var originalValue = [];
+
+ for (var i = 0; i < d.length; i++){
+ originalValue.push(d[i][this.valueField]);
+ }
+
+ return String(this.getValue()) !== String(originalValue.join(','));
+
+ }
});/*
* Based on:
*/
getGroupValue : function(){
return this.el.up('form').child('input[name='+this.el.dom.name+']:checked', true).value;
- }
+ },
+
+
+ onRender : function(ct, position){
+ Roo.form.Checkbox.superclass.onRender.call(this, ct, position);
+
+ if(this.inputValue !== undefined){
+ this.el.dom.value = this.inputValue;
+ }
+
+ this.wrap = this.el.wrap({cls: "x-form-check-wrap"});
+ //this.wrap = this.el.wrap({cls: 'x-menu-check-item '});
+ //var viewEl = this.wrap.createChild({
+ // tag: 'img', cls: 'x-menu-item-icon', style: 'margin: 0px;' ,src : Roo.BLANK_IMAGE_URL });
+ //this.viewEl = viewEl;
+ //this.wrap.on('click', this.onClick, this);
+
+ //this.el.on('DOMAttrModified', this.setFromHidden, this); //ff
+ //this.el.on('propertychange', this.setFromHidden, this); //ie
+
+
+
+ if(this.boxLabel){
+ this.wrap.createChild({tag: 'label', htmlFor: this.el.id, cls: 'x-form-cb-label', html: this.boxLabel});
+ // viewEl.on('click', this.onClick, this);
+ }
+ if(this.checked){
+ this.el.dom.checked = 'checked' ;
+ }
+
+ }
+
+
});//<script type="text/javascript">
/*
insertTag : function(tg)
{
// could be a bit smarter... -> wrap the current selected tRoo..
- if (tg.toLowerCase() == 'span') {
+ if (tg.toLowerCase() == 'span' || tg.toLowerCase() == 'code') {
range = this.createRange(this.getSelection());
- var wrappingNode = this.doc.createElement("span");
+ var wrappingNode = this.doc.createElement(tg.toLowerCase());
wrappingNode.appendChild(range.extractContents());
range.insertNode(wrappingNode);
["abbr"],[ "acronym"],[ "address"],[ "cite"],[ "samp"],[ "var"],
['div'],['span']
],
+
+ cleanStyles : [
+ "font-size"
+ ],
/**
* @cfg {String} defaultFont default font to use.
*/
}
+
+ var cmenu = { };
+ if (!this.disable.cleanStyles) {
+ cmenu = {
+ cls: 'x-btn-icon x-btn-clear',
+
+ menu : {
+ items : []
+ }
+ };
+ for (var i =0; i < this.cleanStyles.length; i++) {
+ cmenu.menu.items.push({
+ actiontype : this.cleanStyles[i],
+ html: 'Remove ' + this.cleanStyles[i],
+ handler: function(a,b) {
+ Roo.log(a);
+ Roo.log(b);
+ var c = Roo.get(editor.doc.body);
+ c.select('[style]').each(function(s) {
+ s.dom.style.removeProperty(a.actiontype);
+ });
+
+ },
+ tabIndex:-1
+ });
+ }
+
+ tb.add(cmenu);
+ }
if (!this.disable.specialElements) {
var semenu = {
title: "Name",
width: 50
},
+ target: {
+ title: "Target",
+ width: 120
+ },
href: {
title: "Href",
width: 220
return;
}
var v = f.getValue();
+ if (f.inputType =='radio') {
+ if (typeof(ret[f.getName()]) == 'undefined') {
+ ret[f.getName()] = ''; // empty..
+ }
+
+ if (!f.el.dom.checked) {
+ return;
+
+ }
+ v = f.el.dom.value;
+
+ }
+
// not sure if this supported any more..
if ((typeof(v) == 'object') && f.getRawValue) {
v = f.getRawValue() ; // dates..
* Fork - LGPL
* <script type="text/javascript">
*/
-
+
+// as we use this in bootstrap.
+Roo.namespace('Roo.form');
/**
* @class Roo.form.Action
* Internal Class used to handle form actions
* @param {Roo.form.BasicForm} el The form element or its id
* @param {Object} config Configuration options
*/
+
// define the action interface
* Server Validation Failed
* @const
*/
- Roo.form.Action.SERVER_INVALID = 'server';
+Roo.form.Action.SERVER_INVALID = 'server';
/**
* Connect to Server Failed
* @const
/**
* @event confirm
* Fires when the 'confirm' icon is pressed (add a listener to enable add button)
- * @param {Roo.form.ComboBox} combo This combo box
+ * @param {Roo.form.Signature} combo This combo box
*/
'confirm' : true,
/**
},
// private
- onRender : function(ct, position){
-
- Roo.form.Signature.superclass.onRender.call(this, ct, position);
+ onRender : function(ct, position){
+
+ Roo.form.Signature.superclass.onRender.call(this, ct, position);
+
+ this.wrap = this.el.wrap({
+ cls:'x-form-signature-wrap', style : 'width: ' + this.width + 'px', cn:{cls:'x-form-signature'}
+ });
+
+ this.createToolbar(this);
+ this.signPanel = this.wrap.createChild({
+ tag: 'div',
+ style: 'width: ' + this.width + 'px; height: ' + this.height + 'px; border: 0;'
+ }, this.el
+ );
+
+ this.svgID = Roo.id();
+ this.svgEl = this.signPanel.createChild({
+ xmlns : 'http://www.w3.org/2000/svg',
+ tag : 'svg',
+ id : this.svgID + "-svg",
+ width: this.width,
+ height: this.height,
+ viewBox: '0 0 '+this.width+' '+this.height,
+ cn : [
+ {
+ tag: "rect",
+ id: this.svgID + "-svg-r",
+ width: this.width,
+ height: this.height,
+ fill: "#ffa"
+ },
+ {
+ tag: "line",
+ id: this.svgID + "-svg-l",
+ x1: "0", // start
+ y1: (this.height*0.8), // start set the line in 80% of height
+ x2: this.width, // end
+ y2: (this.height*0.8), // end set the line in 80% of height
+ 'stroke': "#666",
+ 'stroke-width': "1",
+ 'stroke-dasharray': "3",
+ 'shape-rendering': "crispEdges",
+ 'pointer-events': "none"
+ },
+ {
+ tag: "path",
+ id: this.svgID + "-svg-p",
+ 'stroke': "navy",
+ 'stroke-width': "3",
+ 'fill': "none",
+ 'pointer-events': 'none'
+ }
+ ]
+ });
+ this.createSVG();
+ this.svgBox = this.svgEl.dom.getScreenCTM();
+ },
+ createSVG : function(){
+ var svg = this.signPanel;
+ var r = svg.select('#'+ this.svgID + '-svg-r', true).first().dom;
+ var t = this;
+
+ r.addEventListener('mousedown', function(e) { return t.down(e); }, false);
+ r.addEventListener('mousemove', function(e) { return t.move(e); }, false);
+ r.addEventListener('mouseup', function(e) { return t.up(e); }, false);
+ r.addEventListener('mouseout', function(e) { return t.up(e); }, false);
+ r.addEventListener('touchstart', function(e) { return t.down(e); }, false);
+ r.addEventListener('touchmove', function(e) { return t.move(e); }, false);
+ r.addEventListener('touchend', function(e) { return t.up(e); }, false);
+
+ },
+ isTouchEvent : function(e){
+ return e.type.match(/^touch/);
+ },
+ getCoords : function (e) {
+ var pt = this.svgEl.dom.createSVGPoint();
+ pt.x = e.clientX;
+ pt.y = e.clientY;
+ if (this.isTouchEvent(e)) {
+ pt.x = e.targetTouches[0].clientX
+ pt.y = e.targetTouches[0].clientY;
+ }
+ var a = this.svgEl.dom.getScreenCTM();
+ var b = a.inverse();
+ var mx = pt.matrixTransform(b);
+ return mx.x + ',' + mx.y;
+ },
+ //mouse event headler
+ down : function (e) {
+ this.signatureTmp += 'M' + this.getCoords(e) + ' ';
+ this.signPanel.select('#'+ this.svgID + '-svg-p', true).first().attr('d', this.signatureTmp);
+
+ this.isMouseDown = true;
+
+ e.preventDefault();
+ },
+ move : function (e) {
+ if (this.isMouseDown) {
+ this.signatureTmp += 'L' + this.getCoords(e) + ' ';
+ this.signPanel.select('#'+ this.svgID + '-svg-p', true).first().attr( 'd', this.signatureTmp);
+ }
+
+ e.preventDefault();
+ },
+ up : function (e) {
+ this.isMouseDown = false;
+ var sp = this.signatureTmp.split(' ');
+
+ if(sp.length > 1){
+ if(!sp[sp.length-2].match(/^L/)){
+ sp.pop();
+ sp.pop();
+ sp.push("");
+ this.signatureTmp = sp.join(" ");
+ }
+ }
+ if(this.getValue() != this.signatureTmp){
+ this.signPanel.select('#'+ this.svgID + '-svg-r', true).first().attr('fill', '#ffa');
+ this.isConfirmed = false;
+ }
+ e.preventDefault();
+ },
+
+ /**
+ * 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){
+ 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;
+ this.tb.add(
+ {
+ cls : ' x-signature-btn x-signature-'+id,
+ scope: editor, // was editor...
+ handler: this.reset,
+ clickEvent:'mousedown',
+ text: this.labels.clear
+ },
+ {
+ xtype : 'Fill',
+ xns: Roo.Toolbar
+ },
+ {
+ cls : ' x-signature-btn x-signature-'+id,
+ scope: editor, // was editor...
+ handler: this.confirmHandler,
+ clickEvent:'mousedown',
+ text: this.labels.confirm
+ }
+ );
+
+ },
+ //public
+ /**
+ * when user is clicked confirm then show this image.....
+ *
+ * @return {String} Image Data URI
+ */
+ getImageDataURI : function(){
+ var svg = this.svgEl.dom.parentNode.innerHTML;
+ var src = 'data:image/svg+xml;base64,'+window.btoa(svg);
+ return src;
+ },
+ /**
+ *
+ * @return {Boolean} this.isConfirmed
+ */
+ getConfirmed : function(){
+ return this.isConfirmed;
+ },
+ /**
+ *
+ * @return {Number} this.width
+ */
+ getWidth : function(){
+ return this.width;
+ },
+ /**
+ *
+ * @return {Number} this.height
+ */
+ getHeight : function(){
+ return this.height;
+ },
+ // private
+ getSignature : function(){
+ return this.signatureTmp;
+ },
+ // private
+ reset : function(){
+ this.signatureTmp = '';
+ this.signPanel.select('#'+ this.svgID + '-svg-r', true).first().attr('fill', '#ffa');
+ this.signPanel.select('#'+ this.svgID + '-svg-p', true).first().attr( 'd', '');
+ this.isConfirmed = false;
+ Roo.form.Signature.superclass.reset.call(this);
+ },
+ setSignature : function(s){
+ this.signatureTmp = s;
+ this.signPanel.select('#'+ this.svgID + '-svg-r', true).first().attr('fill', '#ffa');
+ this.signPanel.select('#'+ this.svgID + '-svg-p', true).first().attr( 'd', s);
+ this.setValue(s);
+ this.isConfirmed = false;
+ Roo.form.Signature.superclass.reset.call(this);
+ },
+ test : function(){
+// Roo.log(this.signPanel.dom.contentWindow.up())
+ },
+ //private
+ setConfirmed : function(){
+
+
+
+// Roo.log(Roo.get(this.signPanel.dom.contentWindow.r).attr('fill', '#cfc'));
+ },
+ // private
+ confirmHandler : function(){
+ if(!this.getSignature()){
+ return;
+ }
+
+ this.signPanel.select('#'+ this.svgID + '-svg-r', true).first().attr('fill', '#cfc');
+ this.setValue(this.getSignature());
+ this.isConfirmed = true;
+
+ this.fireEvent('confirm', this);
+ },
+ // private
+ // Subclasses should provide the validation implementation by overriding this
+ validateValue : function(value){
+ if(this.allowBlank){
+ return true;
+ }
+
+ if(this.isConfirmed){
+ return true;
+ }
+ return false;
+ }
+});/*
+ * 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.ComboBox
+ * @extends Roo.form.TriggerField
+ * A combobox control with support for autocomplete, remote-loading, paging and many other features.
+ * @constructor
+ * Create a new ComboBox.
+ * @param {Object} config Configuration options
+ */
+Roo.form.Select = function(config){
+ Roo.form.Select.superclass.constructor.call(this, config);
+
+};
+
+Roo.extend(Roo.form.Select , Roo.form.ComboBox, {
+ /**
+ * @cfg {String/HTMLElement/Element} transform The id, DOM node or element of an existing select to convert to a ComboBox
+ */
+ /**
+ * @cfg {Boolean} lazyRender True to prevent the ComboBox from rendering until requested (should always be used when
+ * rendering into an Roo.Editor, defaults to false)
+ */
+ /**
+ * @cfg {Boolean/Object} autoCreate A DomHelper element spec, or true for a default element spec (defaults to:
+ * {tag: "input", type: "text", size: "24", autocomplete: "off"})
+ */
+ /**
+ * @cfg {Roo.data.Store} store The data store to which this combo is bound (defaults to undefined)
+ */
+ /**
+ * @cfg {String} title If supplied, a header element is created containing this text and added into the top of
+ * the dropdown list (defaults to undefined, with no header element)
+ */
+
+ /**
+ * @cfg {String/Roo.Template} tpl The template to use to render the output
+ */
+
+ // private
+ defaultAutoCreate : {tag: "select" },
+ /**
+ * @cfg {Number} listWidth The width in pixels of the dropdown list (defaults to the width of the ComboBox field)
+ */
+ listWidth: undefined,
+ /**
+ * @cfg {String} displayField The underlying data field name to bind to this CombBox (defaults to undefined if
+ * mode = 'remote' or 'text' if mode = 'local')
+ */
+ displayField: undefined,
+ /**
+ * @cfg {String} valueField The underlying data value name to bind to this CombBox (defaults to undefined if
+ * mode = 'remote' or 'value' if mode = 'local').
+ * Note: use of a valueField requires the user make a selection
+ * in order for a value to be mapped.
+ */
+ valueField: undefined,
+
+
+ /**
+ * @cfg {String} hiddenName If specified, a hidden form field with this name is dynamically generated to store the
+ * field's data value (defaults to the underlying DOM element's name)
+ */
+ hiddenName: undefined,
+ /**
+ * @cfg {String} listClass CSS class to apply to the dropdown list element (defaults to '')
+ */
+ listClass: '',
+ /**
+ * @cfg {String} selectedClass CSS class to apply to the selected item in the dropdown list (defaults to 'x-combo-selected')
+ */
+ selectedClass: 'x-combo-selected',
+ /**
+ * @cfg {String} triggerClass An additional CSS class used to style the trigger button. The trigger will always get the
+ * class 'x-form-trigger' and triggerClass will be <b>appended</b> if specified (defaults to 'x-form-arrow-trigger'
+ * which displays a downward arrow icon).
+ */
+ triggerClass : 'x-form-arrow-trigger',
+ /**
+ * @cfg {Boolean/String} shadow True or "sides" for the default effect, "frame" for 4-way shadow, and "drop" for bottom-right
+ */
+ shadow:'sides',
+ /**
+ * @cfg {String} listAlign A valid anchor position value. See {@link Roo.Element#alignTo} for details on supported
+ * anchor positions (defaults to 'tl-bl')
+ */
+ listAlign: 'tl-bl?',
+ /**
+ * @cfg {Number} maxHeight The maximum height in pixels of the dropdown list before scrollbars are shown (defaults to 300)
+ */
+ maxHeight: 300,
+ /**
+ * @cfg {String} triggerAction The action to execute when the trigger field is activated. Use 'all' to run the
+ * query specified by the allQuery config option (defaults to 'query')
+ */
+ triggerAction: 'query',
+ /**
+ * @cfg {Number} minChars The minimum number of characters the user must type before autocomplete and typeahead activate
+ * (defaults to 4, does not apply if editable = false)
+ */
+ minChars : 4,
+ /**
+ * @cfg {Boolean} typeAhead True to populate and autoselect the remainder of the text being typed after a configurable
+ * delay (typeAheadDelay) if it matches a known value (defaults to false)
+ */
+ typeAhead: false,
+ /**
+ * @cfg {Number} queryDelay The length of time in milliseconds to delay between the start of typing and sending the
+ * query to filter the dropdown list (defaults to 500 if mode = 'remote' or 10 if mode = 'local')
+ */
+ queryDelay: 500,
+ /**
+ * @cfg {Number} pageSize If greater than 0, a paging toolbar is displayed in the footer of the dropdown list and the
+ * filter queries will execute with page start and limit parameters. Only applies when mode = 'remote' (defaults to 0)
+ */
+ pageSize: 0,
+ /**
+ * @cfg {Boolean} selectOnFocus True to select any existing text in the field immediately on focus. Only applies
+ * when editable = true (defaults to false)
+ */
+ selectOnFocus:false,
+ /**
+ * @cfg {String} queryParam Name of the query as it will be passed on the querystring (defaults to 'query')
+ */
+ queryParam: 'query',
+ /**
+ * @cfg {String} loadingText The text to display in the dropdown list while data is loading. Only applies
+ * when mode = 'remote' (defaults to 'Loading...')
+ */
+ loadingText: 'Loading...',
+ /**
+ * @cfg {Boolean} resizable True to add a resize handle to the bottom of the dropdown list (defaults to false)
+ */
+ resizable: false,
+ /**
+ * @cfg {Number} handleHeight The height in pixels of the dropdown list resize handle if resizable = true (defaults to 8)
+ */
+ handleHeight : 8,
+ /**
+ * @cfg {Boolean} editable False to prevent the user from typing text directly into the field, just like a
+ * traditional select (defaults to true)
+ */
+ editable: true,
+ /**
+ * @cfg {String} allQuery The text query to send to the server to return all records for the list with no filtering (defaults to '')
+ */
+ allQuery: '',
+ /**
+ * @cfg {String} mode Set to 'local' if the ComboBox loads local data (defaults to 'remote' which loads from the server)
+ */
+ mode: 'remote',
+ /**
+ * @cfg {Number} minListWidth The minimum width of the dropdown list in pixels (defaults to 70, will be ignored if
+ * listWidth has a higher value)
+ */
+ minListWidth : 70,
+ /**
+ * @cfg {Boolean} forceSelection True to restrict the selected value to one of the values in the list, false to
+ * allow the user to set arbitrary text into the field (defaults to false)
+ */
+ forceSelection:false,
+ /**
+ * @cfg {Number} typeAheadDelay The length of time in milliseconds to wait until the typeahead text is displayed
+ * if typeAhead = true (defaults to 250)
+ */
+ typeAheadDelay : 250,
+ /**
+ * @cfg {String} valueNotFoundText When using a name/value combo, if the value passed to setValue is not found in
+ * the store, valueNotFoundText will be displayed as the field text if defined (defaults to undefined)
+ */
+ valueNotFoundText : undefined,
+
+ /**
+ * @cfg {String} defaultValue The value displayed after loading the store.
+ */
+ defaultValue: '',
+
+ /**
+ * @cfg {Boolean} blockFocus Prevents all focus calls, so it can work with things like HTML edtor bar
+ */
+ blockFocus : false,
+
+ /**
+ * @cfg {Boolean} disableClear Disable showing of clear button.
+ */
+ disableClear : false,
+ /**
+ * @cfg {Boolean} alwaysQuery Disable caching of results, and always send query
+ */
+ alwaysQuery : false,
+
+ //private
+ addicon : false,
+ editicon: false,
+
+ // element that contains real text value.. (when hidden is used..)
+
+ // private
+ onRender : function(ct, position){
+ Roo.form.Field.prototype.onRender.call(this, ct, position);
+
+ if(this.store){
+ this.store.on('beforeload', this.onBeforeLoad, this);
+ this.store.on('load', this.onLoad, this);
+ this.store.on('loadexception', this.onLoadException, this);
+ this.store.load({});
+ }
+
+
+
+ },
+
+ // private
+ initEvents : function(){
+ //Roo.form.ComboBox.superclass.initEvents.call(this);
+
+ },
+
+ onDestroy : function(){
+
+ if(this.store){
+ this.store.un('beforeload', this.onBeforeLoad, this);
+ this.store.un('load', this.onLoad, this);
+ this.store.un('loadexception', this.onLoadException, this);
+ }
+ //Roo.form.ComboBox.superclass.onDestroy.call(this);
+ },
+
+ // private
+ fireKey : function(e){
+ if(e.isNavKeyPress() && !this.list.isVisible()){
+ this.fireEvent("specialkey", this, e);
+ }
+ },
+
+ // private
+ onResize: function(w, h){
- this.wrap = this.el.wrap({
- cls:'x-form-signature-wrap', style : 'width: ' + this.width + 'px', cn:{cls:'x-form-signature'}
- });
+ return;
+
- this.createToolbar(this);
- this.signPanel = this.wrap.createChild({
- tag: 'div',
- style: 'width: ' + this.width + 'px; height: ' + this.height + 'px; border: 0;'
- }, this.el
- );
-
- this.svgID = Roo.id();
- this.svgEl = this.signPanel.createChild({
- xmlns : 'http://www.w3.org/2000/svg',
- tag : 'svg',
- width: this.width,
- height: this.height,
- viewBox: '0 0 '+this.width+' '+this.height,
- cn : [
- {
- tag: "rect",
- id: this.svgID + "-svg-r",
- width: this.width,
- height: this.height,
- fill: "#ffa"
- },
- {
- tag: "line",
- x1: "0", // start
- y1: (this.height*0.8), // start set the line in 80% of height
- x2: this.width, // end
- y2: (this.height*0.8), // end set the line in 80% of height
- 'stroke': "#666",
- 'stroke-width': "1",
- 'stroke-dasharray': "3",
- 'shape-rendering': "crispEdges",
- 'pointer-events': "none"
- },
- {
- tag: "path",
- id: this.svgID + "-svg-p",
- 'stroke': "navy",
- 'stroke-width': "3",
- 'fill': "none",
- 'pointer-events': 'none'
- }
- ]
- });
- this.createSVG();
- this.svgBox = this.svgEl.dom.getScreenCTM();
},
- createSVG : function(){
- var svg = this.signPanel;
- var r = svg.select('#'+ this.svgID + '-svg-r', true).first().dom;
- var t = this;
- r.addEventListener('mousedown', function(e) { return t.down(e); }, false);
- r.addEventListener('mousemove', function(e) { return t.move(e); }, false);
- r.addEventListener('mouseup', function(e) { return t.up(e); }, false);
- r.addEventListener('mouseout', function(e) { return t.up(e); }, false);
- r.addEventListener('touchstart', function(e) { return t.down(e); }, false);
- r.addEventListener('touchmove', function(e) { return t.move(e); }, false);
- r.addEventListener('touchend', function(e) { return t.up(e); }, false);
-
+ /**
+ * Allow or prevent the user from directly editing the field text. If false is passed,
+ * the user will only be able to select from the items defined in the dropdown list. This method
+ * is the runtime equivalent of setting the 'editable' config option at config time.
+ * @param {Boolean} value True to allow the user to directly edit the field text
+ */
+ setEditable : function(value){
+
},
- isTouchEvent : function(e){
- return e.type.match(/^touch/);
+
+ // private
+ onBeforeLoad : function(){
+
+ Roo.log("Select before load");
+ return;
+
+ this.innerList.update(this.loadingText ?
+ '<div class="loading-indicator">'+this.loadingText+'</div>' : '');
+ //this.restrictHeight();
+ this.selectedIndex = -1;
},
- getCoords : function (e) {
- var pt = this.svgEl.dom.createSVGPoint();
- pt.x = e.clientX;
- pt.y = e.clientY;
- if (this.isTouchEvent(e)) {
- pt.x = e.targetTouches[0].clientX
- pt.y = e.targetTouches[0].clientY;
+
+ // private
+ onLoad : function(){
+
+
+ var dom = this.el.dom;
+ dom.innerHTML = '';
+ var od = dom.ownerDocument;
+
+ if (this.emptyText) {
+ var op = od.createElement('option');
+ op.setAttribute('value', '');
+ op.innerHTML = String.format('{0}', this.emptyText);
+ dom.appendChild(op);
}
- var a = this.svgEl.dom.getScreenCTM();
- var b = a.inverse();
- var mx = pt.matrixTransform(b);
- return mx.x + ',' + mx.y;
+ if(this.store.getCount() > 0){
+
+ var vf = this.valueField;
+ var df = this.displayField;
+ this.store.data.each(function(r) {
+ // which colmsn to use... testing - cdoe / title..
+ var op = od.createElement('option');
+ op.setAttribute('value', r.data[vf]);
+ op.innerHTML = String.format('{0}', r.data[df]);
+ dom.appendChild(op);
+ });
+ if (typeof(this.defaultValue != 'undefined')) {
+ this.setValue(this.defaultValue);
+ }
+
+
+ }else{
+ //this.onEmptyResults();
+ }
+ //this.el.focus();
},
- //mouse event headler
- down : function (e) {
- this.signatureTmp += 'M' + this.getCoords(e) + ' ';
- this.signPanel.select('#'+ this.svgID + '-svg-p', true).first().attr('d', this.signatureTmp);
+ // private
+ onLoadException : function()
+ {
+ dom.innerHTML = '';
+
+ Roo.log("Select on load exception");
+ return;
+
+ this.collapse();
+ Roo.log(this.store.reader.jsonData);
+ if (this.store && typeof(this.store.reader.jsonData.errorMsg) != 'undefined') {
+ Roo.MessageBox.alert("Error loading",this.store.reader.jsonData.errorMsg);
+ }
- this.isMouseDown = true;
- e.preventDefault();
},
- move : function (e) {
- if (this.isMouseDown) {
- this.signatureTmp += 'L' + this.getCoords(e) + ' ';
- this.signPanel.select('#'+ this.svgID + '-svg-p', true).first().attr( 'd', this.signatureTmp);
+ // private
+ onTypeAhead : function(){
+
+ },
+
+ // private
+ onSelect : function(record, index){
+ Roo.log('on select?');
+ return;
+ if(this.fireEvent('beforeselect', this, record, index) !== false){
+ this.setFromData(index > -1 ? record.data : false);
+ this.collapse();
+ this.fireEvent('select', this, record, index);
}
+ },
+
+ /**
+ * Returns the currently selected field value or empty string if no value is set.
+ * @return {String} value The selected value
+ */
+ getValue : function(){
+ var dom = this.el.dom;
+ this.value = dom.options[dom.selectedIndex].value;
+ return this.value;
- e.preventDefault();
},
- up : function (e) {
- this.isMouseDown = false;
- var sp = this.signatureTmp.split(' ');
+
+ /**
+ * Clears any text/value currently set in the field
+ */
+ clearValue : function(){
+ this.value = '';
+ this.el.dom.selectedIndex = this.emptyText ? 0 : -1;
- if(sp.length > 1){
- if(!sp[sp.length-2].match(/^L/)){
- sp.pop();
- sp.pop();
- sp.push("");
- this.signatureTmp = sp.join(" ");
+ },
+
+ /**
+ * Sets the specified value into the field. If the value finds a match, the corresponding record text
+ * will be displayed in the field. If the value does not match the data value of an existing item,
+ * and the valueNotFoundText config option is defined, it will be displayed as the default field text.
+ * Otherwise the field will be blank (although the value will still be set).
+ * @param {String} value The value to match
+ */
+ setValue : function(v){
+ var d = this.el.dom;
+ for (var i =0; i < d.options.length;i++) {
+ if (v == d.options[i].value) {
+ d.selectedIndex = i;
+ this.value = v;
+ return;
}
}
- if(this.getValue() != this.signatureTmp){
- this.signPanel.select('#'+ this.svgID + '-svg-r', true).first().attr('fill', '#ffa');
- this.isConfirmed = false;
- }
- e.preventDefault();
+ this.clearValue();
},
+ /**
+ * @property {Object} the last set data for the element
+ */
+ lastData : false,
/**
- * 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
+ * Sets the value of the field based on a object which is related to the record format for the store.
+ * @param {Object} value the value to set as. or false on reset?
*/
- createToolbar : function(editor){
- 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
- };
- }
+ setFromData : function(o){
+ Roo.log('setfrom data?');
+
- var tb = new Roo.Toolbar(editor.wrap.dom.firstChild);
- this.tb = tb;
- this.tb.add(
- {
- cls : ' x-signature-btn x-signature-'+id,
- scope: editor, // was editor...
- handler: this.reset,
- clickEvent:'mousedown',
- text: this.labels.clear
- },
- {
- xtype : 'Fill',
- xns: Roo.Toolbar
- },
- {
- cls : ' x-signature-btn x-signature-'+id,
- scope: editor, // was editor...
- handler: this.setConfirmed,
- clickEvent:'mousedown',
- text: this.labels.confirm
- }
- );
+ },
+ // private
+ reset : function(){
+ this.clearValue();
+ },
+ // private
+ findRecord : function(prop, value){
+
+ return false;
+ var record;
+ if(this.store.getCount() > 0){
+ this.store.each(function(r){
+ if(r.data[prop] == value){
+ record = r;
+ return false;
+ }
+ return true;
+ });
+ }
+ return record;
},
- //public
- /**
- *
- * @return {String} Image Data URI
- */
- getImageDataURI : function(){
- var svg = this.svgEl.dom.outerHTML;
- var src = 'data:image/svg+xml;base64,'+window.btoa(svg);
- return src;
+
+ getName: function()
+ {
+ // returns hidden if it's set..
+ if (!this.rendered) {return ''};
+ return !this.hiddenName && this.el.dom.name ? this.el.dom.name : (this.hiddenName || '');
+
+ },
+
+
+
+
+ // private
+ onEmptyResults : function(){
+ Roo.log('empty results');
+ //this.collapse();
},
+
/**
- *
- * @return {Boolean} this.isConfirmed
+ * Returns true if the dropdown list is expanded, else false.
*/
- getConfirmed : function(){
- return this.isConfirmed;
+ isExpanded : function(){
+ return false;
},
+
/**
- *
- * @return {Number} this.width
+ * Select an item in the dropdown list by its data value. This function does NOT cause the select event to fire.
+ * The store must be loaded and the list expanded for this function to work, otherwise use setValue.
+ * @param {String} value The data value of the item to select
+ * @param {Boolean} scrollIntoView False to prevent the dropdown list from autoscrolling to display the
+ * selected item if it is not currently in view (defaults to true)
+ * @return {Boolean} True if the value matched an item in the list, else false
*/
- getWidth : function(){
- return this.width;
+ selectByValue : function(v, scrollIntoView){
+ Roo.log('select By Value');
+ return false;
+
+ if(v !== undefined && v !== null){
+ var r = this.findRecord(this.valueField || this.displayField, v);
+ if(r){
+ this.select(this.store.indexOf(r), scrollIntoView);
+ return true;
+ }
+ }
+ return false;
},
+
/**
- *
- * @return {Number} this.height
+ * Select an item in the dropdown list by its numeric index in the list. This function does NOT cause the select event to fire.
+ * The store must be loaded and the list expanded for this function to work, otherwise use setValue.
+ * @param {Number} index The zero-based index of the list item to select
+ * @param {Boolean} scrollIntoView False to prevent the dropdown list from autoscrolling to display the
+ * selected item if it is not currently in view (defaults to true)
*/
- getHeight : function(){
- return this.height;
+ select : function(index, scrollIntoView){
+ Roo.log('select ');
+ return ;
+
+ this.selectedIndex = index;
+ this.view.select(index);
+ if(scrollIntoView !== false){
+ var el = this.view.getNode(index);
+ if(el){
+ this.innerList.scrollChildIntoView(el, false);
+ }
+ }
},
+
+
+
// private
- getSignature : function(){
- return this.signatureTmp;
+ validateBlur : function(){
+
+ return;
+
},
+
// private
- reset : function(){
- this.signatureTmp = '';
- this.signPanel.select('#'+ this.svgID + '-svg-r', true).first().attr('fill', '#ffa');
- this.signPanel.select('#'+ this.svgID + '-svg-p', true).first().attr( 'd', '');
- this.isConfirmed = false;
- Roo.form.Signature.superclass.reset.call(this);
+ initQuery : function(){
+ this.doQuery(this.getRawValue());
},
- test : function(){
-// Roo.log(this.signPanel.dom.contentWindow.up())
+
+ // private
+ doForce : function(){
+ if(this.el.dom.value.length > 0){
+ this.el.dom.value =
+ this.lastSelectionText === undefined ? '' : this.lastSelectionText;
+
+ }
},
- //private
- setConfirmed : function(){
- if(!this.getSignature()){
- return;
+
+ /**
+ * Execute a query to filter the dropdown list. Fires the beforequery event prior to performing the
+ * query allowing the query action to be canceled if needed.
+ * @param {String} query The SQL query to execute
+ * @param {Boolean} forceAll True to force the query to execute even if there are currently fewer characters
+ * in the field than the minimum specified by the minChars config option. It also clears any filter previously
+ * saved in the current store (defaults to false)
+ */
+ doQuery : function(q, forceAll){
+
+ Roo.log('doQuery?');
+ if(q === undefined || q === null){
+ q = '';
+ }
+ var qe = {
+ query: q,
+ forceAll: forceAll,
+ combo: this,
+ cancel:false
+ };
+ if(this.fireEvent('beforequery', qe)===false || qe.cancel){
+ return false;
+ }
+ q = qe.query;
+ forceAll = qe.forceAll;
+ if(forceAll === true || (q.length >= this.minChars)){
+ if(this.lastQuery != q || this.alwaysQuery){
+ this.lastQuery = q;
+ if(this.mode == 'local'){
+ this.selectedIndex = -1;
+ if(forceAll){
+ this.store.clearFilter();
+ }else{
+ this.store.filter(this.displayField, q);
+ }
+ this.onLoad();
+ }else{
+ this.store.baseParams[this.queryParam] = q;
+ this.store.load({
+ params: this.getParams(q)
+ });
+ this.expand();
+ }
+ }else{
+ this.selectedIndex = -1;
+ this.onLoad();
+ }
}
- this.signPanel.select('#'+ this.svgID + '-svg-r', true).first().attr('fill', '#cfc');
- this.setValue(this.getSignature());
- this.isConfirmed = true;
-// Roo.log(Roo.get(this.signPanel.dom.contentWindow.r).attr('fill', '#cfc'));
},
+
// private
- // Subclasses should provide the validation implementation by overriding this
- validateValue : function(value){
- if(this.allowBlank){
- return true;
+ getParams : function(q){
+ var p = {};
+ //p[this.queryParam] = q;
+ if(this.pageSize){
+ p.start = 0;
+ p.limit = this.pageSize;
}
+ return p;
+ },
+
+ /**
+ * Hides the dropdown list if it is currently expanded. Fires the 'collapse' event on completion.
+ */
+ collapse : function(){
- if(this.isConfirmed){
- return true;
- }
- return false;
+ },
+
+ // private
+ collapseIf : function(e){
+
+ },
+
+ /**
+ * Expands the dropdown list if it is currently hidden. Fires the 'expand' event on completion.
+ */
+ expand : function(){
+
+ } ,
+
+ // private
+
+
+ /**
+ * @cfg {Boolean} grow
+ * @hide
+ */
+ /**
+ * @cfg {Number} growMin
+ * @hide
+ */
+ /**
+ * @cfg {Number} growMax
+ * @hide
+ */
+ /**
+ * @hide
+ * @method autoSize
+ */
+
+ setWidth : function()
+ {
+
+ },
+ getResizeEl : function(){
+ return this.el;
}
});//<script type="text/javasscript">
});
- if (this.view && typeof(this.view.xtype) != 'undefined') {
- this.view.el = this.el.appendChild(document.createElement("div"));
- this.view = Roo.factory(this.view);
- this.view.render && this.on('render',
- function() {
- this.view.render(false, '',this);
- }, this); // render blank..
- }
-
+
if(this.autoScroll){
Roo.ContentPanel.superclass.constructor.call(this);
+ if (this.view && typeof(this.view.xtype) != 'undefined') {
+ this.view.el = this.el.appendChild(document.createElement("div"));
+ this.view = Roo.factory(this.view);
+ this.view.render && this.view.render(false, '');
+ }
+
+
this.fireEvent('render', this);
};
return this.form;
}
// should only have one of theses..
- if ([/*'View',*/ 'JsonView', 'DatePicker'].indexOf(cfg.xtype) > -1) {
- // views..
+ if ([ 'View', 'JsonView', 'DatePicker'].indexOf(cfg.xtype) > -1) {
+ // views.. should not be just added - used named prop 'view''
+
cfg.el = this.el.appendChild(document.createElement("div"));
// factory?
var ret = new Roo.factory(cfg);
- ret.render && ret.render(false, ''); // render blank..
+
+ ret.render && ret.render(false, ''); // render blank..
this.view = ret;
return ret;
}
c.on("dblclick", this.onDblClick, this);
c.on("contextmenu", this.onContextMenu, this);
c.on("keydown", this.onKeyDown, this);
+ if (Roo.isTouch) {
+ c.on("touchstart", this.onTouchStart, this);
+ }
this.relayEvents(c, ["mousedown","mouseup","mouseover","mouseout","keypress"]);
// private
processEvent : function(name, e){
- this.fireEvent(name, e);
+ // does this fire select???
+ Roo.log('grid:processEvent ' + name);
+
+ if (name != 'touchstart' ) {
+ this.fireEvent(name, e);
+ }
+
var t = e.getTarget();
var v = this.view;
var header = v.findHeaderIndex(t);
if(header !== false){
- this.fireEvent("header" + name, this, header, e);
+ this.fireEvent("header" + (name == 'touchstart' ? 'click' : name), this, header, e);
}else{
var row = v.findRowIndex(t);
var cell = v.findCellIndex(t);
+ if (name == 'touchstart') {
+ // first touch is always a click.
+ // hopefull this happens after selection is updated.?
+ name = false;
+
+ if (typeof(this.selModel.getSelectedCell) != 'undefined') {
+ var cs = this.selModel.getSelectedCell();
+ if (row == cs[0] && cell == cs[1]){
+ name = 'dblclick';
+ }
+ }
+ if (typeof(this.selModel.getSelections) != 'undefined') {
+ var cs = this.selModel.getSelections();
+ var ds = this.dataSource;
+ if (cs.length == 1 && ds.getAt(row) == cs[0]){
+ name = 'dblclick';
+ }
+ }
+ if (!name) {
+ return;
+ }
+ }
+
+
if(row !== false){
this.fireEvent("row" + name, this, row, e);
if(cell !== false){
onClick : function(e){
this.processEvent("click", e);
},
+ // private
+ onTouchStart : function(e){
+ this.processEvent("touchstart", e);
+ },
// private
onContextMenu : function(e, t){
Roo.extend(Roo.XTemplate, Roo.Template, {
/**
- * The various sub templates
- */
- tpls : false,
- /**
- *
- * basic tag replacing syntax
- * WORD:WORD()
- *
- * // you can fake an object call by doing this
- * x.t:(test,tesT)
- *
- */
- re : /\{([\w-\.]+)(?:\:([\w\.]*)(?:\((.*?)?\))?)?\}/g,
-
- /**
- * compile the template
- *
- * This is not recursive, so I'm not sure how nested templates are really going to be handled..
- *
- */
- compile: function()
- {
- var s = this.html;
-
- s = ['<tpl>', s, '</tpl>'].join('');
-
- var re = /<tpl\b[^>]*>((?:(?=([^<]+))\2|<(?!tpl\b[^>]*>))*?)<\/tpl>/,
- nameRe = /^<tpl\b[^>]*?for="(.*?)"/,
- ifRe = /^<tpl\b[^>]*?if="(.*?)"/,
- execRe = /^<tpl\b[^>]*?exec="(.*?)"/,
- namedRe = /^<tpl\b[^>]*?name="(\w+)"/, // named templates..
- m,
- id = 0,
- tpls = [];
-
- while(true == !!(m = s.match(re))){
- var forMatch = m[0].match(nameRe),
- ifMatch = m[0].match(ifRe),
- execMatch = m[0].match(execRe),
- namedMatch = m[0].match(namedRe),
-
- exp = null,
- fn = null,
- exec = null,
- name = forMatch && forMatch[1] ? forMatch[1] : '';
-
- if (ifMatch) {
- // if - puts fn into test..
- exp = ifMatch && ifMatch[1] ? ifMatch[1] : null;
- if(exp){
- fn = new Function('values', 'parent', 'with(values){ return '+(Roo.util.Format.htmlDecode(exp))+'; }');
- }
- }
-
- if (execMatch) {
- // exec - calls a function... returns empty if true is returned.
- exp = execMatch && execMatch[1] ? execMatch[1] : null;
- if(exp){
- exec = new Function('values', 'parent', 'with(values){ '+(Roo.util.Format.htmlDecode(exp))+'; }');
- }
- }
-
-
- if (name) {
- // for =
- switch(name){
- case '.': name = new Function('values', 'parent', 'with(values){ return values; }'); break;
- case '..': name = new Function('values', 'parent', 'with(values){ return parent; }'); break;
- default: name = new Function('values', 'parent', 'with(values){ return '+name+'; }');
- }
- }
- var uid = namedMatch ? namedMatch[1] : id;
-
-
- tpls.push({
- id: namedMatch ? namedMatch[1] : id,
- target: name,
- exec: exec,
- test: fn,
- body: m[1] || ''
- });
- if (namedMatch) {
- s = s.replace(m[0], '');
- } else {
- s = s.replace(m[0], '{xtpl'+ id + '}');
- }
- ++id;
- }
- this.tpls = [];
- for(var i = tpls.length-1; i >= 0; --i){
- this.compileTpl(tpls[i]);
- this.tpls[tpls[i].id] = tpls[i];
- }
- this.master = tpls[tpls.length-1];
- return this;
- },
- /**
- * same as applyTemplate, except it's done to one of the subTemplates
- * when using named templates, you can do:
- *
- * var str = pl.applySubTemplate('your-name', values);
- *
- *
- * @param {Number} id of the template
- * @param {Object} values to apply to template
- * @param {Object} parent (normaly the instance of this object)
- */
- applySubTemplate : function(id, values, parent)
- {
-
-
- var t = this.tpls[id];
-
-
- try {
- if(t.test && !t.test.call(this, values, parent)){
- return '';
- }
- } catch(e) {
- Roo.log("Xtemplate.applySubTemplate 'test': Exception thrown");
- Roo.log(e.toString());
- Roo.log(t.test);
- return ''
- }
- try {
-
- if(t.exec && t.exec.call(this, values, parent)){
- return '';
- }
- } catch(e) {
- Roo.log("Xtemplate.applySubTemplate 'exec': Exception thrown");
- Roo.log(e.toString());
- Roo.log(t.exec);
- return ''
- }
- try {
- var vs = t.target ? t.target.call(this, values, parent) : values;
- parent = t.target ? values : parent;
- if(t.target && vs instanceof Array){
- var buf = [];
- for(var i = 0, len = vs.length; i < len; i++){
- buf[buf.length] = t.compiled.call(this, vs[i], parent);
- }
- return buf.join('');
- }
- return t.compiled.call(this, vs, parent);
- } catch (e) {
- Roo.log("Xtemplate.applySubTemplate : Exception thrown");
- Roo.log(e.toString());
- Roo.log(t.compiled);
- return '';
- }
- },
-
- compileTpl : function(tpl)
- {
- var fm = Roo.util.Format;
- var useF = this.disableFormats !== true;
- var sep = Roo.isGecko ? "+" : ",";
- var undef = function(str) {
- Roo.log("Property not found :" + str);
- return '';
- };
-
- var fn = function(m, name, format, args)
- {
- //Roo.log(arguments);
- args = args ? args.replace(/\\'/g,"'") : args;
- //["{TEST:(a,b,c)}", "TEST", "", "a,b,c", 0, "{TEST:(a,b,c)}"]
- if (typeof(format) == 'undefined') {
- format= 'htmlEncode';
- }
- if (format == 'raw' ) {
- format = false;
- }
-
- if(name.substr(0, 4) == 'xtpl'){
- return "'"+ sep +'this.applySubTemplate('+name.substr(4)+', values, parent)'+sep+"'";
- }
-
- // build an array of options to determine if value is undefined..
-
- // basically get 'xxxx.yyyy' then do
- // (typeof(xxxx) == 'undefined' || typeof(xxx.yyyy) == 'undefined') ?
- // (function () { Roo.log("Property not found"); return ''; })() :
- // ......
-
- var udef_ar = [];
- var lookfor = '';
- Roo.each(name.split('.'), function(st) {
- lookfor += (lookfor.length ? '.': '') + st;
- udef_ar.push( "(typeof(" + lookfor + ") == 'undefined')" );
- });
-
- var udef_st = '((' + udef_ar.join(" || ") +") ? undef('" + name + "') : "; // .. needs )
-
-
- if(format && useF){
-
- args = args ? ',' + args : "";
-
- if(format.substr(0, 5) != "this."){
- format = "fm." + format + '(';
- }else{
- format = 'this.call("'+ format.substr(5) + '", ';
- args = ", values";
- }
-
- return "'"+ sep + udef_st + format + name + args + "))"+sep+"'";
- }
-
- if (args.length) {
- // called with xxyx.yuu:(test,test)
- // change to ()
- return "'"+ sep + udef_st + name + '(' + args + "))"+sep+"'";
- }
- // raw.. - :raw modifier..
- return "'"+ sep + udef_st + name + ")"+sep+"'";
-
- };
- var body;
- // branched to use + in gecko and [].join() in others
- if(Roo.isGecko){
- body = "tpl.compiled = function(values, parent){ with(values) { return '" +
- tpl.body.replace(/(\r\n|\n)/g, '\\n').replace(/'/g, "\\'").replace(this.re, fn) +
- "';};};";
- }else{
- body = ["tpl.compiled = function(values, parent){ with (values) { return ['"];
- body.push(tpl.body.replace(/(\r\n|\n)/g,
- '\\n').replace(/'/g, "\\'").replace(this.re, fn));
- body.push("'].join('');};};");
- body = body.join('');
- }
-
- Roo.debug && Roo.log(body.replace(/\\n/,'\n'));
-
- /** eval:var:tpl eval:var:fm eval:var:useF eval:var:undef */
- eval(body);
-
- return this;
- },
-
- applyTemplate : function(values){
- return this.master.compiled.call(this, values, {});
- //var s = this.subs;
- },
-
- apply : function(){
- return this.applyTemplate.apply(this, arguments);
- }
-
- });
-
-Roo.XTemplate.from = function(el){
- el = Roo.getDom(el);
- return new Roo.XTemplate(el.value || el.innerHTML);
-};/*
- * Original code for Roojs - LGPL
- * <script type="text/javascript">
- */
-
-/**
- * @class Roo.XComponent
- * A delayed Element creator...
- * Or a way to group chunks of interface together.
- *
- * Mypart.xyx = new Roo.XComponent({
-
- parent : 'Mypart.xyz', // empty == document.element.!!
- order : '001',
- name : 'xxxx'
- region : 'xxxx'
- disabled : function() {}
-
- tree : function() { // return an tree of xtype declared components
- var MODULE = this;
- return
- {
- xtype : 'NestedLayoutPanel',
- // technicall
- }
- ]
- *})
- *
- *
- * It can be used to build a big heiracy, with parent etc.
- * or you can just use this to render a single compoent to a dom element
- * MYPART.render(Roo.Element | String(id) | dom_element )
- *
- * @extends Roo.util.Observable
- * @constructor
- * @param cfg {Object} configuration of component
- *
- */
-Roo.XComponent = function(cfg) {
- Roo.apply(this, cfg);
- this.addEvents({
- /**
- * @event built
- * Fires when this the componnt is built
- * @param {Roo.XComponent} c the component
- */
- 'built' : true
-
- });
- this.region = this.region || 'center'; // default..
- Roo.XComponent.register(this);
- this.modules = false;
- this.el = false; // where the layout goes..
-
-
-}
-Roo.extend(Roo.XComponent, Roo.util.Observable, {
- /**
- * @property el
- * The created element (with Roo.factory())
- * @type {Roo.Layout}
- */
- el : false,
-
- /**
- * @property el
- * for BC - use el in new code
- * @type {Roo.Layout}
- */
- panel : false,
-
- /**
- * @property layout
- * for BC - use el in new code
- * @type {Roo.Layout}
- */
- layout : false,
-
- /**
- * @cfg {Function|boolean} disabled
- * If this module is disabled by some rule, return true from the funtion
- */
- disabled : false,
-
- /**
- * @cfg {String} parent
- * Name of parent element which it get xtype added to..
- */
- parent: false,
-
- /**
- * @cfg {String} order
- * Used to set the order in which elements are created (usefull for multiple tabs)
- */
-
- order : false,
- /**
- * @cfg {String} name
- * String to display while loading.
- */
- name : false,
- /**
- * @cfg {String} region
- * Region to render component to (defaults to center)
- */
- region : 'center',
-
- /**
- * @cfg {Array} items
- * A single item array - the first element is the root of the tree..
- * It's done this way to stay compatible with the Xtype system...
- */
- items : false,
-
- /**
- * @property _tree
- * The method that retuns the tree of parts that make up this compoennt
- * @type {function}
- */
- _tree : false,
-
- /**
- * render
- * render element to dom or tree
- * @param {Roo.Element|String|DomElement} optional render to if parent is not set.
- */
-
- render : function(el)
- {
-
- el = el || false;
- var hp = this.parent ? 1 : 0;
-
- if (!el && typeof(this.parent) == 'string' && this.parent.substring(0,1) == '#') {
- // if parent is a '#.....' string, then let's use that..
- var ename = this.parent.substr(1)
- this.parent = false;
- el = Roo.get(ename);
- if (!el) {
- Roo.log("Warning - element can not be found :#" + ename );
- return;
- }
- }
-
-
- if (!this.parent) {
-
- el = el ? Roo.get(el) : false;
-
- // it's a top level one..
- this.parent = {
- el : new Roo.BorderLayout(el || document.body, {
-
- center: {
- titlebar: false,
- autoScroll:false,
- closeOnTab: true,
- tabPosition: 'top',
- //resizeTabs: true,
- alwaysShowTabs: el && hp? false : true,
- hideTabs: el || !hp ? true : false,
- minTabWidth: 140
- }
- })
- }
- }
-
- if (!this.parent.el) {
- // probably an old style ctor, which has been disabled.
- return;
-
- }
- // The 'tree' method is '_tree now'
-
- var tree = this._tree ? this._tree() : this.tree();
- tree.region = tree.region || this.region;
- this.el = this.parent.el.addxtype(tree);
- this.fireEvent('built', this);
-
- this.panel = this.el;
- this.layout = this.panel.layout;
- this.parentLayout = this.parent.layout || false;
-
- }
-
-});
-
-Roo.apply(Roo.XComponent, {
- /**
- * @property hideProgress
- * true to disable the building progress bar.. usefull on single page renders.
- * @type Boolean
- */
- hideProgress : false,
- /**
- * @property buildCompleted
- * True when the builder has completed building the interface.
- * @type Boolean
- */
- buildCompleted : false,
-
- /**
- * @property topModule
- * the upper most module - uses document.element as it's constructor.
- * @type Object
- */
-
- topModule : false,
-
- /**
- * @property modules
- * array of modules to be created by registration system.
- * @type {Array} of Roo.XComponent
+ * The various sub templates
*/
-
- modules : [],
+ tpls : false,
/**
- * @property elmodules
- * array of modules to be created by which use #ID
- * @type {Array} of Roo.XComponent
+ *
+ * basic tag replacing syntax
+ * WORD:WORD()
+ *
+ * // you can fake an object call by doing this
+ * x.t:(test,tesT)
+ *
*/
-
- elmodules : [],
+ re : /\{([\w-\.]+)(?:\:([\w\.]*)(?:\((.*?)?\))?)?\}/g,
-
/**
- * Register components to be built later.
+ * compile the template
*
- * This solves the following issues
- * - Building is not done on page load, but after an authentication process has occured.
- * - Interface elements are registered on page load
- * - Parent Interface elements may not be loaded before child, so this handles that..
- *
+ * This is not recursive, so I'm not sure how nested templates are really going to be handled..
*
- * example:
- *
- * MyApp.register({
- order : '000001',
- module : 'Pman.Tab.projectMgr',
- region : 'center',
- parent : 'Pman.layout',
- disabled : false, // or use a function..
- })
-
- * * @param {Object} details about module
*/
- register : function(obj) {
-
- Roo.XComponent.event.fireEvent('register', obj);
- switch(typeof(obj.disabled) ) {
+ compile: function()
+ {
+ var s = this.html;
+
+ s = ['<tpl>', s, '</tpl>'].join('');
+
+ var re = /<tpl\b[^>]*>((?:(?=([^<]+))\2|<(?!tpl\b[^>]*>))*?)<\/tpl>/,
+ nameRe = /^<tpl\b[^>]*?for="(.*?)"/,
+ ifRe = /^<tpl\b[^>]*?if="(.*?)"/,
+ execRe = /^<tpl\b[^>]*?exec="(.*?)"/,
+ namedRe = /^<tpl\b[^>]*?name="(\w+)"/, // named templates..
+ m,
+ id = 0,
+ tpls = [];
+
+ while(true == !!(m = s.match(re))){
+ var forMatch = m[0].match(nameRe),
+ ifMatch = m[0].match(ifRe),
+ execMatch = m[0].match(execRe),
+ namedMatch = m[0].match(namedRe),
- case 'undefined':
- break;
+ exp = null,
+ fn = null,
+ exec = null,
+ name = forMatch && forMatch[1] ? forMatch[1] : '';
+
+ if (ifMatch) {
+ // if - puts fn into test..
+ exp = ifMatch && ifMatch[1] ? ifMatch[1] : null;
+ if(exp){
+ fn = new Function('values', 'parent', 'with(values){ return '+(Roo.util.Format.htmlDecode(exp))+'; }');
+ }
+ }
- case 'function':
- if ( obj.disabled() ) {
- return;
+ if (execMatch) {
+ // exec - calls a function... returns empty if true is returned.
+ exp = execMatch && execMatch[1] ? execMatch[1] : null;
+ if(exp){
+ exec = new Function('values', 'parent', 'with(values){ '+(Roo.util.Format.htmlDecode(exp))+'; }');
}
- break;
+ }
- default:
- if (obj.disabled) {
- return;
+
+ if (name) {
+ // for =
+ switch(name){
+ case '.': name = new Function('values', 'parent', 'with(values){ return values; }'); break;
+ case '..': name = new Function('values', 'parent', 'with(values){ return parent; }'); break;
+ default: name = new Function('values', 'parent', 'with(values){ return '+name+'; }');
}
- break;
+ }
+ var uid = namedMatch ? namedMatch[1] : id;
+
+
+ tpls.push({
+ id: namedMatch ? namedMatch[1] : id,
+ target: name,
+ exec: exec,
+ test: fn,
+ body: m[1] || ''
+ });
+ if (namedMatch) {
+ s = s.replace(m[0], '');
+ } else {
+ s = s.replace(m[0], '{xtpl'+ id + '}');
+ }
+ ++id;
}
-
- this.modules.push(obj);
-
+ this.tpls = [];
+ for(var i = tpls.length-1; i >= 0; --i){
+ this.compileTpl(tpls[i]);
+ this.tpls[tpls[i].id] = tpls[i];
+ }
+ this.master = tpls[tpls.length-1];
+ return this;
},
/**
- * convert a string to an object..
- * eg. 'AAA.BBB' -> finds AAA.BBB
-
+ * same as applyTemplate, except it's done to one of the subTemplates
+ * when using named templates, you can do:
+ *
+ * var str = pl.applySubTemplate('your-name', values);
+ *
+ *
+ * @param {Number} id of the template
+ * @param {Object} values to apply to template
+ * @param {Object} parent (normaly the instance of this object)
*/
-
- toObject : function(str)
+ applySubTemplate : function(id, values, parent)
{
- if (!str || typeof(str) == 'object') {
- return str;
- }
- if (str.substring(0,1) == '#') {
- return str;
- }
-
- var ar = str.split('.');
- var rt, o;
- rt = ar.shift();
- /** eval:var:o */
- try {
- eval('if (typeof ' + rt + ' == "undefined"){ o = false;} o = ' + rt + ';');
- } catch (e) {
- throw "Module not found : " + str;
- }
- if (o === false) {
- throw "Module not found : " + str;
- }
- Roo.each(ar, function(e) {
- if (typeof(o[e]) == 'undefined') {
- throw "Module not found : " + str;
- }
- o = o[e];
- });
- return o;
+ var t = this.tpls[id];
- },
-
-
- /**
- * move modules into their correct place in the tree..
- *
- */
- preBuild : function ()
- {
- var _t = this;
- Roo.each(this.modules , function (obj)
- {
- Roo.XComponent.event.fireEvent('beforebuild', obj);
-
- var opar = obj.parent;
- try {
- obj.parent = this.toObject(opar);
- } catch(e) {
- Roo.log("parent:toObject failed: " + e.toString());
- return;
+
+ try {
+ if(t.test && !t.test.call(this, values, parent)){
+ return '';
}
+ } catch(e) {
+ Roo.log("Xtemplate.applySubTemplate 'test': Exception thrown");
+ Roo.log(e.toString());
+ Roo.log(t.test);
+ return ''
+ }
+ try {
- if (!obj.parent) {
- Roo.debug && Roo.log("GOT top level module");
- Roo.debug && Roo.log(obj);
- obj.modules = new Roo.util.MixedCollection(false,
- function(o) { return o.order + '' }
- );
- this.topModule = obj;
- return;
- }
- // parent is a string (usually a dom element name..)
- if (typeof(obj.parent) == 'string') {
- this.elmodules.push(obj);
- return;
- }
- if (obj.parent.constructor != Roo.XComponent) {
- Roo.log("Warning : Object Parent is not instance of XComponent:" + obj.name)
- }
- if (!obj.parent.modules) {
- obj.parent.modules = new Roo.util.MixedCollection(false,
- function(o) { return o.order + '' }
- );
+ if(t.exec && t.exec.call(this, values, parent)){
+ return '';
}
- if (obj.parent.disabled) {
- obj.disabled = true;
+ } catch(e) {
+ Roo.log("Xtemplate.applySubTemplate 'exec': Exception thrown");
+ Roo.log(e.toString());
+ Roo.log(t.exec);
+ return ''
+ }
+ try {
+ var vs = t.target ? t.target.call(this, values, parent) : values;
+ parent = t.target ? values : parent;
+ if(t.target && vs instanceof Array){
+ var buf = [];
+ for(var i = 0, len = vs.length; i < len; i++){
+ buf[buf.length] = t.compiled.call(this, vs[i], parent);
+ }
+ return buf.join('');
}
- obj.parent.modules.add(obj);
- }, this);
+ return t.compiled.call(this, vs, parent);
+ } catch (e) {
+ Roo.log("Xtemplate.applySubTemplate : Exception thrown");
+ Roo.log(e.toString());
+ Roo.log(t.compiled);
+ return '';
+ }
},
-
- /**
- * make a list of modules to build.
- * @return {Array} list of modules.
- */
-
- buildOrder : function()
+
+ compileTpl : function(tpl)
{
- var _this = this;
- var cmp = function(a,b) {
- return String(a).toUpperCase() > String(b).toUpperCase() ? 1 : -1;
+ var fm = Roo.util.Format;
+ var useF = this.disableFormats !== true;
+ var sep = Roo.isGecko ? "+" : ",";
+ var undef = function(str) {
+ Roo.log("Property not found :" + str);
+ return '';
};
- if ((!this.topModule || !this.topModule.modules) && !this.elmodules.length) {
- throw "No top level modules to build";
- }
-
- // make a flat list in order of modules to build.
- var mods = this.topModule ? [ this.topModule ] : [];
-
-
- // elmodules (is a list of DOM based modules )
- Roo.each(this.elmodules, function(e) {
- mods.push(e);
- if (!this.topModule &&
- typeof(e.parent) == 'string' &&
- e.parent.substring(0,1) == '#' &&
- Roo.get(e.parent.substr(1))
- ) {
-
- _this.topModule = e;
- }
-
- });
-
- // add modules to their parents..
- var addMod = function(m) {
- Roo.debug && Roo.log("build Order: add: " + m.name);
-
- mods.push(m);
- if (m.modules && !m.disabled) {
- Roo.debug && Roo.log("build Order: " + m.modules.length + " child modules");
- m.modules.keySort('ASC', cmp );
- Roo.debug && Roo.log("build Order: " + m.modules.length + " child modules (after sort)");
-
- m.modules.each(addMod);
- } else {
- Roo.debug && Roo.log("build Order: no child modules");
+ var fn = function(m, name, format, args)
+ {
+ //Roo.log(arguments);
+ args = args ? args.replace(/\\'/g,"'") : args;
+ //["{TEST:(a,b,c)}", "TEST", "", "a,b,c", 0, "{TEST:(a,b,c)}"]
+ if (typeof(format) == 'undefined') {
+ format= 'htmlEncode';
}
- // not sure if this is used any more..
- if (m.finalize) {
- m.finalize.name = m.name + " (clean up) ";
- mods.push(m.finalize);
+ if (format == 'raw' ) {
+ format = false;
}
- }
- if (this.topModule && this.topModule.modules) {
- this.topModule.modules.keySort('ASC', cmp );
- this.topModule.modules.each(addMod);
- }
- return mods;
- },
-
- /**
- * Build the registered modules.
- * @param {Object} parent element.
- * @param {Function} optional method to call after module has been added.
- *
- */
-
- build : function()
- {
-
- this.preBuild();
- var mods = this.buildOrder();
-
- //this.allmods = mods;
- //Roo.debug && Roo.log(mods);
- //return;
- if (!mods.length) { // should not happen
- throw "NO modules!!!";
- }
-
-
- var msg = "Building Interface...";
- // flash it up as modal - so we store the mask!?
- if (!this.hideProgress) {
- Roo.MessageBox.show({ title: 'loading' });
- Roo.MessageBox.show({
- title: "Please wait...",
- msg: msg,
- width:450,
- progress:true,
- closable:false,
- modal: false
-
- });
- }
- var total = mods.length;
-
- var _this = this;
- var progressRun = function() {
- if (!mods.length) {
- Roo.debug && Roo.log('hide?');
- if (!this.hideProgress) {
- Roo.MessageBox.hide();
- }
- Roo.XComponent.event.fireEvent('buildcomplete', _this.topModule);
-
- // THE END...
- return false;
+ if(name.substr(0, 4) == 'xtpl'){
+ return "'"+ sep +'this.applySubTemplate('+name.substr(4)+', values, parent)'+sep+"'";
}
- var m = mods.shift();
-
-
- Roo.debug && Roo.log(m);
- // not sure if this is supported any more.. - modules that are are just function
- if (typeof(m) == 'function') {
- m.call(this);
- return progressRun.defer(10, _this);
- }
+ // build an array of options to determine if value is undefined..
+ // basically get 'xxxx.yyyy' then do
+ // (typeof(xxxx) == 'undefined' || typeof(xxx.yyyy) == 'undefined') ?
+ // (function () { Roo.log("Property not found"); return ''; })() :
+ // ......
- msg = "Building Interface " + (total - mods.length) +
- " of " + total +
- (m.name ? (' - ' + m.name) : '');
- Roo.debug && Roo.log(msg);
- if (!this.hideProgress) {
- Roo.MessageBox.updateProgress( (total - mods.length)/total, msg );
- }
+ var udef_ar = [];
+ var lookfor = '';
+ Roo.each(name.split('.'), function(st) {
+ lookfor += (lookfor.length ? '.': '') + st;
+ udef_ar.push( "(typeof(" + lookfor + ") == 'undefined')" );
+ });
-
- // is the module disabled?
- var disabled = (typeof(m.disabled) == 'function') ?
- m.disabled.call(m.module.disabled) : m.disabled;
+ var udef_st = '((' + udef_ar.join(" || ") +") ? undef('" + name + "') : "; // .. needs )
- if (disabled) {
- return progressRun(); // we do not update the display!
+ if(format && useF){
+
+ args = args ? ',' + args : "";
+
+ if(format.substr(0, 5) != "this."){
+ format = "fm." + format + '(';
+ }else{
+ format = 'this.call("'+ format.substr(5) + '", ';
+ args = ", values";
+ }
+
+ return "'"+ sep + udef_st + format + name + args + "))"+sep+"'";
}
-
- // now build
-
-
-
- m.render();
- // it's 10 on top level, and 1 on others??? why...
- return progressRun.defer(10, _this);
+ if (args.length) {
+ // called with xxyx.yuu:(test,test)
+ // change to ()
+ return "'"+ sep + udef_st + name + '(' + args + "))"+sep+"'";
+ }
+ // raw.. - :raw modifier..
+ return "'"+ sep + udef_st + name + ")"+sep+"'";
+
+ };
+ var body;
+ // branched to use + in gecko and [].join() in others
+ if(Roo.isGecko){
+ body = "tpl.compiled = function(values, parent){ with(values) { return '" +
+ tpl.body.replace(/(\r\n|\n)/g, '\\n').replace(/'/g, "\\'").replace(this.re, fn) +
+ "';};};";
+ }else{
+ body = ["tpl.compiled = function(values, parent){ with (values) { return ['"];
+ body.push(tpl.body.replace(/(\r\n|\n)/g,
+ '\\n').replace(/'/g, "\\'").replace(this.re, fn));
+ body.push("'].join('');};};");
+ body = body.join('');
}
- progressRun.defer(1, _this);
-
+ Roo.debug && Roo.log(body.replace(/\\n/,'\n'));
+
+ /** eval:var:tpl eval:var:fm eval:var:useF eval:var:undef */
+ eval(body);
+ return this;
},
-
-
- /**
- * Event Object.
- *
- *
- */
- event: false,
- /**
- * wrapper for event.on - aliased later..
- * Typically use to register a event handler for register:
- *
- * eg. Roo.XComponent.on('register', function(comp) { comp.disable = true } );
- *
- */
- on : false
-
-
-
-});
-Roo.XComponent.event = new Roo.util.Observable({
- events : {
- /**
- * @event register
- * Fires when an Component is registered,
- * set the disable property on the Component to stop registration.
- * @param {Roo.XComponent} c the component being registerd.
- *
- */
- 'register' : true,
- /**
- * @event beforebuild
- * Fires before each Component is built
- * can be used to apply permissions.
- * @param {Roo.XComponent} c the component being registerd.
- *
- */
- 'beforebuild' : true,
- /**
- * @event buildcomplete
- * Fires on the top level element when all elements have been built
- * @param {Roo.XComponent} the top level component.
- */
- 'buildcomplete' : true
-
- }
-});
+ applyTemplate : function(values){
+ return this.master.compiled.call(this, values, {});
+ //var s = this.subs;
+ },
-Roo.XComponent.on = Roo.XComponent.event.on.createDelegate(Roo.XComponent.event);
-
\ No newline at end of file
+ apply : function(){
+ return this.applyTemplate.apply(this, arguments);
+ }
+
+ });
+
+Roo.XTemplate.from = function(el){
+ el = Roo.getDom(el);
+ return new Roo.XTemplate(el.value || el.innerHTML);
+};
\ No newline at end of file