diff options
author | Andrew Dolgov <[email protected]> | 2011-11-08 20:40:44 +0400 |
---|---|---|
committer | Andrew Dolgov <[email protected]> | 2011-11-08 20:40:44 +0400 |
commit | 81bea17aefb26859f825b9293c7c99192874806e (patch) | |
tree | fb244408ca271affa2899adb634788802c9a89d8 /lib/dijit/_WidgetBase.js | |
parent | 870a70e109ac9e80a88047044530de53d0404ec7 (diff) |
upgrade Dojo to 1.6.1
Diffstat (limited to 'lib/dijit/_WidgetBase.js')
-rw-r--r-- | lib/dijit/_WidgetBase.js | 826 |
1 files changed, 826 insertions, 0 deletions
diff --git a/lib/dijit/_WidgetBase.js b/lib/dijit/_WidgetBase.js new file mode 100644 index 000000000..868ce6a91 --- /dev/null +++ b/lib/dijit/_WidgetBase.js @@ -0,0 +1,826 @@ +/* + Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved. + Available via Academic Free License >= 2.1 OR the modified BSD license. + see: http://dojotoolkit.org/license for details +*/ + + +if(!dojo._hasResource["dijit._WidgetBase"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. +dojo._hasResource["dijit._WidgetBase"] = true; +dojo.provide("dijit._WidgetBase"); +dojo.require("dijit._base.manager"); +dojo.require("dojo.Stateful"); + + +(function(){ + +dojo.declare("dijit._WidgetBase", dojo.Stateful, { + // summary: + // Future base class for all Dijit widgets. + // _Widget extends this class adding support for various features needed by desktop. + + // id: [const] 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. + id: "", + + // lang: [const] String + // Rarely used. Overrides the default Dojo locale used to render this widget, + // as defined by the [HTML LANG](http://www.w3.org/TR/html401/struct/dirlang.html#adef-lang) attribute. + // Value must be among the list of locales specified during by the Dojo bootstrap, + // formatted according to [RFC 3066](http://www.ietf.org/rfc/rfc3066.txt) (like en-us). + lang: "", + + // dir: [const] String + // Bi-directional support, as defined by the [HTML DIR](http://www.w3.org/TR/html401/struct/dirlang.html#adef-dir) + // attribute. Either left-to-right "ltr" or right-to-left "rtl". If undefined, widgets renders in page's + // default direction. + dir: "", + + // class: String + // HTML class attribute + "class": "", + + // style: String||Object + // HTML style attributes as cssText string or name/value hash + style: "", + + // title: String + // HTML title attribute. + // + // For form widgets this specifies a tooltip to display when hovering over + // the widget (just like the native HTML title attribute). + // + // For TitlePane or for when this widget is a child of a TabContainer, AccordionContainer, + // etc., it's used to specify the tab label, accordion pane title, etc. + title: "", + + // tooltip: String + // When this widget's title attribute is used to for a tab label, accordion pane title, etc., + // this specifies the tooltip to appear when the mouse is hovered over that text. + tooltip: "", + + // baseClass: [protected] String + // Root CSS class of the widget (ex: dijitTextBox), used to construct CSS classes to indicate + // widget state. + baseClass: "", + + // srcNodeRef: [readonly] DomNode + // pointer to original DOM node + srcNodeRef: null, + + // domNode: [readonly] DomNode + // This is our visible representation of the widget! Other DOM + // Nodes may by assigned to other properties, usually through the + // template system's dojoAttachPoint syntax, but the domNode + // property is the canonical "top level" node in widget UI. + domNode: null, + + // containerNode: [readonly] DomNode + // Designates where children of the source DOM node will be placed. + // "Children" in this case refers to both DOM nodes and widgets. + // For example, for myWidget: + // + // | <div dojoType=myWidget> + // | <b> here's a plain DOM node + // | <span dojoType=subWidget>and a widget</span> + // | <i> and another plain DOM node </i> + // | </div> + // + // containerNode would point to: + // + // | <b> here's a plain DOM node + // | <span dojoType=subWidget>and a widget</span> + // | <i> and another plain DOM node </i> + // + // In templated widgets, "containerNode" is set via a + // dojoAttachPoint assignment. + // + // containerNode must be defined for any widget that accepts innerHTML + // (like ContentPane or BorderContainer or even Button), and conversely + // is null for widgets that don't, like TextBox. + containerNode: null, + +/*===== + // _started: Boolean + // startup() has completed. + _started: false, +=====*/ + + // attributeMap: [protected] Object + // attributeMap sets up a "binding" between attributes (aka properties) + // of the widget and the widget's DOM. + // Changes to widget attributes listed in attributeMap will be + // reflected into the DOM. + // + // For example, calling set('title', 'hello') + // on a TitlePane will automatically cause the TitlePane's DOM to update + // with the new title. + // + // attributeMap is a hash where the key is an attribute of the widget, + // and the value reflects a binding to a: + // + // - DOM node attribute + // | focus: {node: "focusNode", type: "attribute"} + // Maps this.focus to this.focusNode.focus + // + // - DOM node innerHTML + // | title: { node: "titleNode", type: "innerHTML" } + // Maps this.title to this.titleNode.innerHTML + // + // - DOM node innerText + // | title: { node: "titleNode", type: "innerText" } + // Maps this.title to this.titleNode.innerText + // + // - DOM node CSS class + // | myClass: { node: "domNode", type: "class" } + // Maps this.myClass to this.domNode.className + // + // If the value is an array, then each element in the array matches one of the + // formats of the above list. + // + // There are also some shorthands for backwards compatibility: + // - string --> { node: string, type: "attribute" }, for example: + // | "focusNode" ---> { node: "focusNode", type: "attribute" } + // - "" --> { node: "domNode", type: "attribute" } + attributeMap: {id:"", dir:"", lang:"", "class":"", style:"", title:""}, + + // _blankGif: [protected] String + // Path to a blank 1x1 image. + // Used by <img> nodes in templates that really get their image via CSS background-image. + _blankGif: (dojo.config.blankGif || dojo.moduleUrl("dojo", "resources/blank.gif")).toString(), + + //////////// INITIALIZATION METHODS /////////////////////////////////////// + + postscript: function(/*Object?*/params, /*DomNode|String*/srcNodeRef){ + // summary: + // Kicks off widget instantiation. See create() for details. + // tags: + // private + this.create(params, srcNodeRef); + }, + + create: function(/*Object?*/params, /*DomNode|String?*/srcNodeRef){ + // summary: + // Kick off the life-cycle of a widget + // params: + // Hash of initialization parameters for widget, including + // scalar values (like title, duration etc.) and functions, + // typically callbacks like onClick. + // srcNodeRef: + // If a srcNodeRef (DOM node) is specified: + // - use srcNodeRef.innerHTML as my contents + // - if this is a behavioral widget then apply behavior + // to that srcNodeRef + // - otherwise, replace srcNodeRef with my generated DOM + // tree + // description: + // Create calls a number of widget methods (postMixInProperties, buildRendering, postCreate, + // etc.), some of which of you'll want to override. See http://docs.dojocampus.org/dijit/_Widget + // for a discussion of the widget creation lifecycle. + // + // Of course, adventurous developers could override create entirely, but this should + // only be done as a last resort. + // tags: + // private + + // store pointer to original DOM tree + this.srcNodeRef = dojo.byId(srcNodeRef); + + // For garbage collection. An array of handles returned by Widget.connect() + // Each handle returned from Widget.connect() is an array of handles from dojo.connect() + this._connects = []; + + // For garbage collection. An array of handles returned by Widget.subscribe() + // The handle returned from Widget.subscribe() is the handle returned from dojo.subscribe() + this._subscribes = []; + + // mix in our passed parameters + if(this.srcNodeRef && (typeof this.srcNodeRef.id == "string")){ this.id = this.srcNodeRef.id; } + if(params){ + this.params = params; + dojo._mixin(this, params); + } + this.postMixInProperties(); + + // generate an id for the widget if one wasn't specified + // (be sure to do this before buildRendering() because that function might + // expect the id to be there.) + if(!this.id){ + this.id = dijit.getUniqueId(this.declaredClass.replace(/\./g,"_")); + } + dijit.registry.add(this); + + this.buildRendering(); + + if(this.domNode){ + // Copy attributes listed in attributeMap into the [newly created] DOM for the widget. + // Also calls custom setters for all attributes with custom setters. + this._applyAttributes(); + + // If srcNodeRef was specified, then swap out original srcNode for this widget's DOM tree. + // For 2.0, move this after postCreate(). postCreate() shouldn't depend on the + // widget being attached to the DOM since it isn't when a widget is created programmatically like + // new MyWidget({}). See #11635. + var source = this.srcNodeRef; + if(source && source.parentNode && this.domNode !== source){ + source.parentNode.replaceChild(this.domNode, source); + } + } + + if(this.domNode){ + // Note: for 2.0 may want to rename widgetId to dojo._scopeName + "_widgetId", + // assuming that dojo._scopeName even exists in 2.0 + this.domNode.setAttribute("widgetId", this.id); + } + this.postCreate(); + + // If srcNodeRef has been processed and removed from the DOM (e.g. TemplatedWidget) then delete it to allow GC. + if(this.srcNodeRef && !this.srcNodeRef.parentNode){ + delete this.srcNodeRef; + } + + this._created = true; + }, + + _applyAttributes: function(){ + // summary: + // Step during widget creation to copy all widget attributes to the + // DOM as per attributeMap and _setXXXAttr functions. + // description: + // Skips over blank/false attribute values, unless they were explicitly specified + // as parameters to the widget, since those are the default anyway, + // and setting tabIndex="" is different than not setting tabIndex at all. + // + // It processes the attributes in the attribute map first, and then + // it goes through and processes the attributes for the _setXXXAttr + // functions that have been specified + // tags: + // private + var condAttrApply = function(attr, scope){ + if((scope.params && attr in scope.params) || scope[attr]){ + scope.set(attr, scope[attr]); + } + }; + + // Do the attributes in attributeMap + for(var attr in this.attributeMap){ + condAttrApply(attr, this); + } + + // And also any attributes with custom setters + dojo.forEach(this._getSetterAttributes(), function(a){ + if(!(a in this.attributeMap)){ + condAttrApply(a, this); + } + }, this); + }, + + _getSetterAttributes: function(){ + // summary: + // Returns list of attributes with custom setters for this widget + var ctor = this.constructor; + if(!ctor._setterAttrs){ + var r = (ctor._setterAttrs = []), + attrs, + proto = ctor.prototype; + for(var fxName in proto){ + if(dojo.isFunction(proto[fxName]) && (attrs = fxName.match(/^_set([a-zA-Z]*)Attr$/)) && attrs[1]){ + r.push(attrs[1].charAt(0).toLowerCase() + attrs[1].substr(1)); + } + } + } + return ctor._setterAttrs; // String[] + }, + + postMixInProperties: function(){ + // 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. + // tags: + // protected + }, + + buildRendering: function(){ + // summary: + // Construct the UI for this widget, setting this.domNode + // description: + // Most widgets will mixin `dijit._Templated`, which implements this + // method. + // tags: + // protected + + if(!this.domNode){ + // Create root node if it wasn't created by _Templated + this.domNode = this.srcNodeRef || dojo.create('div'); + } + + // baseClass is a single class name or occasionally a space-separated list of names. + // Add those classes to the DOMNode. If RTL mode then also add with Rtl suffix. + // TODO: make baseClass custom setter + if(this.baseClass){ + var classes = this.baseClass.split(" "); + if(!this.isLeftToRight()){ + classes = classes.concat( dojo.map(classes, function(name){ return name+"Rtl"; })); + } + dojo.addClass(this.domNode, classes); + } + }, + + postCreate: function(){ + // summary: + // Processing after the DOM fragment is created + // description: + // Called after the DOM fragment has been created, but not necessarily + // added to the document. Do not include any operations which rely on + // node dimensions or placement. + // tags: + // protected + }, + + startup: function(){ + // summary: + // Processing after the DOM fragment is added to the document + // description: + // Called after a widget and its children have been created and added to the page, + // and all related widgets have finished their create() cycle, up through postCreate(). + // This is useful for composite widgets that need to control or layout sub-widgets. + // Many layout widgets can use this as a wiring phase. + this._started = true; + }, + + //////////// DESTROY FUNCTIONS //////////////////////////////// + + destroyRecursive: function(/*Boolean?*/ preserveDom){ + // summary: + // Destroy this widget and its descendants + // description: + // This is the generic "destructor" function that all widget users + // should call to cleanly discard with a widget. Once a widget is + // destroyed, it is removed from the manager object. + // preserveDom: + // If true, this method will leave the original DOM structure + // alone of descendant Widgets. Note: This will NOT work with + // dijit._Templated widgets. + + this._beingDestroyed = true; + this.destroyDescendants(preserveDom); + this.destroy(preserveDom); + }, + + destroy: function(/*Boolean*/ preserveDom){ + // summary: + // Destroy this widget, but not its descendants. + // This method will, however, destroy internal widgets such as those used within a template. + // preserveDom: Boolean + // If true, this method will leave the original DOM structure alone. + // Note: This will not yet work with _Templated widgets + + this._beingDestroyed = true; + this.uninitialize(); + var d = dojo, + dfe = d.forEach, + dun = d.unsubscribe; + dfe(this._connects, function(array){ + dfe(array, d.disconnect); + }); + dfe(this._subscribes, function(handle){ + dun(handle); + }); + + // destroy widgets created as part of template, etc. + dfe(this._supportingWidgets || [], function(w){ + if(w.destroyRecursive){ + w.destroyRecursive(); + }else if(w.destroy){ + w.destroy(); + } + }); + + this.destroyRendering(preserveDom); + dijit.registry.remove(this.id); + this._destroyed = true; + }, + + destroyRendering: function(/*Boolean?*/ preserveDom){ + // summary: + // Destroys the DOM nodes associated with this widget + // preserveDom: + // If true, this method will leave the original DOM structure alone + // during tear-down. Note: this will not work with _Templated + // widgets yet. + // tags: + // protected + + if(this.bgIframe){ + this.bgIframe.destroy(preserveDom); + delete this.bgIframe; + } + + if(this.domNode){ + if(preserveDom){ + dojo.removeAttr(this.domNode, "widgetId"); + }else{ + dojo.destroy(this.domNode); + } + delete this.domNode; + } + + if(this.srcNodeRef){ + if(!preserveDom){ + dojo.destroy(this.srcNodeRef); + } + delete this.srcNodeRef; + } + }, + + destroyDescendants: function(/*Boolean?*/ preserveDom){ + // summary: + // Recursively destroy the children of this widget and their + // descendants. + // preserveDom: + // If true, the preserveDom attribute is passed to all descendant + // widget's .destroy() method. Not for use with _Templated + // widgets. + + // get all direct descendants and destroy them recursively + dojo.forEach(this.getChildren(), function(widget){ + if(widget.destroyRecursive){ + widget.destroyRecursive(preserveDom); + } + }); + }, + + uninitialize: function(){ + // summary: + // Stub function. Override to implement custom widget tear-down + // behavior. + // tags: + // protected + return false; + }, + + ////////////////// GET/SET, CUSTOM SETTERS, ETC. /////////////////// + + _setClassAttr: function(/*String*/ value){ + // summary: + // Custom setter for the CSS "class" attribute + // tags: + // protected + var mapNode = this[this.attributeMap["class"] || 'domNode']; + dojo.replaceClass(mapNode, value, this["class"]); + this._set("class", value); + }, + + _setStyleAttr: function(/*String||Object*/ value){ + // summary: + // Sets the style attribute of the widget according to value, + // which is either a hash like {height: "5px", width: "3px"} + // or a plain string + // description: + // Determines which node to set the style on based on style setting + // in attributeMap. + // tags: + // protected + + var mapNode = this[this.attributeMap.style || 'domNode']; + + // Note: technically we should revert any style setting made in a previous call + // to his method, but that's difficult to keep track of. + + if(dojo.isObject(value)){ + dojo.style(mapNode, value); + }else{ + if(mapNode.style.cssText){ + mapNode.style.cssText += "; " + value; + }else{ + mapNode.style.cssText = value; + } + } + + this._set("style", value); + }, + + _attrToDom: function(/*String*/ attr, /*String*/ value){ + // summary: + // Reflect a widget attribute (title, tabIndex, duration etc.) to + // the widget DOM, as specified in attributeMap. + // Note some attributes like "type" + // cannot be processed this way as they are not mutable. + // + // tags: + // private + + var commands = this.attributeMap[attr]; + dojo.forEach(dojo.isArray(commands) ? commands : [commands], function(command){ + + // Get target node and what we are doing to that node + var mapNode = this[command.node || command || "domNode"]; // DOM node + var type = command.type || "attribute"; // class, innerHTML, innerText, or attribute + + switch(type){ + case "attribute": + if(dojo.isFunction(value)){ // functions execute in the context of the widget + value = dojo.hitch(this, value); + } + + // Get the name of the DOM node attribute; usually it's the same + // as the name of the attribute in the widget (attr), but can be overridden. + // Also maps handler names to lowercase, like onSubmit --> onsubmit + var attrName = command.attribute ? command.attribute : + (/^on[A-Z][a-zA-Z]*$/.test(attr) ? attr.toLowerCase() : attr); + + dojo.attr(mapNode, attrName, value); + break; + case "innerText": + mapNode.innerHTML = ""; + mapNode.appendChild(dojo.doc.createTextNode(value)); + break; + case "innerHTML": + mapNode.innerHTML = value; + break; + case "class": + dojo.replaceClass(mapNode, value, this[attr]); + break; + } + }, this); + }, + + get: function(name){ + // summary: + // Get a property from a widget. + // name: + // The property to get. + // description: + // Get a named property from a widget. The property may + // potentially be retrieved via a getter method. If no getter is defined, this + // just retrieves the object's property. + // For example, if the widget has a properties "foo" + // and "bar" and a method named "_getFooAttr", calling: + // | myWidget.get("foo"); + // would be equivalent to writing: + // | widget._getFooAttr(); + // and: + // | myWidget.get("bar"); + // would be equivalent to writing: + // | widget.bar; + var names = this._getAttrNames(name); + return this[names.g] ? this[names.g]() : this[name]; + }, + + set: function(name, value){ + // summary: + // Set a property on a widget + // name: + // The property to set. + // value: + // The value to set in the property. + // description: + // Sets named properties on a widget which may potentially be handled by a + // setter in the widget. + // For example, if the widget has a properties "foo" + // and "bar" and a method named "_setFooAttr", calling: + // | myWidget.set("foo", "Howdy!"); + // would be equivalent to writing: + // | widget._setFooAttr("Howdy!"); + // and: + // | myWidget.set("bar", 3); + // would be equivalent to writing: + // | widget.bar = 3; + // + // set() may also be called with a hash of name/value pairs, ex: + // | myWidget.set({ + // | foo: "Howdy", + // | bar: 3 + // | }) + // This is equivalent to calling set(foo, "Howdy") and set(bar, 3) + + if(typeof name === "object"){ + for(var x in name){ + this.set(x, name[x]); + } + return this; + } + var names = this._getAttrNames(name); + if(this[names.s]){ + // use the explicit setter + var result = this[names.s].apply(this, Array.prototype.slice.call(arguments, 1)); + }else{ + // if param is specified as DOM node attribute, copy it + if(name in this.attributeMap){ + this._attrToDom(name, value); + } + this._set(name, value); + } + return result || this; + }, + + _attrPairNames: {}, // shared between all widgets + _getAttrNames: function(name){ + // summary: + // Helper function for get() and set(). + // Caches attribute name values so we don't do the string ops every time. + // tags: + // private + + var apn = this._attrPairNames; + if(apn[name]){ return apn[name]; } + var uc = name.charAt(0).toUpperCase() + name.substr(1); + return (apn[name] = { + n: name+"Node", + s: "_set"+uc+"Attr", + g: "_get"+uc+"Attr" + }); + }, + + _set: function(/*String*/ name, /*anything*/ value){ + // summary: + // Helper function to set new value for specified attribute, and call handlers + // registered with watch() if the value has changed. + var oldValue = this[name]; + this[name] = value; + if(this._watchCallbacks && this._created && value !== oldValue){ + this._watchCallbacks(name, oldValue, value); + } + }, + + toString: function(){ + // summary: + // Returns a string that represents the widget + // description: + // 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 reversible + // serialization. + return '[Widget ' + this.declaredClass + ', ' + (this.id || 'NO ID') + ']'; // String + }, + + getDescendants: function(){ + // summary: + // Returns all the widgets contained by this, i.e., all widgets underneath this.containerNode. + // This method should generally be avoided as it returns widgets declared in templates, which are + // supposed to be internal/hidden, but it's left here for back-compat reasons. + + return this.containerNode ? dojo.query('[widgetId]', this.containerNode).map(dijit.byNode) : []; // dijit._Widget[] + }, + + getChildren: function(){ + // summary: + // Returns all the widgets contained by this, i.e., all widgets underneath this.containerNode. + // Does not return nested widgets, nor widgets that are part of this widget's template. + return this.containerNode ? dijit.findWidgets(this.containerNode) : []; // dijit._Widget[] + }, + + connect: function( + /*Object|null*/ obj, + /*String|Function*/ event, + /*String|Function*/ method){ + // summary: + // Connects specified obj/event to specified method of this object + // and registers for disconnect() on widget destroy. + // description: + // Provide widget-specific analog to dojo.connect, except with the + // implicit use of this widget as the target object. + // Events connected with `this.connect` are disconnected upon + // destruction. + // returns: + // A handle that can be passed to `disconnect` in order to disconnect before + // the widget is destroyed. + // example: + // | var btn = new dijit.form.Button(); + // | // when foo.bar() is called, call the listener we're going to + // | // provide in the scope of btn + // | btn.connect(foo, "bar", function(){ + // | console.debug(this.toString()); + // | }); + // tags: + // protected + + var handles = [dojo._connect(obj, event, this, method)]; + this._connects.push(handles); + return handles; // _Widget.Handle + }, + + disconnect: function(/* _Widget.Handle */ handles){ + // summary: + // Disconnects handle created by `connect`. + // Also removes handle from this widget's list of connects. + // tags: + // protected + for(var i=0; i<this._connects.length; i++){ + if(this._connects[i] == handles){ + dojo.forEach(handles, dojo.disconnect); + this._connects.splice(i, 1); + return; + } + } + }, + + subscribe: function( + /*String*/ topic, + /*String|Function*/ method){ + // summary: + // Subscribes to the specified topic and calls the specified method + // of this object and registers for unsubscribe() on widget destroy. + // description: + // Provide widget-specific analog to dojo.subscribe, except with the + // implicit use of this widget as the target object. + // example: + // | var btn = new dijit.form.Button(); + // | // when /my/topic is published, this button changes its label to + // | // be the parameter of the topic. + // | btn.subscribe("/my/topic", function(v){ + // | this.set("label", v); + // | }); + var handle = dojo.subscribe(topic, this, method); + + // return handles for Any widget that may need them + this._subscribes.push(handle); + return handle; + }, + + unsubscribe: function(/*Object*/ handle){ + // summary: + // Unsubscribes handle created by this.subscribe. + // Also removes handle from this widget's list of subscriptions + for(var i=0; i<this._subscribes.length; i++){ + if(this._subscribes[i] == handle){ + dojo.unsubscribe(handle); + this._subscribes.splice(i, 1); + return; + } + } + }, + + isLeftToRight: function(){ + // summary: + // Return this widget's explicit or implicit orientation (true for LTR, false for RTL) + // tags: + // protected + return this.dir ? (this.dir == "ltr") : dojo._isBodyLtr(); //Boolean + }, + + placeAt: function(/* String|DomNode|_Widget */reference, /* String?|Int? */position){ + // summary: + // Place this widget's domNode reference somewhere in the DOM based + // on standard dojo.place conventions, or passing a Widget reference that + // contains and addChild member. + // + // description: + // A convenience function provided in all _Widgets, providing a simple + // shorthand mechanism to put an existing (or newly created) Widget + // somewhere in the dom, and allow chaining. + // + // reference: + // The String id of a domNode, a domNode reference, or a reference to a Widget posessing + // an addChild method. + // + // position: + // If passed a string or domNode reference, the position argument + // accepts a string just as dojo.place does, one of: "first", "last", + // "before", or "after". + // + // If passed a _Widget reference, and that widget reference has an ".addChild" method, + // it will be called passing this widget instance into that method, supplying the optional + // position index passed. + // + // returns: + // dijit._Widget + // Provides a useful return of the newly created dijit._Widget instance so you + // can "chain" this function by instantiating, placing, then saving the return value + // to a variable. + // + // example: + // | // create a Button with no srcNodeRef, and place it in the body: + // | var button = new dijit.form.Button({ label:"click" }).placeAt(dojo.body()); + // | // now, 'button' is still the widget reference to the newly created button + // | dojo.connect(button, "onClick", function(e){ console.log('click'); }); + // + // example: + // | // create a button out of a node with id="src" and append it to id="wrapper": + // | var button = new dijit.form.Button({},"src").placeAt("wrapper"); + // + // example: + // | // place a new button as the first element of some div + // | var button = new dijit.form.Button({ label:"click" }).placeAt("wrapper","first"); + // + // example: + // | // create a contentpane and add it to a TabContainer + // | var tc = dijit.byId("myTabs"); + // | new dijit.layout.ContentPane({ href:"foo.html", title:"Wow!" }).placeAt(tc) + + if(reference.declaredClass && reference.addChild){ + reference.addChild(this, position); + }else{ + dojo.place(this.domNode, reference, position); + } + return this; + } +}); + +})(); + +} |