Added: ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/TreeV3.js
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/TreeV3.js?view=auto&rev=509273 ============================================================================== --- ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/TreeV3.js (added) +++ ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/TreeV3.js Mon Feb 19 09:56:06 2007 @@ -0,0 +1,347 @@ +/* + Copyright (c) 2004-2006, The Dojo Foundation + All Rights Reserved. + + Licensed under the Academic Free License version 2.1 or above OR the + modified BSD license. For more information on Dojo licensing, see: + + http://dojotoolkit.org/community/licensing.shtml +*/ + +/** + * Tree model does all the drawing, visual node management etc. + * Throws events about clicks on it, so someone may catch them and process + * Tree knows nothing about DnD stuff, covered in TreeDragAndDrop and (if enabled) attached by controller +*/ + +/** + * TODO: use domNode.cloneNode instead of createElement for grid + * Should be faster (lyxsus) + */ +dojo.provide("dojo.widget.TreeV3"); + +dojo.require("dojo.widget.TreeWithNode"); +dojo.require("dojo.widget.*"); +dojo.require("dojo.event.*"); +dojo.require("dojo.io.*"); +dojo.require("dojo.widget.HtmlWidget"); +dojo.require("dojo.widget.TreeNodeV3"); + +dojo.widget.defineWidget( + "dojo.widget.TreeV3", + [dojo.widget.HtmlWidget, dojo.widget.TreeWithNode], + function() { + this.eventNames = {}; + + this.DndAcceptTypes = []; + this.actionsDisabled = []; + + this.listeners = []; + + this.tree = this; + }, +{ + DndMode: "", + + /** + * factory to generate default widgets + */ + defaultChildWidget: null, + + defaultChildTitle: "New Node", // for editing + + + eagerWidgetInstantiation: false, + + eventNamesDefault: { + + // tree created.. Perform tree-wide actions if needed + afterTreeCreate: "afterTreeCreate", + beforeTreeDestroy: "beforeTreeDestroy", + /* can't name it "beforeDestroy", because such name causes memleaks in IE */ + beforeNodeDestroy: "beforeNodeDestroy", + afterChangeTree: "afterChangeTree", + + afterSetFolder: "afterSetFolder", + afterUnsetFolder: "afterUnsetFolder", + beforeMoveFrom: "beforeMoveFrom", + beforeMoveTo: "beforeMoveTo", + afterMoveFrom: "afterMoveFrom", + afterMoveTo: "afterMoveTo", + afterAddChild: "afterAddChild", + afterDetach: "afterDetach", + afterExpand: "afterExpand", + beforeExpand: "beforeExpand", + afterSetTitle: "afterSetTitle", + afterCollapse: "afterCollapse", + beforeCollapse: "beforeCollapse" + }, + + classPrefix: "Tree", + + style: "", + + /** + * is it possible to add a new child to leaf ? + */ + allowAddChildToLeaf: true, + + /** + * when last children is removed from node should it stop being a "folder" ? + */ + unsetFolderOnEmpty: true, + + + DndModes: { + BETWEEN: 1, + ONTO: 2 + }, + + DndAcceptTypes: "", + + // will have cssRoot before it + templateCssPath: dojo.uri.dojoUri("src/widget/templates/TreeV3.css"), + + templateString: '<div style="${this.style}">\n</div>', + + isExpanded: true, // consider this "root node" to be always expanded + + isTree: true, + + + + createNode: function(data) { + + data.tree = this.widgetId; + + if (data.widgetName) { + // TODO: check if such widget has createSimple + return dojo.widget.createWidget(data.widgetName, data); + } else if (this.defaultChildWidget.prototype.createSimple) { + return this.defaultChildWidget.prototype.createSimple(data); + } else { + var ns = this.defaultChildWidget.prototype.ns; + var wt = this.defaultChildWidget.prototype.widgetType; + + return dojo.widget.createWidget(ns + ":" + wt, data); + } + + }, + + + // expandNode has +- CSS background. Not img.src for performance, background src string resides in single place. + // selection in KHTML/Mozilla disabled treewide, IE requires unselectable for every node + // you can add unselectable if you want both in postCreate of tree and in this template + + // create new template and put into prototype + makeNodeTemplate: function() { + + var domNode = document.createElement("div"); + dojo.html.setClass(domNode, this.classPrefix+"Node "+this.classPrefix+"ExpandLeaf "+this.classPrefix+"ChildrenNo"); + this.nodeTemplate = domNode; + + var expandNode = document.createElement("div"); + var clazz = this.classPrefix+"Expand"; + if (dojo.render.html.ie) { + clazz = clazz + ' ' + this.classPrefix+"IEExpand"; + } + dojo.html.setClass(expandNode, clazz); + + this.expandNodeTemplate = expandNode; + + // need <span> inside <div> + // div for multiline support, span for styling exactly the text, not whole line + var labelNode = document.createElement("span"); + dojo.html.setClass(labelNode, this.classPrefix+"Label"); + this.labelNodeTemplate = labelNode; + + var contentNode = document.createElement("div"); + var clazz = this.classPrefix+"Content"; + + /** + * IE<7 does not support min-height properly so I have to rely + * on this hack + * FIXME: do it in CSS only + */ + if (dojo.render.html.ie && !dojo.render.html.ie70) { + clazz = clazz + ' ' + this.classPrefix+"IEContent"; + } + + + dojo.html.setClass(contentNode, clazz); + + this.contentNodeTemplate = contentNode; + + domNode.appendChild(expandNode); + domNode.appendChild(contentNode); + contentNode.appendChild(labelNode); + + + }, + + makeContainerNodeTemplate: function() { + + var div = document.createElement('div'); + div.style.display = 'none'; + dojo.html.setClass(div, this.classPrefix+"Container"); + + this.containerNodeTemplate = div; + + }, + + + actions: { + ADDCHILD: "ADDCHILD" + }, + + + getInfo: function() { + var info = { + widgetId: this.widgetId, + objectId: this.objectId + } + + return info; + }, + + adjustEventNames: function() { + + for(var name in this.eventNamesDefault) { + if (dojo.lang.isUndefined(this.eventNames[name])) { + this.eventNames[name] = this.widgetId+"/"+this.eventNamesDefault[name]; + } + } + }, + + + adjustDndMode: function() { + var _this = this; + + + var DndMode = 0; + dojo.lang.forEach(this.DndMode.split(';'), + function(elem) { + var mode = _this.DndModes[dojo.string.trim(elem).toUpperCase()]; + if (mode) DndMode = DndMode | mode; + } + ); + + + this.DndMode = DndMode; + + }, + + /** + * publish destruction event so that any listeners should stop listening + */ + destroy: function() { + dojo.event.topic.publish(this.tree.eventNames.beforeTreeDestroy, { source: this } ); + + return dojo.widget.HtmlWidget.prototype.destroy.apply(this, arguments); + }, + + initialize: function(args){ + + this.domNode.widgetId = this.widgetId; + + for(var i=0; i<this.actionsDisabled.length;i++) { + this.actionsDisabled[i] = this.actionsDisabled[i].toUpperCase(); + } + + //dojo.debug(args.defaultChildWidget ? true : false) + + if (!args.defaultChildWidget) { + this.defaultChildWidget = dojo.widget.TreeNodeV3; + } else { + this.defaultChildWidget = dojo.lang.getObjPathValue(args.defaultChildWidget); + } + + this.adjustEventNames(); + this.adjustDndMode(); + + this.makeNodeTemplate(); + this.makeContainerNodeTemplate(); + + this.containerNode = this.domNode; + + dojo.html.setClass(this.domNode, this.classPrefix+"Container"); + + var _this = this; + + //dojo.html.disableSelection(this.domNode) + + dojo.lang.forEach(this.listeners, + function(elem) { + var t = dojo.lang.isString(elem) ? dojo.widget.byId(elem) : elem; + t.listenTree(_this) + } + ); + + + + + + }, + + + postCreate: function() { + dojo.event.topic.publish(this.eventNames.afterTreeCreate, { source: this } ); + }, + + + /** + * Move child to newParent as last child + * redraw tree and update icons. + * + * Called by target, saves source in event. + * events are published for BOTH trees AFTER update. + */ + move: function(child, newParent, index) { + + if (!child.parent) { + dojo.raise(this.widgetType+": child can be moved only while it's attached"); + } + + var oldParent = child.parent; + var oldTree = child.tree; + var oldIndex = child.getParentIndex(); + var newTree = newParent.tree; + var newParent = newParent; + var newIndex = index; + + var message = { + oldParent: oldParent, oldTree: oldTree, oldIndex: oldIndex, + newParent: newParent, newTree: newTree, newIndex: newIndex, + child: child + }; + + dojo.event.topic.publish(oldTree.eventNames.beforeMoveFrom, message); + dojo.event.topic.publish(newTree.eventNames.beforeMoveTo, message); + + this.doMove.apply(this, arguments); + + + /* publish events here about structural changes for both source and target trees */ + dojo.event.topic.publish(oldTree.eventNames.afterMoveFrom, message); + dojo.event.topic.publish(newTree.eventNames.afterMoveTo, message); + + }, + + + /* do actual parent change here. Write remove child first */ + doMove: function(child, newParent, index) { + //dojo.debug("MOVE "+child+" to "+newParent+" at "+index); + + //var parent = child.parent; + child.doDetach(); + + //dojo.debug("addChild "+child+" to "+newParent+" at "+index); + + newParent.doAddChild(child, index); + }, + + toString: function() { + return "["+this.widgetType+" ID:"+this.widgetId +"]" + } + +}); Propchange: ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/TreeV3.js ------------------------------------------------------------------------------ svn:eol-style = native Propchange: ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/TreeV3.js ------------------------------------------------------------------------------ svn:keywords = "Date Rev Author URL Id" Propchange: ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/TreeV3.js ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/TreeWithNode.js URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/TreeWithNode.js?view=auto&rev=509273 ============================================================================== --- ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/TreeWithNode.js (added) +++ ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/TreeWithNode.js Mon Feb 19 09:56:06 2007 @@ -0,0 +1,277 @@ +/* + Copyright (c) 2004-2006, The Dojo Foundation + All Rights Reserved. + + Licensed under the Academic Free License version 2.1 or above OR the + modified BSD license. For more information on Dojo licensing, see: + + http://dojotoolkit.org/community/licensing.shtml +*/ + + +dojo.require("dojo.lang.declare"); +dojo.provide("dojo.widget.TreeWithNode"); + +dojo.declare( + "dojo.widget.TreeWithNode", + null, + function(){ }, +{ + /* + * dynamic loading-related stuff. + * When an empty folder node appears, it is "UNCHECKED" first, + * then after Rpc call it becomes LOADING and, finally LOADED + * + * tree may be dynamically loaded also + */ + loadStates: { + UNCHECKED: "UNCHECKED", + LOADING: "LOADING", + LOADED: "LOADED" + }, + + state: "UNCHECKED", // after creation will change to loadStates: "loaded/loading/unchecked" + + //RpcUrl: "", // user can override rpc url for specific nodes + + objectId: "", // the widget represents an object + + + // I need this to parse children + isContainer: true, + + lockLevel: 0, // lock ++ unlock --, so nested locking works fine + + lock: function() { + this.lockLevel++; + }, + unlock: function() { + if (!this.lockLevel) { + //dojo.debug((new Error()).stack); + dojo.raise(this.widgetType+" unlock: not locked"); + } + this.lockLevel--; + }, + + + expandLevel: 0, // expand to level automatically + loadLevel: 0, // load to level automatically + + hasLock: function() { + return this.lockLevel>0; + }, + + isLocked: function() { + var node = this; + while (true) { + if (node.lockLevel) { + return true; + } + if (!node.parent || node.isTree) { + break; + } + + node = node.parent; + + } + + return false; + }, + + + flushLock: function() { + this.lockLevel = 0; + //this.unMarkLoading(); + }, + + + actionIsDisabled: function(action) { + var disabled = false; + + if (dojo.lang.inArray(this.actionsDisabled, action)) { + disabled = true; + } + + + //dojo.debug("Check "+this+" "+disabled) + + + if (this.isTreeNode) { + if (!this.tree.allowAddChildToLeaf && action == this.actions.ADDCHILD && !this.isFolder) { + disabled = true; + } + } + return disabled; + }, + + actionIsDisabledNow: function(action) { + return this.actionIsDisabled(action) || this.isLocked(); + }, + + + /** + * childrenArray is array of Widgets or array of Objects + * widgets may be both attached and detached + * + * Use Cases + * 1) lots of widgets are packed and passed in. + * - widgets are created + * - widgets have no parent (detached or not attached yet) + * + * 2) array of widgets and data objects passed in with flag makeWidgetsFromChildren + * - some widgets are not created + * - all objects have no parent + * + * 3) expand is called with makeWidgetsFromChildren=true + * - some objects need to be turned into widgets + * - some widgets have parent (e.g markup), some widgets and objects do not + * + * Will folderize a node as side-effect. + */ + setChildren: function(childrenArray) { + //dojo.profile.start("setChildren "+this); + //dojo.debug("setChildren in "+this); + + + if (this.isTreeNode && !this.isFolder) { + //dojo.debug("folder parent "+parent+ " isfolder "+parent.isFolder); + this.setFolder(); + } else if (this.isTreeNode) { + this.state = this.loadStates.LOADED; + } + + var hadChildren = this.children.length > 0; + + if (hadChildren && childrenArray){ + // perf: most of time setChildren used for empty nodes, so save function call + this.destroyChildren() + } + + if (childrenArray) { + this.children = childrenArray; + } + + + + var hasChildren = this.children.length > 0; + if (this.isTreeNode && hasChildren != hadChildren) { + // call only when hasChildren state changes + this.viewSetHasChildren(); + } + + + + for(var i=0; i<this.children.length; i++) { + var child = this.children[i]; + + //dojo.profile.start("setChildren - create "+this); + + if (!(child instanceof dojo.widget.Widget)) { + + child = this.children[i] = this.tree.createNode(child); + var childWidgetCreated = true; + //dojo.debugShallow(child) + + //dojo.debug("setChildren creates node "+child); + } else { + var childWidgetCreated = false; + } + + //dojo.profile.end("setChildren - create "+this); + + //dojo.profile.start("setChildren - attach "+this); + + if (!child.parent) { // detached child + + //dojo.debug("detached child "+child); + + child.parent = this; + + //dojo.profile.start("setChildren - updateTree "+this); + + if (this.tree !== child.tree) { + child.updateTree(this.tree); + } + //dojo.profile.end("setChildren - updateTree "+this); + + + //dojo.debug("Add layout for "+child); + child.viewAddLayout(); + this.containerNode.appendChild(child.domNode); + + var message = { + child: child, + index: i, + parent: this, + childWidgetCreated: childWidgetCreated + } + + delete dojo.widget.manager.topWidgets[child.widgetId]; + + + //dojo.profile.start("setChildren - event "+this); + //dojo.debug("publish "+this.tree.eventNames.afterAddChild) + dojo.event.topic.publish(this.tree.eventNames.afterAddChild, message); + + //dojo.profile.end("setChildren - event "+this); + + } + + if (this.tree.eagerWidgetInstantiation) { + dojo.lang.forEach(this.children, function(child) { + child.setChildren(); + }); + } + + //dojo.profile.end("setChildren - attach "+this); + + + } + + + + //dojo.profile.end("setChildren "+this); + + }, + + + doAddChild: function(child, index) { + return this.addChild(child, index, true); + }, + + addChild: function(child, index, dontPublishEvent) { + if (dojo.lang.isUndefined(index)) { + index = this.children.length; + } + + //dojo.debug("doAddChild "+index+" called for "+this+" child "+child+" existing children "+(this.children.length ? this.children : "<no children>")); + + if (!child.isTreeNode){ + dojo.raise("You can only add TreeNode widgets to a "+this.widgetType+" widget!"); + return; + } + + this.children.splice(index, 0, child); + child.parent = this; + + child.addedTo(this, index, dontPublishEvent); + + // taken from DomWidget.registerChild + // delete from widget list that are notified on resize etc (no parent) + delete dojo.widget.manager.topWidgets[child.widgetId]; + + }, + + /** + * does not inform children about resize (skips onShow), + * because on large trees that's slow + */ + onShow: function() { + this.animationInProgress=false; + }, + + onHide: function() { + this.animationInProgress=false; + } + +}); Propchange: ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/TreeWithNode.js ------------------------------------------------------------------------------ svn:eol-style = native Propchange: ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/TreeWithNode.js ------------------------------------------------------------------------------ svn:keywords = "Date Rev Author URL Id" Propchange: ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/TreeWithNode.js ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/UsTextbox.js URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/UsTextbox.js?view=auto&rev=509273 ============================================================================== --- ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/UsTextbox.js (added) +++ ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/UsTextbox.js Mon Feb 19 09:56:06 2007 @@ -0,0 +1,93 @@ +/* + Copyright (c) 2004-2006, The Dojo Foundation + All Rights Reserved. + + Licensed under the Academic Free License version 2.1 or above OR the + modified BSD license. For more information on Dojo licensing, see: + + http://dojotoolkit.org/community/licensing.shtml +*/ + +dojo.provide("dojo.widget.UsTextbox"); + +dojo.require("dojo.widget.ValidationTextbox"); +dojo.require("dojo.validate.us"); + +dojo.widget.defineWidget( + "dojo.widget.UsStateTextbox", + dojo.widget.ValidationTextbox, + { + // summary: + // a Textbox which tests for a United States state abbreviation + + // allowTerritories: Boolean + // Allow Guam, Puerto Rico, etc. Default is true. + + // allowMilitary: Boolean + // Allow military 'states', e.g. Armed Forces Europe (AE). Default is true. + + mixInProperties: function(/*Object*/localProperties){ + // summary: see dojo.widget.Widget + + // Initialize properties in super-class. + dojo.widget.UsStateTextbox.superclass.mixInProperties.apply(this, arguments); + + // Get properties from markup attributes, and assign to flags object. + if(localProperties.allowterritories){ + this.flags.allowTerritories = (localProperties.allowterritories == "true"); + } + if(localProperties.allowmilitary){ + this.flags.allowMilitary = (localProperties.allowmilitary == "true"); + } + }, + + isValid: function(){ + // summary: see dojo.widget.ValidationTextbox + return dojo.validate.us.isState(this.textbox.value, this.flags); + } + } +); + +/* + ****** UsZipTextbox ****** + + A subclass of ValidationTextbox. + Over-rides isValid to test if input is a US zip code. + Validates zip-5 and zip-5 plus 4. +*/ +dojo.widget.defineWidget( + "dojo.widget.UsZipTextbox", + dojo.widget.ValidationTextbox, + { + // summary: a Textbox which tests for a United States postal code + isValid: function(){ + // summary: see dojo.widget.ValidationTextbox + return dojo.validate.us.isZipCode(this.textbox.value); + } + } +); + +dojo.widget.defineWidget( + "dojo.widget.UsSocialSecurityNumberTextbox", + dojo.widget.ValidationTextbox, + { + // summary: a Textbox which tests for a United States Social Security number + isValid: function(){ + // summary: see dojo.widget.ValidationTextbox + return dojo.validate.us.isSocialSecurityNumber(this.textbox.value); + } + } +); + +dojo.widget.defineWidget( + "dojo.widget.UsPhoneNumberTextbox", + dojo.widget.ValidationTextbox, + { + // summary: a Textbox which tests for a United States 10-digit telephone number, extension is optional. + + isValid: function(){ + // summary: see dojo.widget.ValidationTextbox + return dojo.validate.us.isPhoneNumber(this.textbox.value); + } + } +); Propchange: ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/UsTextbox.js ------------------------------------------------------------------------------ svn:eol-style = native Propchange: ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/UsTextbox.js ------------------------------------------------------------------------------ svn:keywords = "Date Rev Author URL Id" Propchange: ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/UsTextbox.js ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/ValidationTextbox.js URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/ValidationTextbox.js?view=auto&rev=509273 ============================================================================== --- ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/ValidationTextbox.js (added) +++ ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/ValidationTextbox.js Mon Feb 19 09:56:06 2007 @@ -0,0 +1,204 @@ +/* + Copyright (c) 2004-2006, The Dojo Foundation + All Rights Reserved. + + Licensed under the Academic Free License version 2.1 or above OR the + modified BSD license. For more information on Dojo licensing, see: + + http://dojotoolkit.org/community/licensing.shtml +*/ + +dojo.provide("dojo.widget.ValidationTextbox"); + +dojo.require("dojo.widget.Textbox"); +dojo.require("dojo.i18n.common"); + +dojo.widget.defineWidget( + "dojo.widget.ValidationTextbox", + dojo.widget.Textbox, + function() { + // summary: + // A subclass of Textbox. + // Over-ride isValid in subclasses to perform specific kinds of validation. + + // this property isn't a primitive and needs to be created on a per-item basis. + this.flags = {}; + }, + { + // default values for new subclass properties + // required: Boolean + // Can be true or false, default is false. + required: false, + rangeClass: "range", + // invalidClass: String + // Class used to format displayed text in page if necessary to override default class + invalidClass: "invalid", + // missingClass: String + // Override default class used for missing input data + missingClass: "missing", + classPrefix: "dojoValidate", + // size: String + // Basic input tag size declaration. + size: "", + // maxlength: String + // Basic input tag maxlength declaration. + maxlength: "", + // promptMessage: String + // Will not issue invalid message if field is populated with default user-prompt text + promptMessage: "", + // invalidMessage: String + // The message to display if value is invalid. + invalidMessage: "", + // missingMessage: String + // The message to display if value is missing. + missingMessage: "", + rangeMessage: "", + // listenOnKeyPress: Boolean + // Updates messages on each key press. Default is true. + listenOnKeyPress: true, + htmlfloat: "none", + lastCheckedValue: null, + + templatePath: dojo.uri.dojoUri("src/widget/templates/ValidationTextbox.html"), + templateCssPath: dojo.uri.dojoUri("src/widget/templates/Validate.css"), + + // new DOM nodes + invalidSpan: null, + missingSpan: null, + rangeSpan: null, + + getValue: function() { + return this.textbox.value; + }, + + setValue: function(value) { + this.textbox.value = value; + this.update(); + }, + + isValid: function() { + // summary: Need to over-ride with your own validation code in subclasses + return true; + }, + + isInRange: function() { + // summary: Need to over-ride with your own validation code in subclasses + return true; + }, + + isEmpty: function() { + // summary: Checks for whitespace + return ( /^\s*$/.test(this.textbox.value) ); // Boolean + }, + + isMissing: function() { + // summary: Checks to see if value is required and is whitespace + return ( this.required && this.isEmpty() ); // Boolean + }, + + update: function() { + // summary: + // Called by oninit, onblur, and onkeypress. + // description: + // Show missing or invalid messages if appropriate, and highlight textbox field. + this.lastCheckedValue = this.textbox.value; + this.missingSpan.style.display = "none"; + this.invalidSpan.style.display = "none"; + this.rangeSpan.style.display = "none"; + + var empty = this.isEmpty(); + var valid = true; + if(this.promptMessage != this.textbox.value){ + valid = this.isValid(); + } + var missing = this.isMissing(); + + // Display at most one error message + if(missing){ + this.missingSpan.style.display = ""; + }else if( !empty && !valid ){ + this.invalidSpan.style.display = ""; + }else if( !empty && !this.isInRange() ){ + this.rangeSpan.style.display = ""; + } + this.highlight(); + }, + + updateClass: function(className){ + // summary: used to ensure that only 1 validation class is set at a time + var pre = this.classPrefix; + dojo.html.removeClass(this.textbox,pre+"Empty"); + dojo.html.removeClass(this.textbox,pre+"Valid"); + dojo.html.removeClass(this.textbox,pre+"Invalid"); + dojo.html.addClass(this.textbox,pre+className); + }, + + highlight: function() { + // summary: by Called oninit, and onblur. + + // highlight textbox background + if (this.isEmpty()) { + this.updateClass("Empty"); + }else if (this.isValid() && this.isInRange() ){ + this.updateClass("Valid"); + }else if(this.textbox.value != this.promptMessage){ + this.updateClass("Invalid"); + }else{ + this.updateClass("Empty"); + } + }, + + onfocus: function(evt) { + if ( !this.listenOnKeyPress) { + this.updateClass("Empty"); +// this.textbox.style.backgroundColor = ""; + } + }, + + onblur: function(evt) { + this.filter(); + this.update(); + }, + + onkeyup: function(evt){ + if(this.listenOnKeyPress){ + //this.filter(); trim is problem if you have to type two words + this.update(); + }else if (this.textbox.value != this.lastCheckedValue){ + this.updateClass("Empty"); +// this.textbox.style.backgroundColor = ""; + } + }, + + postMixInProperties: function(localProperties, frag) { + dojo.widget.ValidationTextbox.superclass.postMixInProperties.apply(this, arguments); + this.messages = dojo.i18n.getLocalization("dojo.widget", "validate", this.lang); + dojo.lang.forEach(["invalidMessage", "missingMessage", "rangeMessage"], function(prop) { + if(this[prop]){ this.messages[prop] = this[prop]; } + }, this); + }, + + fillInTemplate: function() { + dojo.widget.ValidationTextbox.superclass.fillInTemplate.apply(this, arguments); + + // Attach isMissing and isValid methods to the textbox. + // We may use them later in connection with a submit button widget. + // TODO: this is unorthodox; it seems better to do it another way -- Bill + this.textbox.isValid = function() { this.isValid.call(this); }; + this.textbox.isMissing = function() { this.isMissing.call(this); }; + this.textbox.isInRange = function() { this.isInRange.call(this); }; + dojo.html.setClass(this.invalidSpan,this.invalidClass); + this.update(); + + // apply any filters to initial value + this.filter(); + + // set table to be inlined (technique varies by browser) + // TODO: use method in dojo.html that does this + if(dojo.render.html.ie){ dojo.html.addClass(this.domNode, "ie"); } + if(dojo.render.html.moz){ dojo.html.addClass(this.domNode, "moz"); } + if(dojo.render.html.opera){ dojo.html.addClass(this.domNode, "opera"); } + if(dojo.render.html.safari){ dojo.html.addClass(this.domNode, "safari"); } + } + } +); Propchange: ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/ValidationTextbox.js ------------------------------------------------------------------------------ svn:eol-style = native Propchange: ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/ValidationTextbox.js ------------------------------------------------------------------------------ svn:keywords = "Date Rev Author URL Id" Propchange: ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/ValidationTextbox.js ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/Widget.js URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/Widget.js?view=auto&rev=509273 ============================================================================== --- ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/Widget.js (added) +++ ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/Widget.js Mon Feb 19 09:56:06 2007 @@ -0,0 +1,761 @@ +/* + Copyright (c) 2004-2006, The Dojo Foundation + All Rights Reserved. + + Licensed under the Academic Free License version 2.1 or above OR the + modified BSD license. For more information on Dojo licensing, see: + + http://dojotoolkit.org/community/licensing.shtml +*/ + +dojo.provide("dojo.widget.Widget"); + +dojo.require("dojo.lang.func"); +dojo.require("dojo.lang.array"); +dojo.require("dojo.lang.extras"); +dojo.require("dojo.lang.declare"); +dojo.require("dojo.ns"); +dojo.require("dojo.widget.Manager"); +dojo.require("dojo.event.*"); +dojo.require("dojo.a11y"); + +dojo.declare("dojo.widget.Widget", null, + function(){ + // these properties aren't primitives and need to be created on a per-item + // basis. + + // children: Array + // a list of all of the widgets that have been added as children of + // this component. Should only have values if isContainer is true. + this.children = []; + + // extraArgs: Object + // a map of properties which the widget system tried to assign from + // user input but did not correspond to any of the properties set on + // the class prototype. These names will also be available in all + // lower-case form in this map + this.extraArgs = {}; + }, +{ + // parent: Widget + // the parent of this widget + parent: null, + + // isTopLevel: Boolean + // should this widget eat all events that bubble up to it? + // obviously, top-level and modal widgets should set these appropriately + isTopLevel: false, + + // disabled: Boolean + // should this widget respond to user input? + // in markup, this is specified as "disabled='disabled'", or just "disabled" + disabled: false, + + // isContainer: Boolean + // can this widget contain other widgets? + isContainer: false, + + // widgetId: String + // a unique, opaque ID string that can be assigned by users or by the + // system. If the developer passes an ID which is known not to be + // unique, the specified ID is ignored and the system-generated ID is + // used instead. + widgetId: "", + + // widgetType: String + // used for building generic widgets + widgetType: "Widget", + + // ns: String + // defaults to 'dojo'. "namespace" is a reserved word in JavaScript, so we abbreviate + ns: "dojo", + + getNamespacedType: function(){ + // summary: + // get the "full" name of the widget. If the widget comes from the + // "dojo" namespace and is a Button, calling this method will + // return "dojo:button", all lower-case + return (this.ns ? this.ns + ":" + this.widgetType : this.widgetType).toLowerCase(); // String + }, + + toString: function(){ + // summary: + // returns a string that represents the widget. When a widget is + // cast to a string, this method will be used to generate the + // output. Currently, it does not implement any sort of reversable + // serialization. + return '[Widget ' + this.getNamespacedType() + ', ' + (this.widgetId || 'NO ID') + ']'; // String + }, + + repr: function(){ + // summary: returns the string representation of the widget. + return this.toString(); // String + }, + + enable: function(){ + // summary: + // enables the widget, usually involving unmasking inputs and + // turning on event handlers. Not implemented here. + this.disabled = false; + }, + + disable: function(){ + // summary: + // disables the widget, usually involves masking inputs and + // unsetting event handlers. Not implemented here. + this.disabled = true; + }, + + // TODO: + // 1) this would be better in HtmlWidget rather than here? + // 2) since many widgets don't care if they've been resized, maybe this should be a mixin? + onResized: function(){ + // summary: + // A signal that widgets will call when they have been resized. + // Can be connected to for determining if a layout needs to be + // reflowed. Clients should override this function to do special + // processing, then call this.notifyChildrenOfResize() to notify + // children of resize. + this.notifyChildrenOfResize(); + }, + + notifyChildrenOfResize: function(){ + // summary: dispatches resized events to all children of this widget + for(var i=0; i<this.children.length; i++){ + var child = this.children[i]; + //dojo.debug(this.widgetId + " resizing child " + child.widgetId); + if( child.onResized ){ + child.onResized(); + } + } + }, + + create: function(args, fragment, parent, ns){ + // summary: + // 'create' manages the initialization part of the widget + // lifecycle. It's called implicitly when any widget is created. + // All other initialization functions for widgets, except for the + // constructor, are called as a result of 'create' being fired. + // args: Object + // a normalized view of the parameters that the widget should take + // fragment: Object + // if the widget is being instantiated from markup, this object + // parent: Widget? + // the widget, if any, that this widget will be the child of. If + // none is passed, the global default widget is used. + // ns: String? + // what namespace the widget belongs to + // description: + // to understand the process by which widgets are instantiated, it + // is critical to understand what other methods 'create' calls and + // which of them you'll want to over-ride. Of course, adventurous + // developers could over-ride 'create' entirely, but this should + // only be done as a last resort. + // + // Below is a list of the methods that are called, in the order + // they are fired, along with notes about what they do and if/when + // you should over-ride them in your widget: + // + // mixInProperties: + // takes the args and does lightweight type introspection + // on pre-existing object properties to initialize widget + // values by casting the values that are passed in args + // postMixInProperties: + // a stub function that you can over-ride to modify + // variables that may have been naively assigned by + // mixInProperties + // # widget is added to manager object here + // buildRendering + // subclasses use this method to handle all UI initialization + // initialize: + // a stub function that you can over-ride. + // postInitialize: + // a stub function that you can over-ride. + // postCreate + // a stub function that you can over-ride to modify take + // actions once the widget has been placed in the UI + // + // all of these functions are passed the same arguments as are + // passed to 'create' + + //dojo.profile.start(this.widgetType + " create"); + if(ns){ + this.ns = ns; + } + // dojo.debug(this.widgetType, "create"); + //dojo.profile.start(this.widgetType + " satisfyPropertySets"); + this.satisfyPropertySets(args, fragment, parent); + //dojo.profile.end(this.widgetType + " satisfyPropertySets"); + // dojo.debug(this.widgetType, "-> mixInProperties"); + //dojo.profile.start(this.widgetType + " mixInProperties"); + this.mixInProperties(args, fragment, parent); + //dojo.profile.end(this.widgetType + " mixInProperties"); + // dojo.debug(this.widgetType, "-> postMixInProperties"); + //dojo.profile.start(this.widgetType + " postMixInProperties"); + this.postMixInProperties(args, fragment, parent); + //dojo.profile.end(this.widgetType + " postMixInProperties"); + // dojo.debug(this.widgetType, "-> dojo.widget.manager.add"); + dojo.widget.manager.add(this); + // dojo.debug(this.widgetType, "-> buildRendering"); + //dojo.profile.start(this.widgetType + " buildRendering"); + this.buildRendering(args, fragment, parent); + //dojo.profile.end(this.widgetType + " buildRendering"); + // dojo.debug(this.widgetType, "-> initialize"); + //dojo.profile.start(this.widgetType + " initialize"); + this.initialize(args, fragment, parent); + //dojo.profile.end(this.widgetType + " initialize"); + // dojo.debug(this.widgetType, "-> postInitialize"); + // postinitialize includes subcomponent creation + // profile is put directly to function + this.postInitialize(args, fragment, parent); + // dojo.debug(this.widgetType, "-> postCreate"); + //dojo.profile.start(this.widgetType + " postCreate"); + this.postCreate(args, fragment, parent); + //dojo.profile.end(this.widgetType + " postCreate"); + // dojo.debug(this.widgetType, "done!"); + + //dojo.profile.end(this.widgetType + " create"); + + return this; + }, + + destroy: function(finalize){ + // summary: + // Destroy this widget and it's descendants. This is the generic + // "destructor" function that all widget users should call to + // clealy discard with a widget. Once a widget is destroyed, it's + // removed from the manager object. + // finalize: Boolean + // is this function being called part of global environment + // tear-down? + + // FIXME: this is woefully incomplete + if(this.parent){ + this.parent.removeChild(this); + } + this.destroyChildren(); + this.uninitialize(); + this.destroyRendering(finalize); + dojo.widget.manager.removeById(this.widgetId); + }, + + destroyChildren: function(){ + // summary: + // Recursively destroy the children of this widget and their + // descendents. + var widget; + var i=0; + while(this.children.length > i){ + widget = this.children[i]; + if (widget instanceof dojo.widget.Widget) { // find first widget + this.removeChild(widget); + widget.destroy(); + continue; + } + + i++; // skip data object + } + + }, + + getChildrenOfType: function(/*String*/type, recurse){ + // summary: + // return an array of descendant widgets who match the passed type + // recurse: Boolean + // should we try to get all descendants that match? Defaults to + // false. + var ret = []; + var isFunc = dojo.lang.isFunction(type); + if(!isFunc){ + type = type.toLowerCase(); + } + for(var x=0; x<this.children.length; x++){ + if(isFunc){ + if(this.children[x] instanceof type){ + ret.push(this.children[x]); + } + }else{ + if(this.children[x].widgetType.toLowerCase() == type){ + ret.push(this.children[x]); + } + } + if(recurse){ + ret = ret.concat(this.children[x].getChildrenOfType(type, recurse)); + } + } + return ret; // Array + }, + + getDescendants: function(){ + // returns: a flattened array of all direct descendants including self + var result = []; + var stack = [this]; + var elem; + while ((elem = stack.pop())){ + result.push(elem); + // a child may be data object without children field set (not widget) + if (elem.children) { + dojo.lang.forEach(elem.children, function(elem) { stack.push(elem); }); + } + } + return result; // Array + }, + + + isFirstChild: function(){ + return this === this.parent.children[0]; // Boolean + }, + + isLastChild: function() { + return this === this.parent.children[this.parent.children.length-1]; // Boolean + }, + + satisfyPropertySets: function(args){ + // summary: not implemented! + + // dojo.profile.start("satisfyPropertySets"); + // get the default propsets for our component type + /* + var typePropSets = []; // FIXME: need to pull these from somewhere! + var localPropSets = []; // pull out propsets from the parser's return structure + + // for(var x=0; x<args.length; x++){ + // } + + for(var x=0; x<typePropSets.length; x++){ + } + + for(var x=0; x<localPropSets.length; x++){ + } + */ + // dojo.profile.end("satisfyPropertySets"); + + return args; + }, + + mixInProperties: function(args, /*Object*/frag){ + // summary: + // takes the list of properties listed in args and sets values of + // the current object based on existence of properties with the + // same name (case insensitive) and the type of the pre-existing + // property. This is a lightweight conversion and is not intended + // to capture custom type semantics. + // args: Object + // A map of properties and values to set on the current object. By + // default it is assumed that properties in args are in string + // form and need to be converted. However, if there is a + // 'fastMixIn' property with the value 'true' in the args param, + // this assumption is ignored and all values in args are copied + // directly to the current object without any form of type + // casting. + // description: + // The mix-in code attempts to do some type-assignment based on + // PRE-EXISTING properties of the "this" object. When a named + // property of args is located, it is first tested to make + // sure that the current object already "has one". Properties + // which are undefined in the base widget are NOT settable here. + // The next step is to try to determine type of the pre-existing + // property. If it's a string, the property value is simply + // assigned. If a function, it is first cast using "new + // Function()" and the execution scope modified such that it + // always evaluates in the context of the current object. This + // listener is then added to the original function via + // dojo.event.connect(). If an Array, the system attempts to split + // the string value on ";" chars, and no further processing is + // attempted (conversion of array elements to a integers, for + // instance). If the property value is an Object + // (testObj.constructor === Object), the property is split first + // on ";" chars, secondly on ":" chars, and the resulting + // key/value pairs are assigned to an object in a map style. The + // onus is on the property user to ensure that all property values + // are converted to the expected type before usage. Properties + // which do not occur in the "this" object are assigned to the + // this.extraArgs map using both the original name and the + // lower-case name of the property. This allows for consistent + // access semantics regardless of the case preservation of the + // source of the property names. + + if((args["fastMixIn"])||(frag["fastMixIn"])){ + // dojo.profile.start("mixInProperties_fastMixIn"); + // fast mix in assumes case sensitivity, no type casting, etc... + // dojo.lang.mixin(this, args); + for(var x in args){ + this[x] = args[x]; + } + // dojo.profile.end("mixInProperties_fastMixIn"); + return; + } + // dojo.profile.start("mixInProperties"); + + var undef; + + // NOTE: we cannot assume that the passed properties are case-correct + // (esp due to some browser bugs). Therefore, we attempt to locate + // properties for assignment regardless of case. This may cause + // problematic assignments and bugs in the future and will need to be + // documented with big bright neon lights. + + // FIXME: fails miserably if a mixin property has a default value of null in + // a widget + + // NOTE: caching lower-cased args in the prototype is only + // acceptable if the properties are invariant. + // if we have a name-cache, get it + var lcArgs = dojo.widget.lcArgsCache[this.widgetType]; + if ( lcArgs == null ){ + // build a lower-case property name cache if we don't have one + lcArgs = {}; + for(var y in this){ + lcArgs[((new String(y)).toLowerCase())] = y; + } + dojo.widget.lcArgsCache[this.widgetType] = lcArgs; + } + var visited = {}; + for(var x in args){ + if(!this[x]){ // check the cache for properties + var y = lcArgs[(new String(x)).toLowerCase()]; + if(y){ + args[y] = args[x]; + x = y; + } + } + if(visited[x]){ continue; } + visited[x] = true; + if((typeof this[x]) != (typeof undef)){ + if(typeof args[x] != "string"){ + this[x] = args[x]; + }else{ + if(dojo.lang.isString(this[x])){ + this[x] = args[x]; + }else if(dojo.lang.isNumber(this[x])){ + this[x] = new Number(args[x]); // FIXME: what if NaN is the result? + }else if(dojo.lang.isBoolean(this[x])){ + this[x] = (args[x].toLowerCase()=="false") ? false : true; + }else if(dojo.lang.isFunction(this[x])){ + + // FIXME: need to determine if always over-writing instead + // of attaching here is appropriate. I suspect that we + // might want to only allow attaching w/ action items. + + // RAR, 1/19/05: I'm going to attach instead of + // over-write here. Perhaps function objects could have + // some sort of flag set on them? Or mixed-into objects + // could have some list of non-mutable properties + // (although I'm not sure how that would alleviate this + // particular problem)? + + // this[x] = new Function(args[x]); + + // after an IRC discussion last week, it was decided + // that these event handlers should execute in the + // context of the widget, so that the "this" pointer + // takes correctly. + + // argument that contains no punctuation other than . is + // considered a function spec, not code + if(args[x].search(/[^\w\.]+/i) == -1){ + this[x] = dojo.evalObjPath(args[x], false); + }else{ + var tn = dojo.lang.nameAnonFunc(new Function(args[x]), this); + dojo.event.kwConnect({ + srcObj: this, + srcFunc: x, + adviceObj: this, + adviceFunc: tn + }); + } + }else if(dojo.lang.isArray(this[x])){ // typeof [] == "object" + this[x] = args[x].split(";"); + } else if (this[x] instanceof Date) { + this[x] = new Date(Number(args[x])); // assume timestamp + }else if(typeof this[x] == "object"){ + // FIXME: should we be allowing extension here to handle + // other object types intelligently? + + // if a plain string is passed to a property of type dojo.uri.Uri, + // we assume it is relative to root of dojo + if (this[x] instanceof dojo.uri.Uri){ + this[x] = dojo.uri.dojoUri(args[x]); + }else{ + // FIXME: unlike all other types, we do not replace the + // object with a new one here. Should we change that? + var pairs = args[x].split(";"); + for(var y=0; y<pairs.length; y++){ + var si = pairs[y].indexOf(":"); + if((si != -1)&&(pairs[y].length>si)){ + this[x][pairs[y].substr(0, si).replace(/^\s+|\s+$/g, "")] = pairs[y].substr(si+1); + } + } + } + }else{ + // the default is straight-up string assignment. When would + // we ever hit this? + this[x] = args[x]; + } + } + }else{ + // collect any extra 'non mixed in' args + this.extraArgs[x.toLowerCase()] = args[x]; + } + } + // dojo.profile.end("mixInProperties"); + }, + + postMixInProperties: function(/*Object*/args, /*Object*/frag, /*Widget*/parent){ + // summary + // Called after the parameters to the widget have been read-in, + // but before the widget template is instantiated. + // Especially useful to set properties that are referenced in the widget template. + }, + + initialize: function(/*Object*/args, /*Object*/frag, /*Widget*/parent){ + // summary: stub function. + return false; + // dojo.unimplemented("dojo.widget.Widget.initialize"); + }, + + postInitialize: function(/*Object*/args, /*Object*/frag, /*Widget*/parent){ + // summary: stub function. + return false; + }, + + postCreate: function(/*Object*/args, /*Object*/frag, /*Widget*/parent){ + // summary: stub function. + return false; + }, + + uninitialize: function(){ + // summary: + // stub function. Over-ride to implement custom widget tear-down + // behavior. + return false; + }, + + buildRendering: function(/*Object*/args, /*Object*/frag, /*Widget*/parent){ + // summary: stub function. SUBCLASSES MUST IMPLEMENT + dojo.unimplemented("dojo.widget.Widget.buildRendering, on "+this.toString()+", "); + return false; + }, + + destroyRendering: function(){ + // summary: stub function. SUBCLASSES MUST IMPLEMENT + dojo.unimplemented("dojo.widget.Widget.destroyRendering"); + return false; + }, + + addedTo: function(parent){ + // summary: + // stub function this is just a signal that can be caught + // parent: Widget + // instance of dojo.widget.Widget that we were added to + }, + + addChild: function(child){ + // summary: stub function. SUBCLASSES MUST IMPLEMENT + dojo.unimplemented("dojo.widget.Widget.addChild"); + return false; + }, + + // Detach the given child widget from me, but don't destroy it + removeChild: function(/*Widget*/widget){ + // summary: + // removes the passed widget instance from this widget but does + // not destroy it + for(var x=0; x<this.children.length; x++){ + if(this.children[x] === widget){ + this.children.splice(x, 1); + widget.parent=null; + break; + } + } + return widget; // Widget + }, + + getPreviousSibling: function(){ + // summary: + // returns null if this is the first child of the parent, + // otherwise returns the next sibling to the "left". + var idx = this.getParentIndex(); + + // first node is idx=0 not found is idx<0 + if (idx<=0) return null; + + return this.parent.children[idx-1]; // Widget + }, + + getSiblings: function(){ + // summary: gets an array of all children of our parent, including "this" + return this.parent.children; // Array + }, + + getParentIndex: function(){ + // summary: what index are we at in the parent's children array? + return dojo.lang.indexOf(this.parent.children, this, true); // int + }, + + getNextSibling: function(){ + // summary: + // returns null if this is the last child of the parent, + // otherwise returns the next sibling to the "right". + + var idx = this.getParentIndex(); + + if (idx == this.parent.children.length-1){return null;} // last node + if (idx < 0){return null;} // not found + + return this.parent.children[idx+1]; // Widget + } +}); + +// Lower case name cache: listing of the lower case elements in each widget. +// We can't store the lcArgs in the widget itself because if B subclasses A, +// then B.prototype.lcArgs might return A.prototype.lcArgs, which is not what we +// want +dojo.widget.lcArgsCache = {}; + +// TODO: should have a more general way to add tags or tag libraries? +// TODO: need a default tags class to inherit from for things like getting propertySets +// TODO: parse properties/propertySets into component attributes +// TODO: parse subcomponents +// TODO: copy/clone raw markup fragments/nodes as appropriate +dojo.widget.tags = {}; +dojo.widget.tags.addParseTreeHandler = function(/*String*/type){ + // summary: deprecated! + dojo.deprecated("addParseTreeHandler", ". ParseTreeHandlers are now reserved for components. Any unfiltered DojoML tag without a ParseTreeHandler is assumed to be a widget", "0.5"); + /* + var ltype = type.toLowerCase(); + this[ltype] = function(fragment, widgetParser, parentComp, insertionIndex, localProps){ + var _ltype = ltype; + dojo.profile.start(_ltype); + var n = dojo.widget.buildWidgetFromParseTree(ltype, fragment, widgetParser, parentComp, insertionIndex, localProps); + dojo.profile.end(_ltype); + return n; + } + */ +} + +//dojo.widget.tags.addParseTreeHandler("dojo:widget"); + +dojo.widget.tags["dojo:propertyset"] = function(fragment, widgetParser, parentComp){ + // FIXME: Is this needed? + // FIXME: Not sure that this parses into the structure that I want it to parse into... + // FIXME: add support for nested propertySets + var properties = widgetParser.parseProperties(fragment["dojo:propertyset"]); +} + +// FIXME: need to add the <dojo:connect /> +dojo.widget.tags["dojo:connect"] = function(fragment, widgetParser, parentComp){ + var properties = widgetParser.parseProperties(fragment["dojo:connect"]); +} + +// FIXME: if we know the insertion point (to a reasonable location), why then do we: +// - create a template node +// - clone the template node +// - render the clone and set properties +// - remove the clone from the render tree +// - place the clone +// this is quite dumb +dojo.widget.buildWidgetFromParseTree = function(/*String*/ type, + /*Object*/ frag, + /*dojo.widget.Parse*/ parser, + /*Widget, optional*/ parentComp, + /*int, optional*/ insertionIndex, + /*Object*/ localProps){ + + // summary: creates a tree of widgets from the data structure produced by the first-pass parser (frag) + + // test for accessibility mode + dojo.a11y.setAccessibleMode(); + //dojo.profile.start("buildWidgetFromParseTree"); + // FIXME: for codepath from createComponentFromScript, we are now splitting a path + // that we already split and then joined + var stype = type.split(":"); + stype = (stype.length == 2) ? stype[1] : type; + + // FIXME: we don't seem to be doing anything with this! + // var propertySets = parser.getPropertySets(frag); + var localProperties = localProps || parser.parseProperties(frag[frag["ns"]+":"+stype]); + var twidget = dojo.widget.manager.getImplementation(stype,null,null,frag["ns"]); + if(!twidget){ + throw new Error('cannot find "' + type + '" widget'); + }else if (!twidget.create){ + throw new Error('"' + type + '" widget object has no "create" method and does not appear to implement *Widget'); + } + localProperties["dojoinsertionindex"] = insertionIndex; + // FIXME: we lose no less than 5ms in construction! + var ret = twidget.create(localProperties, frag, parentComp, frag["ns"]); + // dojo.profile.end("buildWidgetFromParseTree"); + return ret; +} + +dojo.widget.defineWidget = function(widgetClass, renderer, superclasses, init, props){ + // summary: Create a widget constructor function (aka widgetClass) + // widgetClass: String + // the location in the object hierarchy to place the new widget class constructor + // renderer: String + // usually "html", determines when this delcaration will be used + // superclasses: Function||Function[] + // can be either a single function or an array of functions to be + // mixed in as superclasses. If an array, only the first will be used + // to set prototype inheritance. + // init: Function + // an optional constructor function. Will be called after superclasses are mixed in. + // props: Object + // a map of properties and functions to extend the class prototype with + + // This meta-function does parameter juggling for backward compat and overloading + // if 4th argument is a string, we are using the old syntax + // old sig: widgetClass, superclasses, props (object), renderer (string), init (function) + if(dojo.lang.isString(arguments[3])){ + dojo.widget._defineWidget(arguments[0], arguments[3], arguments[1], arguments[4], arguments[2]); + }else{ + // widgetClass + var args = [ arguments[0] ], p = 3; + if(dojo.lang.isString(arguments[1])){ + // renderer, superclass + args.push(arguments[1], arguments[2]); + }else{ + // superclass + args.push('', arguments[1]); + p = 2; + } + if(dojo.lang.isFunction(arguments[p])){ + // init (function), props (object) + args.push(arguments[p], arguments[p+1]); + }else{ + // props (object) + args.push(null, arguments[p]); + } + dojo.widget._defineWidget.apply(this, args); + } +} + +dojo.widget.defineWidget.renderers = "html|svg|vml"; + +dojo.widget._defineWidget = function(widgetClass /*string*/, renderer /*string*/, superclasses /*function||array*/, init /*function*/, props /*object*/){ + // FIXME: uncomment next line to test parameter juggling ... remove when confidence improves + // dojo.debug('(c:)' + widgetClass + '\n\n(r:)' + renderer + '\n\n(i:)' + init + '\n\n(p:)' + props); + // widgetClass takes the form foo.bar.baz<.renderer>.WidgetName (e.g. foo.bar.baz.WidgetName or foo.bar.baz.html.WidgetName) + var module = widgetClass.split("."); + var type = module.pop(); // type <= WidgetName, module <= foo.bar.baz<.renderer> + var regx = "\\.(" + (renderer ? renderer + '|' : '') + dojo.widget.defineWidget.renderers + ")\\."; + var r = widgetClass.search(new RegExp(regx)); + module = (r < 0 ? module.join(".") : widgetClass.substr(0, r)); + + // deprecated in favor of namespace system, remove for 0.5 + dojo.widget.manager.registerWidgetPackage(module); + + var pos = module.indexOf("."); + var nsName = (pos > -1) ? module.substring(0,pos) : module; + + // FIXME: hrm, this might make things simpler + //dojo.widget.tags.addParseTreeHandler(nsName+":"+type.toLowerCase()); + + props=(props)||{}; + props.widgetType = type; + if((!init)&&(props["classConstructor"])){ + init = props.classConstructor; + delete props.classConstructor; + } + dojo.declare(widgetClass, superclasses, init, props); +} Propchange: ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/Widget.js ------------------------------------------------------------------------------ svn:eol-style = native Propchange: ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/Widget.js ------------------------------------------------------------------------------ svn:keywords = "Date Rev Author URL Id" Propchange: ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/Widget.js ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/Wizard.js URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/Wizard.js?view=auto&rev=509273 ============================================================================== --- ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/Wizard.js (added) +++ ofbiz/trunk/framework/images/webapp/images/dojo/src/widget/Wizard.js Mon Feb 19 09:56:06 2007 @@ -0,0 +1,233 @@ +/* + Copyright (c) 2004-2006, The Dojo Foundation + All Rights Reserved. + + Licensed under the Academic Free License version 2.1 or above OR the + modified BSD license. For more information on Dojo licensing, see: + + http://dojotoolkit.org/community/licensing.shtml +*/ + +dojo.provide("dojo.widget.Wizard"); + +dojo.require("dojo.widget.*"); +dojo.require("dojo.widget.LayoutContainer"); +dojo.require("dojo.widget.ContentPane"); +dojo.require("dojo.event.*"); +dojo.require("dojo.html.style"); + +// TODO: base this on PageContainer +dojo.widget.defineWidget( + "dojo.widget.WizardContainer", + dojo.widget.LayoutContainer, +{ + // summary + // A set of panels that display sequentially, typically notating a step-by-step + // procedure like an install + + templatePath: dojo.uri.dojoUri("src/widget/templates/Wizard.html"), + templateCssPath: dojo.uri.dojoUri("src/widget/templates/Wizard.css"), + + // selected: DomNode + // Currently selected panel. (Read-only) + selected: null, + + // nextButtonLabel: String + // Label for the "Next" button. + nextButtonLabel: "next", + + // previousButtonLabel: String + // Label for the "Previous" button. + previousButtonLabel: "previous", + + // cancelButtonLabel: String + // Label for the "Cancel" button. + cancelButtonLabel: "cancel", + + // doneButtonLabel: String + // Label for the "Done" button. + doneButtonLabel: "done", + + // cancelButtonLabel: FunctionName + // Name of function to call if user presses cancel button. + // Cancel button is not displayed if function is not specified. + cancelFunction: "", + + // hideDisabledButtons: Boolean + // If true, disabled buttons are hidden; otherwise, they are assigned the + // "WizardButtonDisabled" CSS class + hideDisabledButtons: false, + + fillInTemplate: function(args, frag){ + dojo.event.connect(this.nextButton, "onclick", this, "_onNextButtonClick"); + dojo.event.connect(this.previousButton, "onclick", this, "_onPreviousButtonClick"); + if (this.cancelFunction){ + dojo.event.connect(this.cancelButton, "onclick", this.cancelFunction); + }else{ + this.cancelButton.style.display = "none"; + } + dojo.event.connect(this.doneButton, "onclick", this, "done"); + this.nextButton.value = this.nextButtonLabel; + this.previousButton.value = this.previousButtonLabel; + this.cancelButton.value = this.cancelButtonLabel; + this.doneButton.value = this.doneButtonLabel; + }, + + _checkButtons: function(){ + |
Free forum by Nabble | Edit this page |