diff options
| author | mensonge <mensonge@b3834d28-1941-0410-a4f8-b48e95affb8f> | 2008-11-13 09:49:11 +0000 | 
|---|---|---|
| committer | mensonge <mensonge@b3834d28-1941-0410-a4f8-b48e95affb8f> | 2008-11-13 09:49:11 +0000 | 
| commit | e44a7e37b6c7b5961adaffc62b9042b8d442938e (patch) | |
| tree | 95b67c356e93163467db2451f2b8cce84ed5d582 /includes/js/dijit/form | |
| parent | a62b9742ee5e28bcec6872d88f50f25b820914f6 (diff) | |
| download | semanticscuttle-e44a7e37b6c7b5961adaffc62b9042b8d442938e.tar.gz semanticscuttle-e44a7e37b6c7b5961adaffc62b9042b8d442938e.tar.bz2 | |
New feature: basic Ajax suggestion for tags and implementation of Dojo toolkit
git-svn-id: https://semanticscuttle.svn.sourceforge.net/svnroot/semanticscuttle/trunk@151 b3834d28-1941-0410-a4f8-b48e95affb8f
Diffstat (limited to 'includes/js/dijit/form')
103 files changed, 4745 insertions, 0 deletions
| diff --git a/includes/js/dijit/form/Button.js b/includes/js/dijit/form/Button.js new file mode 100644 index 0000000..f81078f --- /dev/null +++ b/includes/js/dijit/form/Button.js @@ -0,0 +1,425 @@ +if(!dojo._hasResource["dijit.form.Button"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. +dojo._hasResource["dijit.form.Button"] = true; +dojo.provide("dijit.form.Button"); + +dojo.require("dijit.form._FormWidget"); +dojo.require("dijit._Container"); + +dojo.declare("dijit.form.Button", +	dijit.form._FormWidget, +	{ +	// summary: +	//	Basically the same thing as a normal HTML button, but with special styling. +	// +	// example: +	// |	<button dojoType="dijit.form.Button" onClick="...">Hello world</button> +	//  +	// example: +	// |	var button1 = new dijit.form.Button({label: "hello world", onClick: foo}); +	// |	dojo.body().appendChild(button1.domNode); +	// +	// label: String +	//	text to display in button +	label: "", + +	// showLabel: Boolean +	//	whether or not to display the text label in button +	showLabel: true, + +	// iconClass: String +	//	class to apply to div in button to make it display an icon +	iconClass: "", + +	type: "button", +	baseClass: "dijitButton", +	templateString:"<div class=\"dijit dijitReset dijitLeft dijitInline\"\n\tdojoAttachEvent=\"onclick:_onButtonClick,onmouseenter:_onMouse,onmouseleave:_onMouse,onmousedown:_onMouse\"\n\twaiRole=\"presentation\"\n\t><button class=\"dijitReset dijitStretch dijitButtonNode dijitButtonContents\" dojoAttachPoint=\"focusNode,titleNode\"\n\t\ttype=\"${type}\" waiRole=\"button\" waiState=\"labelledby-${id}_label\"\n\t\t><span class=\"dijitReset dijitInline ${iconClass}\" dojoAttachPoint=\"iconNode\" \n \t\t\t><span class=\"dijitReset dijitToggleButtonIconChar\">✓</span \n\t\t></span\n\t\t><div class=\"dijitReset dijitInline\"><center class=\"dijitReset dijitButtonText\" id=\"${id}_label\" dojoAttachPoint=\"containerNode\">${label}</center></div\n\t></button\n></div>\n", + +	_onChangeMonitor: '', +	// TODO: set button's title to this.containerNode.innerText + +	_onClick: function(/*Event*/ e){ +		// summary: internal function to handle click actions +		if(this.disabled || this.readOnly){ +			dojo.stopEvent(e); // needed for checkbox +			return false; +		} +		this._clicked(); // widget click actions +		return this.onClick(e); // user click actions +	}, + +	_onButtonClick: function(/*Event*/ e){ +		// summary: callback when the user mouse clicks the button portion +		if(this._onClick(e) === false){ // returning nothing is same as true +			dojo.stopEvent(e); +		}else if(this.type=="submit" && !this.focusNode.form){ // see if a nonform widget needs to be signalled +			for(var node=this.domNode; node.parentNode/*#5935*/; node=node.parentNode){ +				var widget=dijit.byNode(node); +				if(widget && typeof widget._onSubmit == "function"){ +					widget._onSubmit(e); +					break; +				} +			} +		} +	}, + +	postCreate: function(){ +		// summary: +		//	get label and set as title on button icon if necessary +		if (this.showLabel == false){ +			var labelText = ""; +			this.label = this.containerNode.innerHTML; +			labelText = dojo.trim(this.containerNode.innerText || this.containerNode.textContent || ''); +			// set title attrib on iconNode +			this.titleNode.title=labelText; +			dojo.addClass(this.containerNode,"dijitDisplayNone"); +		} +		dojo.setSelectable(this.focusNode, false); +		this.inherited(arguments); +	}, + +	onClick: function(/*Event*/ e){ +		// summary: user callback for when button is clicked +		//      if type="submit", return true to perform submit +		return true; +	}, + +	_clicked: function(/*Event*/ e){ +		// summary: internal replaceable function for when the button is clicked +	}, + +	setLabel: function(/*String*/ content){ +		// summary: reset the label (text) of the button; takes an HTML string +		this.containerNode.innerHTML = this.label = content; +		this._layoutHack(); +		if (this.showLabel == false){ +			this.titleNode.title=dojo.trim(this.containerNode.innerText || this.containerNode.textContent || ''); +		} +	}		 +}); + + +dojo.declare("dijit.form.DropDownButton", [dijit.form.Button, dijit._Container], { +	// summary: A button with a popup +	// +	// example: +	// |	<button dojoType="dijit.form.DropDownButton" label="Hello world"> +	// |		<div dojotype="dijit.Menu">...</div> +	// |	</button> +	// +	// example: +	// |	var button1 = new dijit.form.DropDownButton({ label: "hi", dropDown: new dijit.Menu(...) }); +	// |	dojo.body().appendChild(button1); +	// 	 +	 +	baseClass : "dijitDropDownButton", + +	templateString:"<div class=\"dijit dijitReset dijitLeft dijitInline\"\n\tdojoAttachEvent=\"onmouseenter:_onMouse,onmouseleave:_onMouse,onmousedown:_onMouse,onclick:_onDropDownClick,onkeydown:_onDropDownKeydown,onblur:_onDropDownBlur,onkeypress:_onKey\"\n\twaiRole=\"presentation\"\n\t><div class='dijitReset dijitRight' waiRole=\"presentation\"\n\t><button class=\"dijitReset dijitStretch dijitButtonNode dijitButtonContents\" type=\"${type}\"\n\t\tdojoAttachPoint=\"focusNode,titleNode\" waiRole=\"button\" waiState=\"haspopup-true,labelledby-${id}_label\"\n\t\t><div class=\"dijitReset dijitInline ${iconClass}\" dojoAttachPoint=\"iconNode\" waiRole=\"presentation\"></div\n\t\t><div class=\"dijitReset dijitInline dijitButtonText\"  dojoAttachPoint=\"containerNode,popupStateNode\" waiRole=\"presentation\"\n\t\t\tid=\"${id}_label\">${label}</div\n\t\t><div class=\"dijitReset dijitInline dijitArrowButtonInner\" waiRole=\"presentation\"> </div\n\t\t><div class=\"dijitReset dijitInline dijitArrowButtonChar\" waiRole=\"presentation\">▼</div\n\t></button\n></div></div>\n", + +	_fillContent: function(){ +		// my inner HTML contains both the button contents and a drop down widget, like +		// <DropDownButton>  <span>push me</span>  <Menu> ... </Menu> </DropDownButton> +		// The first node is assumed to be the button content. The widget is the popup. +		if(this.srcNodeRef){ // programatically created buttons might not define srcNodeRef +			//FIXME: figure out how to filter out the widget and use all remaining nodes as button +			//	content, not just nodes[0] +			var nodes = dojo.query("*", this.srcNodeRef); +			dijit.form.DropDownButton.superclass._fillContent.call(this, nodes[0]); + +			// save pointer to srcNode so we can grab the drop down widget after it's instantiated +			this.dropDownContainer = this.srcNodeRef; +		} +	}, + +	startup: function(){ +		if(this._started){ return; } + +		// the child widget from srcNodeRef is the dropdown widget.  Insert it in the page DOM, +		// make it invisible, and store a reference to pass to the popup code. +		if(!this.dropDown){ +			var dropDownNode = dojo.query("[widgetId]", this.dropDownContainer)[0]; +			this.dropDown = dijit.byNode(dropDownNode); +			delete this.dropDownContainer; +		} +		dijit.popup.prepare(this.dropDown.domNode); + +		this.inherited(arguments); +	}, + +	destroyDescendants: function(){ +		if(this.dropDown){ +			this.dropDown.destroyRecursive(); +			delete this.dropDown; +		} +		this.inherited(arguments); +	}, + +	_onArrowClick: function(/*Event*/ e){ +		// summary: callback when the user mouse clicks on menu popup node +		if(this.disabled || this.readOnly){ return; } +		this._toggleDropDown(); +	}, + +	_onDropDownClick: function(/*Event*/ e){ +		// on Firefox 2 on the Mac it is possible to fire onclick +		// by pressing enter down on a second element and transferring +		// focus to the DropDownButton; +		// we want to prevent opening our menu in this situation +		// and only do so if we have seen a keydown on this button; +		// e.detail != 0 means that we were fired by mouse +		var isMacFFlessThan3 = dojo.isFF && dojo.isFF < 3 +			&& navigator.appVersion.indexOf("Macintosh") != -1; +		if(!isMacFFlessThan3 || e.detail != 0 || this._seenKeydown){ +			this._onArrowClick(e); +		} +		this._seenKeydown = false; +	}, + +	_onDropDownKeydown: function(/*Event*/ e){ +		this._seenKeydown = true; +	}, + +	_onDropDownBlur: function(/*Event*/ e){ +		this._seenKeydown = false; +	}, + +	_onKey: function(/*Event*/ e){ +		// summary: callback when the user presses a key on menu popup node +		if(this.disabled || this.readOnly){ return; } +		if(e.keyCode == dojo.keys.DOWN_ARROW){ +			if(!this.dropDown || this.dropDown.domNode.style.visibility=="hidden"){ +				dojo.stopEvent(e); +				this._toggleDropDown(); +			} +		} +	}, + +	_onBlur: function(){ +		// summary: called magically when focus has shifted away from this widget and it's dropdown +		this._closeDropDown(); +		// don't focus on button.  the user has explicitly focused on something else. +		this.inherited(arguments); +	}, + +	_toggleDropDown: function(){ +		// summary: toggle the drop-down widget; if it is up, close it, if not, open it +		if(this.disabled || this.readOnly){ return; } +		dijit.focus(this.popupStateNode); +		var dropDown = this.dropDown; +		if(!dropDown){ return; } +		if(!this._opened){ +			// If there's an href, then load that first, so we don't get a flicker +			if(dropDown.href && !dropDown.isLoaded){ +				var self = this; +				var handler = dojo.connect(dropDown, "onLoad", function(){ +					dojo.disconnect(handler); +					self._openDropDown(); +				}); +				dropDown._loadCheck(true); +				return; +			}else{ +				this._openDropDown(); +			} +		}else{ +			this._closeDropDown(); +		} +	}, + +	_openDropDown: function(){ +		var dropDown = this.dropDown; +		var oldWidth=dropDown.domNode.style.width; +		var self = this; + +		dijit.popup.open({ +			parent: this, +			popup: dropDown, +			around: this.domNode, +			orient: +				// TODO: add user-defined positioning option, like in Tooltip.js +				this.isLeftToRight() ? {'BL':'TL', 'BR':'TR', 'TL':'BL', 'TR':'BR'} +				: {'BR':'TR', 'BL':'TL', 'TR':'BR', 'TL':'BL'}, +			onExecute: function(){ +				self._closeDropDown(true); +			}, +			onCancel: function(){ +				self._closeDropDown(true); +			}, +			onClose: function(){ +				dropDown.domNode.style.width = oldWidth; +				self.popupStateNode.removeAttribute("popupActive"); +				this._opened = false; +			} +		}); +		if(this.domNode.offsetWidth > dropDown.domNode.offsetWidth){ +			var adjustNode = null; +			if(!this.isLeftToRight()){ +				adjustNode = dropDown.domNode.parentNode; +				var oldRight = adjustNode.offsetLeft + adjustNode.offsetWidth; +			} +			// make menu at least as wide as the button +			dojo.marginBox(dropDown.domNode, {w: this.domNode.offsetWidth}); +			if(adjustNode){ +				adjustNode.style.left = oldRight - this.domNode.offsetWidth + "px"; +			} +		} +		this.popupStateNode.setAttribute("popupActive", "true"); +		this._opened=true; +		if(dropDown.focus){ +			dropDown.focus(); +		} +		// TODO: set this.checked and call setStateClass(), to affect button look while drop down is shown +	}, +	 +	_closeDropDown: function(/*Boolean*/ focus){ +		if(this._opened){ +			dijit.popup.close(this.dropDown); +			if(focus){ this.focus(); } +			this._opened = false;			 +		} +	} +}); + +dojo.declare("dijit.form.ComboButton", dijit.form.DropDownButton, { +	// summary: A Normal Button with a DropDown +	// +	// example: +	// |	<button dojoType="dijit.form.ComboButton" onClick="..."> +	// |		<span>Hello world</span> +	// |		<div dojoType="dijit.Menu">...</div> +	// |	</button> +	// +	// example: +	// |	var button1 = new dijit.form.ComboButton({label: "hello world", onClick: foo, dropDown: "myMenu"}); +	// |	dojo.body().appendChild(button1.domNode); +	//  + +	templateString:"<table class='dijit dijitReset dijitInline dijitLeft'\n\tcellspacing='0' cellpadding='0' waiRole=\"presentation\"\n\t><tbody waiRole=\"presentation\"><tr waiRole=\"presentation\"\n\t\t><td\tclass=\"dijitReset dijitStretch dijitButtonContents dijitButtonNode\"\n\t\t\ttabIndex=\"${tabIndex}\"\n\t\t\tdojoAttachEvent=\"ondijitclick:_onButtonClick,onmouseenter:_onMouse,onmouseleave:_onMouse,onmousedown:_onMouse\"  dojoAttachPoint=\"titleNode\"\n\t\t\twaiRole=\"button\" waiState=\"labelledby-${id}_label\"\n\t\t\t><div class=\"dijitReset dijitInline ${iconClass}\" dojoAttachPoint=\"iconNode\" waiRole=\"presentation\"></div\n\t\t\t><div class=\"dijitReset dijitInline dijitButtonText\" id=\"${id}_label\" dojoAttachPoint=\"containerNode\" waiRole=\"presentation\">${label}</div\n\t\t></td\n\t\t><td class='dijitReset dijitStretch dijitButtonNode dijitArrowButton dijitDownArrowButton'\n\t\t\tdojoAttachPoint=\"popupStateNode,focusNode\"\n\t\t\tdojoAttachEvent=\"ondijitclick:_onArrowClick, onkeypress:_onKey,onmouseenter:_onMouse,onmouseleave:_onMouse\"\n\t\t\tstateModifier=\"DownArrow\"\n\t\t\ttitle=\"${optionsTitle}\" name=\"${name}\"\n\t\t\twaiRole=\"button\" waiState=\"haspopup-true\"\n\t\t\t><div class=\"dijitReset dijitArrowButtonInner\" waiRole=\"presentation\"> </div\n\t\t\t><div class=\"dijitReset dijitArrowButtonChar\" waiRole=\"presentation\">▼</div\n\t\t></td\n\t></tr></tbody\n></table>\n", + +	attributeMap: dojo.mixin(dojo.clone(dijit.form._FormWidget.prototype.attributeMap), +		{id:"", name:""}), + +	// optionsTitle: String +	//  text that describes the options menu (accessibility) +	optionsTitle: "", + +	baseClass: "dijitComboButton", + +	_focusedNode: null, + +	postCreate: function(){ +		this.inherited(arguments); +		this._focalNodes = [this.titleNode, this.popupStateNode]; +		dojo.forEach(this._focalNodes, dojo.hitch(this, function(node){ +			if(dojo.isIE){ +				this.connect(node, "onactivate", this._onNodeFocus); +				this.connect(node, "ondeactivate", this._onNodeBlur); +			}else{ +				this.connect(node, "onfocus", this._onNodeFocus); +				this.connect(node, "onblur", this._onNodeBlur); +			} +		})); +	}, + +	focusFocalNode: function(node){ +		// summary: Focus the focal node node. +		this._focusedNode = node; +		dijit.focus(node); +	}, + +	hasNextFocalNode: function(){ +		// summary: Returns true if this widget has no node currently +		//		focused or if there is a node following the focused one. +		//		False is returned if the last node has focus. +		return this._focusedNode !== this.getFocalNodes()[1]; +	}, + +	focusNext: function(){ +		// summary: Focus the focal node following the current node with focus +		//		or the first one if no node currently has focus. +		this._focusedNode = this.getFocalNodes()[this._focusedNode ? 1 : 0]; +		dijit.focus(this._focusedNode); +	}, + +	hasPrevFocalNode: function(){ +		// summary: Returns true if this widget has no node currently +		//		focused or if there is a node before the focused one. +		//		False is returned if the first node has focus. +		return this._focusedNode !== this.getFocalNodes()[0]; +	}, + +	focusPrev: function(){ +		// summary: Focus the focal node before the current node with focus +		//		or the last one if no node currently has focus. +		this._focusedNode = this.getFocalNodes()[this._focusedNode ? 0 : 1]; +		dijit.focus(this._focusedNode); +	}, + +	getFocalNodes: function(){ +		// summary: Returns an array of focal nodes for this widget. +		return this._focalNodes; +	}, + +	_onNodeFocus: function(evt){ +		this._focusedNode = evt.currentTarget; +		var fnc = this._focusedNode == this.focusNode ? "dijitDownArrowButtonFocused" : "dijitButtonContentsFocused"; +		dojo.addClass(this._focusedNode, fnc); +	}, + +	_onNodeBlur: function(evt){ +		var fnc = evt.currentTarget == this.focusNode ? "dijitDownArrowButtonFocused" : "dijitButtonContentsFocused"; +		dojo.removeClass(evt.currentTarget, fnc); +	}, + +	_onBlur: function(){ +		this.inherited(arguments); +		this._focusedNode = null; +	} +}); + +dojo.declare("dijit.form.ToggleButton", dijit.form.Button, { +	// summary: +	//	A button that can be in two states (checked or not). +	//	Can be base class for things like tabs or checkbox or radio buttons + +	baseClass: "dijitToggleButton", + +	// checked: Boolean +	//		Corresponds to the native HTML <input> element's attribute. +	//		In markup, specified as "checked='checked'" or just "checked". +	//		True if the button is depressed, or the checkbox is checked, +	//		or the radio button is selected, etc. +	checked: false, + +	_onChangeMonitor: 'checked', + +	attributeMap: dojo.mixin(dojo.clone(dijit.form.Button.prototype.attributeMap), +		{checked:"focusNode"}), + +	_clicked: function(/*Event*/ evt){ +		this.setAttribute('checked', !this.checked); +	}, + +	setAttribute: function(/*String*/ attr, /*anything*/ value){ +		this.inherited(arguments); +		switch(attr){ +			case "checked": +				dijit.setWaiState(this.focusNode || this.domNode, "pressed", this.checked); +				this._setStateClass();		 +				this._handleOnChange(this.checked, true); +		} +	}, + + +	setChecked: function(/*Boolean*/ checked){ +		// summary: +		//	Programatically deselect the button +		dojo.deprecated("setChecked("+checked+") is deprecated. Use setAttribute('checked',"+checked+") instead.", "", "2.0"); +		this.setAttribute('checked', checked); +	}, +	 +	postCreate: function(){ +		this.inherited(arguments); +		this.setAttribute('checked', this.checked); //to initially set wai pressed state  +	} +}); + +} diff --git a/includes/js/dijit/form/CheckBox.js b/includes/js/dijit/form/CheckBox.js new file mode 100644 index 0000000..295a711 --- /dev/null +++ b/includes/js/dijit/form/CheckBox.js @@ -0,0 +1,133 @@ +if(!dojo._hasResource["dijit.form.CheckBox"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. +dojo._hasResource["dijit.form.CheckBox"] = true; +dojo.provide("dijit.form.CheckBox"); + +dojo.require("dijit.form.Button"); + +dojo.declare( +	"dijit.form.CheckBox", +	dijit.form.ToggleButton, +	{ +		// summary: +		// 		Same as an HTML checkbox, but with fancy styling. +		// +		// description: +		// User interacts with real html inputs. +		// On onclick (which occurs by mouse click, space-bar, or +		// using the arrow keys to switch the selected radio button), +		// we update the state of the checkbox/radio. +		// +		// There are two modes: +		//   1. High contrast mode +		//   2. Normal mode +		// In case 1, the regular html inputs are shown and used by the user. +		// In case 2, the regular html inputs are invisible but still used by +		// the user. They are turned quasi-invisible and overlay the background-image. + +		templateString:"<div class=\"dijitReset dijitInline\" waiRole=\"presentation\"\n\t><input\n\t \ttype=\"${type}\" name=\"${name}\"\n\t\tclass=\"dijitReset dijitCheckBoxInput\"\n\t\tdojoAttachPoint=\"focusNode\"\n\t \tdojoAttachEvent=\"onmouseover:_onMouse,onmouseout:_onMouse,onclick:_onClick\"\n/></div>\n", + +		baseClass: "dijitCheckBox", + +		//	Value of "type" attribute for <input> +		type: "checkbox", + +		// value: Value +		//	equivalent to value field on normal checkbox (if checked, the value is passed as +		//	the value when form is submitted) +		value: "on", + +		setValue: function(/*String or Boolean*/ newValue){ +			// summary: +			//		When passed a boolean, controls whether or not the CheckBox is checked. +			//		If passed a string, changes the value attribute of the CheckBox (the one +			//		specified as "value" when the CheckBox was constructed (ex: <input +			//		dojoType="dijit.CheckBox" value="chicken">) +			if(typeof newValue == "string"){ +				this.setAttribute('value', newValue); +				newValue = true; +			} +			this.setAttribute('checked', newValue); +		}, + +		_getValueDeprecated: false, // remove when _FormWidget:_getValueDeprecated is removed +		getValue: function(){ +			// summary: +			//		If the CheckBox is checked, returns the value attribute. +			//		Otherwise returns false. +			return (this.checked ? this.value : false); +		}, + +		reset: function(){ +			this.inherited(arguments); +			this.setAttribute('value', this._resetValueAttr); +		}, + +		postCreate: function(){ +			this.inherited(arguments); +			this._resetValueAttr = this.value; +		} +	} +); + +dojo.declare( +	"dijit.form.RadioButton", +	dijit.form.CheckBox, +	{ +		// summary: +		// 		Same as an HTML radio, but with fancy styling. +		// +		// description: +		// Implementation details +		// +		// Specialization: +		// We keep track of dijit radio groups so that we can update the state +		// of all the siblings (the "context") in a group based on input +		// events. We don't rely on browser radio grouping. + +		type: "radio", +		baseClass: "dijitRadio", + +		// This shared object keeps track of all widgets, grouped by name +		_groups: {}, + +		postCreate: function(){ +			// add this widget to _groups +			(this._groups[this.name] = this._groups[this.name] || []).push(this); + +			this.inherited(arguments); +		}, + +		uninitialize: function(){ +			// remove this widget from _groups +			dojo.forEach(this._groups[this.name], function(widget, i, arr){ +				if(widget === this){ +					arr.splice(i, 1); +					return; +				} +			}, this); +		}, + +		setAttribute: function(/*String*/ attr, /*anything*/ value){ +			// If I am being checked then have to deselect currently checked radio button +			this.inherited(arguments); +			switch(attr){ +				case "checked": +					if(this.checked){ +						dojo.forEach(this._groups[this.name], function(widget){ +							if(widget != this && widget.checked){ +								widget.setAttribute('checked', false); +							} +						}, this); +					} +			} +		}, + +		_clicked: function(/*Event*/ e){ +			if(!this.checked){ +				this.setAttribute('checked', true); +			} +		} +	} +); + +} diff --git a/includes/js/dijit/form/ComboBox.js b/includes/js/dijit/form/ComboBox.js new file mode 100644 index 0000000..77a75f0 --- /dev/null +++ b/includes/js/dijit/form/ComboBox.js @@ -0,0 +1,1060 @@ +if(!dojo._hasResource["dijit.form.ComboBox"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. +dojo._hasResource["dijit.form.ComboBox"] = true; +dojo.provide("dijit.form.ComboBox"); + +dojo.require("dijit.form.ValidationTextBox"); +dojo.requireLocalization("dijit.form", "ComboBox", null, "zh,ROOT,pt,da,tr,ru,de,sv,ja,he,fi,nb,el,ar,pt-pt,cs,fr,es,ko,nl,zh-tw,pl,it,hu"); + +dojo.declare( +	"dijit.form.ComboBoxMixin", +	null, +	{ +		// item: Object +		//		This is the item returned by the dojo.data.store implementation that +		//		provides the data for this cobobox, it's the currently selected item. +		item: null, + +		// pageSize: Integer +		//		Argument to data provider. +		//		Specifies number of search results per page (before hitting "next" button) +		pageSize: Infinity, + +		// store: Object +		//		Reference to data provider object used by this ComboBox +		store: null, + +		// query: Object +		//		A query that can be passed to 'store' to initially filter the items, +		//		before doing further filtering based on `searchAttr` and the key. +		//		Any reference to the `searchAttr` is ignored. +		query: {}, + +		// autoComplete: Boolean +		//		If you type in a partial string, and then tab out of the `<input>` box, +		//		automatically copy the first entry displayed in the drop down list to +		//		the `<input>` field +		autoComplete: true, + +		// searchDelay: Integer +		//		Delay in milliseconds between when user types something and we start +		//		searching based on that value +		searchDelay: 100, + +		// searchAttr: String +		//		Searches pattern match against this field +		searchAttr: "name", + +		// queryExpr: String +		//		dojo.data query expression pattern. +		//		`${0}` will be substituted for the user text. +		//		`*` is used for wildcards. +		//		`${0}*` means "starts with", `*${0}*` means "contains", `${0}` means "is" +		queryExpr: "${0}*", + +		// ignoreCase: Boolean +		//		Set true if the ComboBox should ignore case when matching possible items +		ignoreCase: true, + +		// hasDownArrow: Boolean +		//		Set this textbox to have a down arrow button. +		//		Defaults to true. +		hasDownArrow:true, + +		templateString:"<div class=\"dijit dijitReset dijitInlineTable dijitLeft\"\n\tid=\"widget_${id}\"\n\tdojoAttachEvent=\"onmouseenter:_onMouse,onmouseleave:_onMouse,onmousedown:_onMouse\" dojoAttachPoint=\"comboNode\" waiRole=\"combobox\" tabIndex=\"-1\"\n\t><div style=\"overflow:hidden;\"\n\t\t><div class='dijitReset dijitRight dijitButtonNode dijitArrowButton dijitDownArrowButton'\n\t\t\tdojoAttachPoint=\"downArrowNode\" waiRole=\"presentation\"\n\t\t\tdojoAttachEvent=\"onmousedown:_onArrowMouseDown,onmouseup:_onMouse,onmouseenter:_onMouse,onmouseleave:_onMouse\"\n\t\t\t><div class=\"dijitArrowButtonInner\"> </div\n\t\t\t><div class=\"dijitArrowButtonChar\">▼</div\n\t\t></div\n\t\t><div class=\"dijitReset dijitValidationIcon\"><br></div\n\t\t><div class=\"dijitReset dijitValidationIconText\">Χ</div\n\t\t><div class=\"dijitReset dijitInputField\"\n\t\t\t><input type=\"text\" autocomplete=\"off\" name=\"${name}\" class='dijitReset'\n\t\t\tdojoAttachEvent=\"onkeypress:_onKeyPress, onfocus:_update, compositionend,onkeyup\"\n\t\t\tdojoAttachPoint=\"textbox,focusNode\" waiRole=\"textbox\" waiState=\"haspopup-true,autocomplete-list\"\n\t\t/></div\n\t></div\n></div>\n", + +		baseClass:"dijitComboBox", + +		_getCaretPos: function(/*DomNode*/ element){ +			// khtml 3.5.2 has selection* methods as does webkit nightlies from 2005-06-22 +			var pos = 0; +			if(typeof(element.selectionStart)=="number"){ +				// FIXME: this is totally borked on Moz < 1.3. Any recourse? +				pos = element.selectionStart; +			}else if(dojo.isIE){ +				// in the case of a mouse click in a popup being handled, +				// then the dojo.doc.selection is not the textarea, but the popup +				// var r = dojo.doc.selection.createRange(); +				// hack to get IE 6 to play nice. What a POS browser. +				var tr = dojo.doc.selection.createRange().duplicate(); +				var ntr = element.createTextRange(); +				tr.move("character",0); +				ntr.move("character",0); +				try{ +					// If control doesnt have focus, you get an exception. +					// Seems to happen on reverse-tab, but can also happen on tab (seems to be a race condition - only happens sometimes). +					// There appears to be no workaround for this - googled for quite a while. +					ntr.setEndPoint("EndToEnd", tr); +					pos = String(ntr.text).replace(/\r/g,"").length; +				}catch(e){ +					// If focus has shifted, 0 is fine for caret pos. +				} +			} +			return pos; +		}, + +		_setCaretPos: function(/*DomNode*/ element, /*Number*/ location){ +			location = parseInt(location); +			dijit.selectInputText(element, location, location); +		}, + +		_setAttribute: function(/*String*/ attr, /*anything*/ value){ +			// summary: additional code to set disablbed state of combobox node +			if (attr == "disabled"){ +				dijit.setWaiState(this.comboNode, "disabled", value); +			} +		},	 +		 +		_onKeyPress: function(/*Event*/ evt){ +			// summary: handles keyboard events + +			//except for pasting case - ctrl + v(118) +			if(evt.altKey || (evt.ctrlKey && evt.charCode != 118)){ +				return; +			} +			var doSearch = false; +			var pw = this._popupWidget; +			var dk = dojo.keys; +			if(this._isShowingNow){ +				pw.handleKey(evt); +			} +			switch(evt.keyCode){ +				case dk.PAGE_DOWN: +				case dk.DOWN_ARROW: +					if(!this._isShowingNow||this._prev_key_esc){ +						this._arrowPressed(); +						doSearch=true; +					}else{ +						this._announceOption(pw.getHighlightedOption()); +					} +					dojo.stopEvent(evt); +					this._prev_key_backspace = false; +					this._prev_key_esc = false; +					break; + +				case dk.PAGE_UP: +				case dk.UP_ARROW: +					if(this._isShowingNow){ +						this._announceOption(pw.getHighlightedOption()); +					} +					dojo.stopEvent(evt); +					this._prev_key_backspace = false; +					this._prev_key_esc = false; +					break; + +				case dk.ENTER: +					// prevent submitting form if user presses enter. Also +					// prevent accepting the value if either Next or Previous +					// are selected +					var highlighted; +					if(	this._isShowingNow &&  +						(highlighted = pw.getHighlightedOption()) +					){ +						// only stop event on prev/next +						if(highlighted == pw.nextButton){ +							this._nextSearch(1); +							dojo.stopEvent(evt); +							break; +						}else if(highlighted == pw.previousButton){ +							this._nextSearch(-1); +							dojo.stopEvent(evt); +							break; +						} +					}else{ +						this.setDisplayedValue(this.getDisplayedValue()); +					} +					// default case: +					// prevent submit, but allow event to bubble +					evt.preventDefault(); +					// fall through + +				case dk.TAB: +					var newvalue = this.getDisplayedValue(); +					// #4617:  +					//		if the user had More Choices selected fall into the +					//		_onBlur handler +					if(pw && ( +						newvalue == pw._messages["previousMessage"] || +						newvalue == pw._messages["nextMessage"]) +					){ +						break; +					} +					if(this._isShowingNow){ +						this._prev_key_backspace = false; +						this._prev_key_esc = false; +						if(pw.getHighlightedOption()){ +							pw.setValue({ target: pw.getHighlightedOption() }, true); +						} +						this._hideResultList(); +					} +					break; + +				case dk.SPACE: +					this._prev_key_backspace = false; +					this._prev_key_esc = false; +					if(this._isShowingNow && pw.getHighlightedOption()){ +						dojo.stopEvent(evt); +						this._selectOption(); +						this._hideResultList(); +					}else{ +						doSearch = true; +					} +					break; + +				case dk.ESCAPE: +					this._prev_key_backspace = false; +					this._prev_key_esc = true; +					if(this._isShowingNow){ +						dojo.stopEvent(evt); +						this._hideResultList(); +					} +					this.inherited(arguments); +					break; + +				case dk.DELETE: +				case dk.BACKSPACE: +					this._prev_key_esc = false; +					this._prev_key_backspace = true; +					doSearch = true; +					break; + +				case dk.RIGHT_ARROW: // fall through +				case dk.LEFT_ARROW:  +					this._prev_key_backspace = false; +					this._prev_key_esc = false; +					break; + +				default: // non char keys (F1-F12 etc..)  shouldn't open list +					this._prev_key_backspace = false; +					this._prev_key_esc = false; +					if(dojo.isIE || evt.charCode != 0){ +						doSearch = true; +					} +			} +			if(this.searchTimer){ +				clearTimeout(this.searchTimer); +			} +			if(doSearch){ +				// need to wait a tad before start search so that the event +				// bubbles through DOM and we have value visible +				setTimeout(dojo.hitch(this, "_startSearchFromInput"),1); +			} +		}, + +		_autoCompleteText: function(/*String*/ text){ +			// summary: +			// 		Fill in the textbox with the first item from the drop down +			// 		list, and highlight the characters that were +			// 		auto-completed. For example, if user typed "CA" and the +			// 		drop down list appeared, the textbox would be changed to +			// 		"California" and "ifornia" would be highlighted. + +			var fn = this.focusNode; + +			// IE7: clear selection so next highlight works all the time +			dijit.selectInputText(fn, fn.value.length); +			// does text autoComplete the value in the textbox? +			var caseFilter = this.ignoreCase? 'toLowerCase' : 'substr'; +			if(text[caseFilter](0).indexOf(this.focusNode.value[caseFilter](0)) == 0){ +				var cpos = this._getCaretPos(fn); +				// only try to extend if we added the last character at the end of the input +				if((cpos+1) > fn.value.length){ +					// only add to input node as we would overwrite Capitalisation of chars +					// actually, that is ok +					fn.value = text;//.substr(cpos); +					// visually highlight the autocompleted characters +					dijit.selectInputText(fn, cpos); +				} +			}else{ +				// text does not autoComplete; replace the whole value and highlight +				fn.value = text; +				dijit.selectInputText(fn); +			} +		}, + +		_openResultList: function(/*Object*/ results, /*Object*/ dataObject){ +			if(	this.disabled ||  +				this.readOnly ||  +				(dataObject.query[this.searchAttr] != this._lastQuery) +			){ +				return; +			} +			this._popupWidget.clearResultList(); +			if(!results.length){ +				this._hideResultList(); +				return; +			} + +			// Fill in the textbox with the first item from the drop down list, +			// and highlight the characters that were auto-completed. For +			// example, if user typed "CA" and the drop down list appeared, the +			// textbox would be changed to "California" and "ifornia" would be +			// highlighted. + +			var zerothvalue = new String(this.store.getValue(results[0], this.searchAttr)); +			if(zerothvalue && this.autoComplete && !this._prev_key_backspace && +				(dataObject.query[this.searchAttr] != "*")){ +				// when the user clicks the arrow button to show the full list, +				// startSearch looks for "*". +				// it does not make sense to autocomplete +				// if they are just previewing the options available. +				this._autoCompleteText(zerothvalue); +			} +			this._popupWidget.createOptions( +				results,  +				dataObject,  +				dojo.hitch(this, "_getMenuLabelFromItem") +			); + +			// show our list (only if we have content, else nothing) +			this._showResultList(); + +			// #4091: +			//		tell the screen reader that the paging callback finished by +			//		shouting the next choice +			if(dataObject.direction){ +				if(1 == dataObject.direction){ +					this._popupWidget.highlightFirstOption(); +				}else if(-1 == dataObject.direction){ +					this._popupWidget.highlightLastOption(); +				} +				this._announceOption(this._popupWidget.getHighlightedOption()); +			} +		}, + +		_showResultList: function(){ +			this._hideResultList(); +			var items = this._popupWidget.getItems(), +				visibleCount = Math.min(items.length,this.maxListLength); +			this._arrowPressed(); +			// hide the tooltip +			this.displayMessage(""); +			 +			// Position the list and if it's too big to fit on the screen then +			// size it to the maximum possible height +			// Our dear friend IE doesnt take max-height so we need to +			// calculate that on our own every time + +			// TODO: want to redo this, see  +			//		http://trac.dojotoolkit.org/ticket/3272 +			//	and +			//		http://trac.dojotoolkit.org/ticket/4108 + +			with(this._popupWidget.domNode.style){ +				// natural size of the list has changed, so erase old +				// width/height settings, which were hardcoded in a previous +				// call to this function (via dojo.marginBox() call)  +				width = ""; +				height = ""; +			} +			var best = this.open(); +			// #3212: +			//		only set auto scroll bars if necessary prevents issues with +			//		scroll bars appearing when they shouldn't when node is made +			//		wider (fractional pixels cause this) +			var popupbox = dojo.marginBox(this._popupWidget.domNode); +			this._popupWidget.domNode.style.overflow =  +				((best.h==popupbox.h)&&(best.w==popupbox.w)) ? "hidden" : "auto"; +			// #4134: +			//		borrow TextArea scrollbar test so content isn't covered by +			//		scrollbar and horizontal scrollbar doesn't appear +			var newwidth = best.w; +			if(best.h < this._popupWidget.domNode.scrollHeight){ +				newwidth += 16; +			} +			dojo.marginBox(this._popupWidget.domNode, { +				h: best.h, +				w: Math.max(newwidth, this.domNode.offsetWidth) +			}); +			dijit.setWaiState(this.comboNode, "expanded", "true"); +		}, + +		_hideResultList: function(){ +			if(this._isShowingNow){ +				dijit.popup.close(this._popupWidget); +				this._arrowIdle(); +				this._isShowingNow=false; +				dijit.setWaiState(this.comboNode, "expanded", "false"); +				dijit.removeWaiState(this.focusNode,"activedescendant"); +			} +		}, + +		_setBlurValue: function(){ +			// if the user clicks away from the textbox OR tabs away, set the +			// value to the textbox value +			// #4617:  +			//		if value is now more choices or previous choices, revert +			//		the value +			var newvalue=this.getDisplayedValue(); +			var pw = this._popupWidget; +			if(pw && ( +				newvalue == pw._messages["previousMessage"] || +				newvalue == pw._messages["nextMessage"] +				) +			){ +				this.setValue(this._lastValueReported, true); +			}else{ +				this.setDisplayedValue(newvalue); +			} +		}, + +		_onBlur: function(){ +			// summary: called magically when focus has shifted away from this widget and it's dropdown +			this._hideResultList(); +			this._arrowIdle(); +			this.inherited(arguments); +		}, + +		_announceOption: function(/*Node*/ node){ +			// summary: +			//		a11y code that puts the highlighted option in the textbox +			//		This way screen readers will know what is happening in the +			//		menu + +			if(node == null){ +				return; +			} +			// pull the text value from the item attached to the DOM node +			var newValue; +			if( node == this._popupWidget.nextButton || +				node == this._popupWidget.previousButton){ +				newValue = node.innerHTML; +			}else{ +				newValue = this.store.getValue(node.item, this.searchAttr); +			} +			// get the text that the user manually entered (cut off autocompleted text) +			this.focusNode.value = this.focusNode.value.substring(0, this._getCaretPos(this.focusNode)); +			//set up ARIA activedescendant +			dijit.setWaiState(this.focusNode, "activedescendant", dojo.attr(node, "id"));  +			// autocomplete the rest of the option to announce change +			this._autoCompleteText(newValue); +		}, + +		_selectOption: function(/*Event*/ evt){ +			var tgt = null; +			if(!evt){ +				evt ={ target: this._popupWidget.getHighlightedOption()}; +			} +				// what if nothing is highlighted yet? +			if(!evt.target){ +				// handle autocompletion where the the user has hit ENTER or TAB +				this.setDisplayedValue(this.getDisplayedValue()); +				return; +			// otherwise the user has accepted the autocompleted value +			}else{ +				tgt = evt.target; +			} +			if(!evt.noHide){ +				this._hideResultList(); +				this._setCaretPos(this.focusNode, this.store.getValue(tgt.item, this.searchAttr).length); +			} +			this._doSelect(tgt); +		}, + +		_doSelect: function(tgt){ +			this.item = tgt.item; +			this.setValue(this.store.getValue(tgt.item, this.searchAttr), true); +		}, + +		_onArrowMouseDown: function(evt){ +			// summary: callback when arrow is clicked +			if(this.disabled || this.readOnly){ +				return; +			} +			dojo.stopEvent(evt); +			this.focus(); +			if(this._isShowingNow){ +				this._hideResultList(); +			}else{ +				// forces full population of results, if they click +				// on the arrow it means they want to see more options +				this._startSearch(""); +			} +		}, + +		_startSearchFromInput: function(){ +			this._startSearch(this.focusNode.value); +		}, + +		_getQueryString: function(/*String*/ text){ +			return dojo.string.substitute(this.queryExpr, [text]); +		}, + +		_startSearch: function(/*String*/ key){ +			if(!this._popupWidget){ +				var popupId = this.id + "_popup"; +				this._popupWidget = new dijit.form._ComboBoxMenu({ +					onChange: dojo.hitch(this, this._selectOption), +					id:popupId +				}); +				dijit.removeWaiState(this.focusNode,"activedescendant"); +				dijit.setWaiState(this.textbox,"owns",popupId); // associate popup with textbox +			} +			// create a new query to prevent accidentally querying for a hidden +			// value from FilteringSelect's keyField +			this.item = null; // #4872 +			var query = dojo.clone(this.query); // #5970 +			this._lastQuery = query[this.searchAttr] = this._getQueryString(key); +			// #5970: set _lastQuery, *then* start the timeout +			// otherwise, if the user types and the last query returns before the timeout, +			// _lastQuery won't be set and their input gets rewritten +			this.searchTimer=setTimeout(dojo.hitch(this, function(query, _this){ +				var dataObject = this.store.fetch({ +					queryOptions: { +						ignoreCase: this.ignoreCase,  +						deep: true +					}, +					query: query, +					onComplete: dojo.hitch(this, "_openResultList"),  +					onError: function(errText){ +						console.error('dijit.form.ComboBox: ' + errText); +						dojo.hitch(_this, "_hideResultList")(); +					}, +					start:0, +					count:this.pageSize +				}); + +				var nextSearch = function(dataObject, direction){ +					dataObject.start += dataObject.count*direction; +					// #4091: +					//		tell callback the direction of the paging so the screen +					//		reader knows which menu option to shout +					dataObject.direction = direction; +					this.store.fetch(dataObject); +				} +				this._nextSearch = this._popupWidget.onPage = dojo.hitch(this, nextSearch, dataObject); +			}, query, this), this.searchDelay); +		}, + +		_getValueField:function(){ +			return this.searchAttr; +		}, + +		/////////////// Event handlers ///////////////////// + +		_arrowPressed: function(){ +			if(!this.disabled && !this.readOnly && this.hasDownArrow){ +				dojo.addClass(this.downArrowNode, "dijitArrowButtonActive"); +			} +		}, + +		_arrowIdle: function(){ +			if(!this.disabled && !this.readOnly && this.hasDownArrow){ +				dojo.removeClass(this.downArrowNode, "dojoArrowButtonPushed"); +			} +		}, + +		// FIXME:  +		//		this is public so we can't remove until 2.0, but the name +		//		SHOULD be "compositionEnd" + +		compositionend: function(/*Event*/ evt){ +			//	summary: +			//		When inputting characters using an input method, such as +			//		Asian languages, it will generate this event instead of +			//		onKeyDown event Note: this event is only triggered in FF +			//		(not in IE) +			this.onkeypress({charCode:-1}); +		}, + +		//////////// INITIALIZATION METHODS /////////////////////////////////////// + +		constructor: function(){ +			this.query={}; +		}, + +		postMixInProperties: function(){ +			if(!this.hasDownArrow){ +				this.baseClass = "dijitTextBox"; +			} +			if(!this.store){ +				var srcNodeRef = this.srcNodeRef; + +				// if user didn't specify store, then assume there are option tags +				this.store = new dijit.form._ComboBoxDataStore(srcNodeRef); + +				// if there is no value set and there is an option list, set +				// the value to the first value to be consistent with native +				// Select + +				// Firefox and Safari set value +				// IE6 and Opera set selectedIndex, which is automatically set +				// by the selected attribute of an option tag +				// IE6 does not set value, Opera sets value = selectedIndex +				if(	!this.value || ( +						(typeof srcNodeRef.selectedIndex == "number") &&  +						srcNodeRef.selectedIndex.toString() === this.value) +				){ +					var item = this.store.fetchSelectedItem(); +					if(item){ +						this.value = this.store.getValue(item, this._getValueField()); +					} +				} +			} +		}, +		 +		_postCreate:function(){ +			//find any associated label element and add to combobox node. +			var label=dojo.query('label[for="'+this.id+'"]'); +			if(label.length){ +				label[0].id = (this.id+"_label"); +				var cn=this.comboNode; +				dijit.setWaiState(cn, "labelledby", label[0].id); +				dijit.setWaiState(cn, "disabled", this.disabled); +				 +			} +		}, + +		uninitialize:function(){ +			if(this._popupWidget){ +				this._hideResultList(); +				this._popupWidget.destroy() +			} +		}, + +		_getMenuLabelFromItem:function(/*Item*/ item){ +			return { +				html: false,  +				label: this.store.getValue(item, this.searchAttr) +			}; +		}, + +		open:function(){ +			this._isShowingNow=true; +			return dijit.popup.open({ +				popup: this._popupWidget, +				around: this.domNode, +				parent: this +			}); +		}, +		 +		reset:function(){ +			//	summary: +			//		Additionally reset the .item (to clean up). +			this.item = null; +			this.inherited(arguments); +		} +		 +	} +); + +dojo.declare( +	"dijit.form._ComboBoxMenu", +	[dijit._Widget, dijit._Templated], + +	{ +		//	summary: +		//		Focus-less div based menu for internal use in ComboBox + +		templateString: "<ul class='dijitMenu' dojoAttachEvent='onmousedown:_onMouseDown,onmouseup:_onMouseUp,onmouseover:_onMouseOver,onmouseout:_onMouseOut' tabIndex='-1' style='overflow:\"auto\";'>" +				+"<li class='dijitMenuItem dijitMenuPreviousButton' dojoAttachPoint='previousButton'></li>" +				+"<li class='dijitMenuItem dijitMenuNextButton' dojoAttachPoint='nextButton'></li>" +			+"</ul>", +		_messages: null, + +		postMixInProperties: function(){ +			this._messages = dojo.i18n.getLocalization("dijit.form", "ComboBox", this.lang); +			this.inherited("postMixInProperties", arguments); +		}, + +		setValue: function(/*Object*/ value){ +			this.value = value; +			this.onChange(value); +		}, + +		// stubs +		onChange: function(/*Object*/ value){}, +		onPage: function(/*Number*/ direction){}, + +		postCreate:function(){ +			// fill in template with i18n messages +			this.previousButton.innerHTML = this._messages["previousMessage"]; +			this.nextButton.innerHTML = this._messages["nextMessage"]; +			this.inherited("postCreate", arguments); +		}, + +		onClose:function(){ +			this._blurOptionNode(); +		}, + +		_createOption:function(/*Object*/ item, labelFunc){ +			//	summary:  +			//		creates an option to appear on the popup menu subclassed by +			//		FilteringSelect + +			var labelObject = labelFunc(item); +			var menuitem = dojo.doc.createElement("li"); +			dijit.setWaiRole(menuitem, "option"); +			if(labelObject.html){ +				menuitem.innerHTML = labelObject.label; +			}else{ +				menuitem.appendChild( +					dojo.doc.createTextNode(labelObject.label) +				); +			} +			// #3250: in blank options, assign a normal height +			if(menuitem.innerHTML == ""){ +				menuitem.innerHTML = " "; +			} +			menuitem.item=item; +			return menuitem; +		}, + +		createOptions: function(results, dataObject, labelFunc){ +			//this._dataObject=dataObject; +			//this._dataObject.onComplete=dojo.hitch(comboBox, comboBox._openResultList); +			// display "Previous . . ." button +			this.previousButton.style.display = (dataObject.start == 0) ? "none" : ""; +			dojo.attr(this.previousButton, "id", this.id + "_prev"); +			// create options using _createOption function defined by parent +			// ComboBox (or FilteringSelect) class +			// #2309: +			//		iterate over cache nondestructively +			dojo.forEach(results, function(item, i){ +				var menuitem = this._createOption(item, labelFunc); +				menuitem.className = "dijitMenuItem"; +				dojo.attr(menuitem, "id", this.id + i); +				this.domNode.insertBefore(menuitem, this.nextButton); +			}, this); +			// display "Next . . ." button +			this.nextButton.style.display = (dataObject.count == results.length) ? "" : "none"; +			dojo.attr(this.nextButton,"id", this.id + "_next") +		}, + +		clearResultList: function(){ +			// keep the previous and next buttons of course +			while(this.domNode.childNodes.length>2){ +				this.domNode.removeChild(this.domNode.childNodes[this.domNode.childNodes.length-2]); +			} +		}, + +		// these functions are called in showResultList +		getItems: function(){ +			return this.domNode.childNodes; +		}, + +		getListLength: function(){ +			return this.domNode.childNodes.length-2; +		}, + +		_onMouseDown: function(/*Event*/ evt){ +			dojo.stopEvent(evt); +		}, + +		_onMouseUp: function(/*Event*/ evt){ +			if(evt.target === this.domNode){ +				return; +			}else if(evt.target==this.previousButton){ +				this.onPage(-1); +			}else if(evt.target==this.nextButton){ +				this.onPage(1); +			}else{ +				var tgt = evt.target; +				// while the clicked node is inside the div +				while(!tgt.item){ +					// recurse to the top +					tgt = tgt.parentNode; +				} +				this.setValue({ target: tgt }, true); +			} +		}, + +		_onMouseOver: function(/*Event*/ evt){ +			if(evt.target === this.domNode){ return; } +			var tgt = evt.target; +			if(!(tgt == this.previousButton || tgt == this.nextButton)){ +				// while the clicked node is inside the div +				while(!tgt.item){ +					// recurse to the top +					tgt = tgt.parentNode; +				} +			} +			this._focusOptionNode(tgt); +		}, + +		_onMouseOut:function(/*Event*/ evt){ +			if(evt.target === this.domNode){ return; } +			this._blurOptionNode(); +		}, + +		_focusOptionNode:function(/*DomNode*/ node){ +			// summary: +			//	does the actual highlight +			if(this._highlighted_option != node){ +				this._blurOptionNode(); +				this._highlighted_option = node; +				dojo.addClass(this._highlighted_option, "dijitMenuItemHover"); +			} +		}, + +		_blurOptionNode:function(){ +			// summary: +			//	removes highlight on highlighted option +			if(this._highlighted_option){ +				dojo.removeClass(this._highlighted_option, "dijitMenuItemHover"); +				this._highlighted_option = null; +			} +		}, + +		_highlightNextOption:function(){ +			//	summary: +			// 		Highlight the item just below the current selection. +			// 		If nothing selected, highlight first option + +			// because each press of a button clears the menu, +			// the highlighted option sometimes becomes detached from the menu! +			// test to see if the option has a parent to see if this is the case. +			var fc = this.domNode.firstChild; +			if(!this.getHighlightedOption()){ +				this._focusOptionNode(fc.style.display=="none" ? fc.nextSibling : fc); +			}else{ +				var ns = this._highlighted_option.nextSibling; +				if(ns && ns.style.display!="none"){ +					this._focusOptionNode(ns); +				} +			} +			// scrollIntoView is called outside of _focusOptionNode because in IE putting it inside causes the menu to scroll up on mouseover +			dijit.scrollIntoView(this._highlighted_option); +		}, + +		highlightFirstOption:function(){ +			//	summary: +			// 		Highlight the first real item in the list (not Previous Choices). +			this._focusOptionNode(this.domNode.firstChild.nextSibling); +			dijit.scrollIntoView(this._highlighted_option); +		}, + +		highlightLastOption:function(){ +			//	summary: +			// 		Highlight the last real item in the list (not More Choices). +			this._focusOptionNode(this.domNode.lastChild.previousSibling); +			dijit.scrollIntoView(this._highlighted_option); +		}, + +		_highlightPrevOption:function(){ +			//	summary: +			// 		Highlight the item just above the current selection. +			// 		If nothing selected, highlight last option (if +			// 		you select Previous and try to keep scrolling up the list) +			var lc = this.domNode.lastChild; +			if(!this.getHighlightedOption()){ +				this._focusOptionNode(lc.style.display == "none" ? lc.previousSibling : lc); +			}else{ +				var ps = this._highlighted_option.previousSibling; +				if(ps && ps.style.display != "none"){ +					this._focusOptionNode(ps); +				} +			} +			dijit.scrollIntoView(this._highlighted_option); +		}, + +		_page:function(/*Boolean*/ up){ +			var scrollamount = 0; +			var oldscroll = this.domNode.scrollTop; +			var height = dojo.style(this.domNode, "height"); +			// if no item is highlighted, highlight the first option +			if(!this.getHighlightedOption()){ +				this._highlightNextOption(); +			} +			while(scrollamount<height){ +				if(up){ +					// stop at option 1 +					if(!this.getHighlightedOption().previousSibling || +						this._highlighted_option.previousSibling.style.display == "none"){ +						break; +					} +					this._highlightPrevOption(); +				}else{ +					// stop at last option +					if(!this.getHighlightedOption().nextSibling || +						this._highlighted_option.nextSibling.style.display == "none"){ +						break; +					} +					this._highlightNextOption(); +				} +				// going backwards +				var newscroll=this.domNode.scrollTop; +				scrollamount+=(newscroll-oldscroll)*(up ? -1:1); +				oldscroll=newscroll; +			} +		}, + +		pageUp: function(){ this._page(true); }, + +		pageDown: function(){ this._page(false); }, + +		getHighlightedOption: function(){ +			//	summary: +			//		Returns the highlighted option. +			var ho = this._highlighted_option; +			return (ho && ho.parentNode) ? ho : null; +		}, + +		handleKey: function(evt){ +			switch(evt.keyCode){ +				case dojo.keys.DOWN_ARROW: +					this._highlightNextOption(); +					break; +				case dojo.keys.PAGE_DOWN: +					this.pageDown(); +					break;	 +				case dojo.keys.UP_ARROW: +					this._highlightPrevOption(); +					break; +				case dojo.keys.PAGE_UP: +					this.pageUp(); +					break;	 +			} +		} +	} +); + +dojo.declare( +	"dijit.form.ComboBox", +	[dijit.form.ValidationTextBox, dijit.form.ComboBoxMixin], +	{ +		//	summary: +		//		Auto-completing text box, and base class for dijit.form.FilteringSelect. +		//  +		//	description: +		//		The drop down box's values are populated from an class called +		//		a data provider, which returns a list of values based on the characters +		//		that the user has typed into the input box. +		//  +		//		Some of the options to the ComboBox are actually arguments to the data +		//		provider. +		//  +		//		You can assume that all the form widgets (and thus anything that mixes +		//		in dijit.formComboBoxMixin) will inherit from dijit.form._FormWidget and thus the `this` +		//		reference will also "be a" _FormWidget. + +		postMixInProperties: function(){ +			// this.inherited(arguments); // ?? +			dijit.form.ComboBoxMixin.prototype.postMixInProperties.apply(this, arguments); +			dijit.form.ValidationTextBox.prototype.postMixInProperties.apply(this, arguments); +		}, + +		postCreate: function(){ +			dijit.form.ComboBoxMixin.prototype._postCreate.apply(this, arguments); +			dijit.form.ValidationTextBox.prototype.postCreate.apply(this, arguments); +		}, +		setAttribute: function(/*String*/ attr, /*anything*/ value){ +			dijit.form.ValidationTextBox.prototype.setAttribute.apply(this, arguments); +			dijit.form.ComboBoxMixin.prototype._setAttribute.apply(this, arguments); +		} +		 +	} +); + +dojo.declare("dijit.form._ComboBoxDataStore", null, { +	//	summary: +	//		Inefficient but small data store specialized for inlined ComboBox data +	// +	//	description: +	//		Provides a store for inlined data like: +	// +	//	|	<select> +	//	|		<option value="AL">Alabama</option> +	//	|		... +	// +	//		Actually. just implements the subset of dojo.data.Read/Notification +	//		needed for ComboBox and FilteringSelect to work. +	// +	//		Note that an item is just a pointer to the <option> DomNode. + +	constructor: function( /*DomNode*/ root){ +		this.root = root; +/* +		//	TODO: this was added in #3858 but unclear why/if it's needed;  doesn't seem to be. +		//	If it is needed then can we just hide the select itself instead? +		dojo.query("> option", root).forEach(function(node){ +			node.style.display="none"; +		}); +*/ +	}, + +	getValue: function(	/* item */ item,  +						/* attribute-name-string */ attribute,  +						/* value? */ defaultValue){ +		return (attribute == "value") ? item.value : (item.innerText || item.textContent || ''); +	}, + +	isItemLoaded: function(/* anything */ something) { +		return true; +	}, + +	fetch: function(/* Object */ args){ +		//	summary: +		//		Given a query and set of defined options, such as a start and count of items to return, +		//		this method executes the query and makes the results available as data items. +		//		Refer to dojo.data.api.Read.fetch() more details. +		// +		//	description: +		//		Given a query like +		// +		//	|	{ +		// 	|		query: {name: "Cal*"}, +		//	|		start: 30, +		//	|		count: 20, +		//	|		ignoreCase: true, +		//	|		onComplete: function(/* item[] */ items, /* Object */ args){...} +		// 	|	} +		// +		//		will call `onComplete()` with the results of the query (and the argument to this method) + +		// convert query to regex (ex: convert "first\last*" to /^first\\last.*$/i) and get matching vals +		var query = "^" + args.query.name +				.replace(/([\\\|\(\)\[\{\^\$\+\?\.\<\>])/g, "\\$1") +				.replace("*", ".*") + "$", +			matcher = new RegExp(query, args.queryOptions.ignoreCase ? "i" : ""), +			items = dojo.query("> option", this.root).filter(function(option){ +				return (option.innerText || option.textContent || '').match(matcher); +			} ); + +		var start = args.start || 0, +			end = ("count" in args && args.count != Infinity) ? (start + args.count) : items.length ; +		args.onComplete(items.slice(start, end), args); +		return args; // Object +		// TODO: I don't need to return the length? +	}, + +	close: function(/*dojo.data.api.Request || args || null */ request){ +		return; +	}, + +	getLabel: function(/* item */ item){ +		return item.innerHTML; +	}, + +	getIdentity: function(/* item */ item){ +		return dojo.attr(item, "value"); +	}, + +	fetchItemByIdentity: function(/* Object */ args){ +		//	summary: +		//		Given the identity of an item, this method returns the item that has +		//		that identity through the onItem callback. +		//		Refer to dojo.data.api.Identity.fetchItemByIdentity() for more details. +		// +		//	description: +		//		Given arguments like: +		// +		//	|		{identity: "CA", onItem: function(item){...} +		// +		//		Call `onItem()` with the DOM node `<option value="CA">California</option>` +		var item = dojo.query("option[value='" + args.identity + "']", this.root)[0]; +		args.onItem(item); +	}, +	 +	fetchSelectedItem: function(){ +		//	summary: +		//		Get the option marked as selected, like `<option selected>`. +		//		Not part of dojo.data API. +		var root = this.root, +			si = root.selectedIndex; +		return dojo.query("> option:nth-child(" + +			(si != -1 ? si+1 : 1) + ")", +			root)[0];	// dojo.data.Item +	} +}); + +} diff --git a/includes/js/dijit/form/CurrencyTextBox.js b/includes/js/dijit/form/CurrencyTextBox.js new file mode 100644 index 0000000..c04d07e --- /dev/null +++ b/includes/js/dijit/form/CurrencyTextBox.js @@ -0,0 +1,51 @@ +if(!dojo._hasResource["dijit.form.CurrencyTextBox"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. +dojo._hasResource["dijit.form.CurrencyTextBox"] = true; +dojo.provide("dijit.form.CurrencyTextBox"); + +//FIXME: dojo.experimental throws an unreadable exception? +//dojo.experimental("dijit.form.CurrencyTextBox"); + +dojo.require("dojo.currency"); +dojo.require("dijit.form.NumberTextBox"); + +dojo.declare( +	"dijit.form.CurrencyTextBox", +	dijit.form.NumberTextBox, +	{ +		// summary: +		//		A validating currency textbox +		// +		// constraints: dijit.form._DateTimeTextBox.__Constraints  +		// +		// currency: String +		//		the [ISO4217](http://en.wikipedia.org/wiki/ISO_4217) currency code, a three letter sequence like "USD" +		currency: "", + +		/*===== +		constraints: {}, +		======*/ + +		regExpGen: dojo.currency.regexp, +		_formatter: dojo.currency.format, +/*===== +		parse: function(value, constraints){ +			//	summary: parses the value as a Currency, according to constraints +			//	value: String +			// +			//	constraints: dojo.currency.__ParseOptions +		}, +=====*/ +		parse: dojo.currency.parse, + +		postMixInProperties: function(){ +			if(this.constraints === dijit.form.ValidationTextBox.prototype.constraints){ +				// declare a constraints property on 'this' so we don't overwrite the shared default object in 'prototype' +				this.constraints = {}; +			} +			this.constraints.currency = this.currency; +			dijit.form.CurrencyTextBox.superclass.postMixInProperties.apply(this, arguments); +		} +	} +); + +} diff --git a/includes/js/dijit/form/DateTextBox.js b/includes/js/dijit/form/DateTextBox.js new file mode 100644 index 0000000..c3ce9d8 --- /dev/null +++ b/includes/js/dijit/form/DateTextBox.js @@ -0,0 +1,20 @@ +if(!dojo._hasResource["dijit.form.DateTextBox"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. +dojo._hasResource["dijit.form.DateTextBox"] = true; +dojo.provide("dijit.form.DateTextBox"); + +dojo.require("dijit._Calendar"); +dojo.require("dijit.form._DateTimeTextBox"); + +dojo.declare( +	"dijit.form.DateTextBox", +	dijit.form._DateTimeTextBox, +	{ +		// summary: +		//		A validating, serializable, range-bound date text box with a popup calendar + +		popupClass: "dijit._Calendar", +		_selector: "date" +	} +); + +} diff --git a/includes/js/dijit/form/FilteringSelect.js b/includes/js/dijit/form/FilteringSelect.js new file mode 100644 index 0000000..d1e25c0 --- /dev/null +++ b/includes/js/dijit/form/FilteringSelect.js @@ -0,0 +1,241 @@ +if(!dojo._hasResource["dijit.form.FilteringSelect"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. +dojo._hasResource["dijit.form.FilteringSelect"] = true; +dojo.provide("dijit.form.FilteringSelect"); + +dojo.require("dijit.form.ComboBox"); + +dojo.declare( +	"dijit.form.FilteringSelect", +	[dijit.form.MappedTextBox, dijit.form.ComboBoxMixin], +	{ +		// summary +		// An enhanced version of the HTML SELECT tag, populated dynamically +		// +		// description +		// An enhanced version of the HTML SELECT tag, populated dynamically. It works +		// very nicely with very large data sets because it can load and page data as needed. +		// It also resembles ComboBox, but does not allow values outside of the provided ones. +		//   +		// Similar features: +		//  - There is a drop down list of possible values. +		//	- You can only enter a value from the drop down list.  (You can't +		//	  enter an arbitrary value.) +		//	- The value submitted with the form is the hidden value (ex: CA), +		//	  not the displayed value a.k.a. label (ex: California) +		//  +		//	Enhancements over plain HTML version: +		//	- If you type in some text then it will filter down the list of +		//	  possible values in the drop down list. +		//	- List can be specified either as a static list or via a javascript +		//	  function (that can get the list from a server) +		// +		// searchAttr: String +		//		Searches pattern match against this field +		// +		// labelAttr: String +		//		Optional.  The text that actually appears in the drop down. +		//		If not specified, the searchAttr text is used instead. +		labelAttr: "", + +		// labelType: String +		//		"html" or "text" +		labelType: "text", + +		_isvalid:true, + +		_lastDisplayedValue: "", + +		isValid:function(){ +			return this._isvalid; +		}, + +		_callbackSetLabel: function(	/*Array*/ result,  +						/*Object*/ dataObject,  +						/*Boolean?*/ priorityChange){ +			// summary: +			//		Callback function that dynamically sets the label of the +			//		ComboBox + +			// setValue does a synchronous lookup, +			// so it calls _callbackSetLabel directly, +			// and so does not pass dataObject +			// dataObject==null means do not test the lastQuery, just continue +			if(dataObject && dataObject.query[this.searchAttr] != this._lastQuery){ +				return; +			} +			if(!result.length){ +				//#3268: do nothing on bad input +				//this._setValue("", ""); +				//#3285: change CSS to indicate error +				if(!this._focused){ this.valueNode.value=""; } +				dijit.form.TextBox.superclass.setValue.call(this, undefined, !this._focused); +				this._isvalid=false; +				this.validate(this._focused); +			}else{ +				this._setValueFromItem(result[0], priorityChange); +			} +		}, + +		_openResultList: function(/*Object*/ results, /*Object*/ dataObject){ +			// #3285: tap into search callback to see if user's query resembles a match +			if(dataObject.query[this.searchAttr] != this._lastQuery){ +				return; +			} +			this._isvalid = results.length != 0; // FIXME: should this be greater-than? +			this.validate(true); +			dijit.form.ComboBoxMixin.prototype._openResultList.apply(this, arguments); +		}, + +		getValue:function(){ +			// don't get the textbox value but rather the previously set hidden value +			return this.valueNode.value; +		}, + +		_getValueField:function(){ +			// used for option tag selects +			return "value"; +		}, + +		_setValue:function(	/*String*/ value,  +					/*String*/ displayedValue,  +					/*Boolean?*/ priorityChange){ +			this.valueNode.value = value; +			dijit.form.FilteringSelect.superclass.setValue.call(this, value, priorityChange, displayedValue); +			this._lastDisplayedValue = displayedValue; +		}, + +		setValue: function(/*String*/ value, /*Boolean?*/ priorityChange){ +			// summary +			//	Sets the value of the select. +			//	Also sets the label to the corresponding value by reverse lookup. + +			//#3347: fetchItemByIdentity if no keyAttr specified +			var self=this; +			var handleFetchByIdentity = function(item, priorityChange){ +				if(item){ +					if(self.store.isItemLoaded(item)){ +						self._callbackSetLabel([item], undefined, priorityChange); +					}else{ +						self.store.loadItem({ +							item: item,  +							onItem: function(result, dataObject){ +								self._callbackSetLabel(result, dataObject, priorityChange); +							} +						}); +					} +				}else{ +					self._isvalid=false; +					// prevent errors from Tooltip not being created yet +					self.validate(false); +				} +			} +			this.store.fetchItemByIdentity({ +				identity: value,  +				onItem: function(item){ +					handleFetchByIdentity(item, priorityChange); +				} +			}); +		}, + +		_setValueFromItem: function(/*item*/ item, /*Boolean?*/ priorityChange){ +			//	summary: +			//		Set the displayed valued in the input box, based on a +			//		selected item. +			//	description: +			//		Users shouldn't call this function; they should be calling +			//		setDisplayedValue() instead +			this._isvalid=true; +			this._setValue(	this.store.getIdentity(item),  +							this.labelFunc(item, this.store),  +							priorityChange); +		}, + +		labelFunc: function(/*item*/ item, /*dojo.data.store*/ store){ +			// summary: Event handler called when the label changes +			// return: the label that the ComboBox should display +			return store.getValue(item, this.searchAttr); +		}, + +		_doSelect: function(/*Event*/ tgt){ +			// summary: +			//		ComboBox's menu callback function +			//	description: +			//		FilteringSelect overrides this to set both the visible and +			//		hidden value from the information stored in the menu +			this.item = tgt.item; +			this._setValueFromItem(tgt.item, true); +		}, + +		setDisplayedValue:function(/*String*/ label, /*Boolean?*/ priorityChange){ +			// summary: +			//		Set textbox to display label. Also performs reverse lookup +			//		to set the hidden value. Used in InlineEditBox + +			if(this.store){ +				var query = dojo.clone(this.query); // #6196: populate query with user-specifics +				this._lastQuery = query[this.searchAttr] = label; +				// if the label is not valid, the callback will never set it, +				// so the last valid value will get the warning textbox set the +				// textbox value now so that the impending warning will make +				// sense to the user +				this.textbox.value = label; +				this._lastDisplayedValue = label; +				var _this = this; +				this.store.fetch({ +					query: query,  +					queryOptions: { +						ignoreCase: this.ignoreCase,  +						deep: true +					},  +					onComplete: function(result, dataObject){ +						        dojo.hitch(_this, "_callbackSetLabel")(result, dataObject, priorityChange); +					}, +					onError: function(errText){ +						console.error('dijit.form.FilteringSelect: ' + errText); +						dojo.hitch(_this, "_setValue")(undefined, label, false); +					} +				}); +			} +		}, + +		_getMenuLabelFromItem:function(/*Item*/ item){ +			// internal function to help ComboBoxMenu figure out what to display +			if(this.labelAttr){ +				return { +					html: this.labelType=="html",  +					label: this.store.getValue(item, this.labelAttr) +				}; +			}else{ +				// because this function is called by ComboBoxMenu, +				// this.inherited tries to find the superclass of ComboBoxMenu +				return dijit.form.ComboBoxMixin.prototype._getMenuLabelFromItem.apply(this, arguments); +			} +		}, + +		postMixInProperties: function(){ +			// FIXME: shouldn't this just be a call to inherited? +			dijit.form.ComboBoxMixin.prototype.postMixInProperties.apply(this, arguments); +			dijit.form.MappedTextBox.prototype.postMixInProperties.apply(this, arguments); +		}, + +		postCreate: function(){ +			dijit.form.ComboBoxMixin.prototype._postCreate.apply(this, arguments); +			dijit.form.MappedTextBox.prototype.postCreate.apply(this, arguments); +		}, +		 +		setAttribute: function(/*String*/ attr, /*anything*/ value){ +			dijit.form.MappedTextBox.prototype.setAttribute.apply(this, arguments); +			dijit.form.ComboBoxMixin.prototype._setAttribute.apply(this, arguments); +		}, + +		undo: function(){ +			this.setDisplayedValue(this._lastDisplayedValue); +		}, + +		_valueChanged: function(){ +			return this.getDisplayedValue()!=this._lastDisplayedValue; +		} +	} +); + +} diff --git a/includes/js/dijit/form/Form.js b/includes/js/dijit/form/Form.js new file mode 100644 index 0000000..4ad29f9 --- /dev/null +++ b/includes/js/dijit/form/Form.js @@ -0,0 +1,384 @@ +if(!dojo._hasResource["dijit.form.Form"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. +dojo._hasResource["dijit.form.Form"] = true; +dojo.provide("dijit.form.Form"); + +dojo.require("dijit._Widget"); +dojo.require("dijit._Templated"); + +dojo.declare("dijit.form._FormMixin", null, +	{ +	// +	//	summary: +	//		Widget corresponding to HTML form tag, for validation and serialization +	// +	//	example: +	//	|	<form dojoType="dijit.form.Form" id="myForm"> +	//	|		Name: <input type="text" name="name" /> +	//	|	</form> +	//	|	myObj = {name: "John Doe"}; +	//	|	dijit.byId('myForm').setValues(myObj); +	//	| +	//	|	myObj=dijit.byId('myForm').getValues(); + +	//	TODO: +	//	* Repeater +	//	* better handling for arrays.  Often form elements have names with [] like +	//	* people[3].sex (for a list of people [{name: Bill, sex: M}, ...]) +	// +	//	 + +		reset: function(){ +			dojo.forEach(this.getDescendants(), function(widget){ +				if(widget.reset){ +					widget.reset(); +				} +			}); +		}, + +		validate: function(){ +			// summary: returns if the form is valid - same as isValid - but +			//			provides a few additional (ui-specific) features. +			//			1 - it will highlight any sub-widgets that are not +			//				valid +			//			2 - it will call focus() on the first invalid  +			//				sub-widget +			var didFocus = false; +			return dojo.every(dojo.map(this.getDescendants(), function(widget){ +				// Need to set this so that "required" widgets get their  +				// state set. +				widget._hasBeenBlurred = true; +				var valid = !widget.validate || widget.validate(); +				if (!valid && !didFocus) { +					// Set focus of the first non-valid widget +					dijit.scrollIntoView(widget.containerNode||widget.domNode); +					widget.focus(); +					didFocus = true; +				} +	 			return valid; +	 		}), "return item;"); +		}, +		 +		setValues: function(/*object*/obj){ +			// summary: fill in form values from a JSON structure + +			// generate map from name --> [list of widgets with that name] +			var map = { }; +			dojo.forEach(this.getDescendants(), function(widget){ +				if(!widget.name){ return; } +				var entry = map[widget.name] || (map[widget.name] = [] ); +				entry.push(widget); +			}); + +			// call setValue() or setAttribute('checked') for each widget, according to obj +			for(var name in map){ +				var widgets = map[name],						// array of widgets w/this name +					values = dojo.getObject(name, false, obj);	// list of values for those widgets +				if(!dojo.isArray(values)){ +					values = [ values ]; +				} +				if(typeof widgets[0].checked == 'boolean'){ +					// for checkbox/radio, values is a list of which widgets should be checked +					dojo.forEach(widgets, function(w, i){ +						w.setValue(dojo.indexOf(values, w.value) != -1); +					}); +				}else if(widgets[0]._multiValue){ +					// it takes an array (e.g. multi-select) +					widgets[0].setValue(values); +				}else{ +					// otherwise, values is a list of values to be assigned sequentially to each widget +					dojo.forEach(widgets, function(w, i){ +						w.setValue(values[i]); +					});					 +				} +			} + +			/*** +			 * 	TODO: code for plain input boxes (this shouldn't run for inputs that are part of widgets) + +			dojo.forEach(this.containerNode.elements, function(element){ +				if (element.name == ''){return};	// like "continue"	 +				var namePath = element.name.split("."); +				var myObj=obj; +				var name=namePath[namePath.length-1]; +				for(var j=1,len2=namePath.length;j<len2;++j){ +					var p=namePath[j - 1]; +					// repeater support block +					var nameA=p.split("["); +					if (nameA.length > 1){ +						if(typeof(myObj[nameA[0]]) == "undefined"){ +							myObj[nameA[0]]=[ ]; +						} // if + +						nameIndex=parseInt(nameA[1]); +						if(typeof(myObj[nameA[0]][nameIndex]) == "undefined"){ +							myObj[nameA[0]][nameIndex] = { }; +						} +						myObj=myObj[nameA[0]][nameIndex]; +						continue; +					} // repeater support ends + +					if(typeof(myObj[p]) == "undefined"){ +						myObj=undefined; +						break; +					}; +					myObj=myObj[p]; +				} + +				if (typeof(myObj) == "undefined"){ +					return;		// like "continue" +				} +				if (typeof(myObj[name]) == "undefined" && this.ignoreNullValues){ +					return;		// like "continue" +				} + +				// TODO: widget values (just call setValue() on the widget) + +				switch(element.type){ +					case "checkbox": +						element.checked = (name in myObj) && +							dojo.some(myObj[name], function(val){ return val==element.value; }); +						break; +					case "radio": +						element.checked = (name in myObj) && myObj[name]==element.value; +						break; +					case "select-multiple": +						element.selectedIndex=-1; +						dojo.forEach(element.options, function(option){ +							option.selected = dojo.some(myObj[name], function(val){ return option.value == val; }); +						}); +						break; +					case "select-one": +						element.selectedIndex="0"; +						dojo.forEach(element.options, function(option){ +							option.selected = option.value == myObj[name]; +						}); +						break; +					case "hidden": +					case "text": +					case "textarea": +					case "password": +						element.value = myObj[name] || ""; +						break; +				} +	  		}); +	  		*/ +		}, + +		getValues: function(){ +			// summary: generate JSON structure from form values + +			// get widget values +			var obj = { }; +			dojo.forEach(this.getDescendants(), function(widget){ +				var name = widget.name; +				if(!name){ return; } + +				// Single value widget (checkbox, radio, or plain <input> type widget +				var value = (widget.getValue && !widget._getValueDeprecated) ? widget.getValue() : widget.value; + +				// Store widget's value(s) as a scalar, except for checkboxes which are automatically arrays +				if(typeof widget.checked == 'boolean'){ +					if(/Radio/.test(widget.declaredClass)){ +						// radio button +						if(value !== false){ +							dojo.setObject(name, value, obj); +						} +					}else{ +						// checkbox/toggle button +						var ary=dojo.getObject(name, false, obj); +						if(!ary){ +							ary=[]; +							dojo.setObject(name, ary, obj); +						} +						if(value !== false){ +							ary.push(value); +						} +					} +				}else{ +					// plain input +					dojo.setObject(name, value, obj); +				} +			}); + +			/*** +			 * code for plain input boxes (see also dojo.formToObject, can we use that instead of this code? +			 * but it doesn't understand [] notation, presumably) +			var obj = { }; +			dojo.forEach(this.containerNode.elements, function(elm){ +				if (!elm.name)	{ +					return;		// like "continue" +				} +				var namePath = elm.name.split("."); +				var myObj=obj; +				var name=namePath[namePath.length-1]; +				for(var j=1,len2=namePath.length;j<len2;++j){ +					var nameIndex = null; +					var p=namePath[j - 1]; +					var nameA=p.split("["); +					if (nameA.length > 1){ +						if(typeof(myObj[nameA[0]]) == "undefined"){ +							myObj[nameA[0]]=[ ]; +						} // if +						nameIndex=parseInt(nameA[1]); +						if(typeof(myObj[nameA[0]][nameIndex]) == "undefined"){ +							myObj[nameA[0]][nameIndex] = { }; +						} +					} else if(typeof(myObj[nameA[0]]) == "undefined"){ +						myObj[nameA[0]] = { } +					} // if + +					if (nameA.length == 1){ +						myObj=myObj[nameA[0]]; +					} else{ +						myObj=myObj[nameA[0]][nameIndex]; +					} // if +				} // for + +				if ((elm.type != "select-multiple" && elm.type != "checkbox" && elm.type != "radio") || (elm.type=="radio" && elm.checked)){ +					if(name == name.split("[")[0]){ +						myObj[name]=elm.value; +					} else{ +						// can not set value when there is no name +					} +				} else if (elm.type == "checkbox" && elm.checked){ +					if(typeof(myObj[name]) == 'undefined'){ +						myObj[name]=[ ]; +					} +					myObj[name].push(elm.value); +				} else if (elm.type == "select-multiple"){ +					if(typeof(myObj[name]) == 'undefined'){ +						myObj[name]=[ ]; +					} +					for (var jdx=0,len3=elm.options.length; jdx<len3; ++jdx){ +						if (elm.options[jdx].selected){ +							myObj[name].push(elm.options[jdx].value); +						} +					} +				} // if +				name=undefined; +			}); // forEach +			***/ +			return obj; +		}, + +		// TODO: ComboBox might need time to process a recently input value.  This should be async? +	 	isValid: function(){ +	 		// summary: make sure that every widget that has a validator function returns true +	 		return dojo.every(this.getDescendants(), function(widget){ +	 			return !widget.isValid || widget.isValid(); +	 		}); +		} +	}); + +dojo.declare( +	"dijit.form.Form", +	[dijit._Widget, dijit._Templated, dijit.form._FormMixin], +	{ +		// summary: +		// Adds conveniences to regular HTML form + +		// HTML <FORM> attributes +		name: "", +		action: "", +		method: "", +		encType: "", +		"accept-charset": "", +		accept: "", +		target: "", + +		templateString: "<form dojoAttachPoint='containerNode' dojoAttachEvent='onreset:_onReset,onsubmit:_onSubmit' name='${name}'></form>", + +		attributeMap: dojo.mixin(dojo.clone(dijit._Widget.prototype.attributeMap), +			{action: "", method: "", encType: "", "accept-charset": "", accept: "", target: ""}), + +		execute: function(/*Object*/ formContents){ +			//	summary: +			//		Deprecated: use submit() +		}, + +		onExecute: function(){ +			// summary: +			//		Deprecated: use onSubmit() +		}, + +		setAttribute: function(/*String*/ attr, /*anything*/ value){ +			this.inherited(arguments); +			switch(attr){ +				case "encType": +					if(dojo.isIE){ this.domNode.encoding = value; } +			} +		}, + +		postCreate: function(){ +			// IE tries to hide encType +			if(dojo.isIE && this.srcNodeRef && this.srcNodeRef.attributes){ +				var item = this.srcNodeRef.attributes.getNamedItem('encType'); +				if(item && !item.specified && (typeof item.value == "string")){ +					this.setAttribute('encType', item.value); +				} +			} +			this.inherited(arguments); +		}, + +		onReset: function(/*Event?*/e){  +			//	summary: +			//		Callback when user resets the form. This method is intended +			//		to be over-ridden. When the `reset` method is called +			//		programmatically, the return value from `onReset` is used +			//		to compute whether or not resetting should proceed +			return true; // Boolean +		}, + +		_onReset: function(e){ +			// create fake event so we can know if preventDefault() is called +			var faux = { +				returnValue: true, // the IE way +				preventDefault: function(){  // not IE +							this.returnValue = false; +						}, +				stopPropagation: function(){}, currentTarget: e.currentTarget, target: e.target +			}; +			// if return value is not exactly false, and haven't called preventDefault(), then reset +			if(!(this.onReset(faux) === false) && faux.returnValue){ +				this.reset(); +			} +			dojo.stopEvent(e); +			return false; +		}, + +		_onSubmit: function(e){ +			var fp = dijit.form.Form.prototype; +			// TODO: remove ths if statement beginning with 2.0 +			if(this.execute != fp.execute || this.onExecute != fp.onExecute){ +				dojo.deprecated("dijit.form.Form:execute()/onExecute() are deprecated. Use onSubmit() instead.", "", "2.0"); +				this.onExecute(); +				this.execute(this.getValues()); +			} +			if(this.onSubmit(e) === false){ // only exactly false stops submit +				dojo.stopEvent(e); +			} +		}, +		 +		onSubmit: function(/*Event?*/e){  +			//	summary: +			//		Callback when user submits the form. This method is +			//		intended to be over-ridden, but by default it checks and +			//		returns the validity of form elements. When the `submit` +			//		method is called programmatically, the return value from +			//		`onSubmit` is used to compute whether or not submission +			//		should proceed + +			return this.isValid(); // Boolean +		}, + +		submit: function(){ +			// summary: +			//		programmatically submit form if and only if the `onSubmit` returns true +			if(!(this.onSubmit() === false)){ +				this.containerNode.submit(); +			} +		} +	} +); + +} diff --git a/includes/js/dijit/form/MultiSelect.js b/includes/js/dijit/form/MultiSelect.js new file mode 100644 index 0000000..e1f468c --- /dev/null +++ b/includes/js/dijit/form/MultiSelect.js @@ -0,0 +1,84 @@ +if(!dojo._hasResource["dijit.form.MultiSelect"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. +dojo._hasResource["dijit.form.MultiSelect"] = true; +dojo.provide("dijit.form.MultiSelect"); + +dojo.require("dijit.form._FormWidget"); + +dojo.declare("dijit.form.MultiSelect",dijit.form._FormWidget,{ +	// summary: Wrapper for a native select multiple="true" element to +	//		interact with dijit.form.Form + +	// size: Number +	//		Number of elements to display on a page +	//		NOTE: may be removed in version 2.0, since elements may have variable height; +	//		set the size via style="..." or CSS class names instead. +	size: 7, +	 +	templateString: "<select multiple='true' dojoAttachPoint='containerNode,focusNode' dojoAttachEvent='onchange: _onChange'></select>", + +	attributeMap: dojo.mixin(dojo.clone(dijit.form._FormWidget.prototype.attributeMap), +		{size:"focusNode"}), + +	addSelected: function(/* dijit.form.MultiSelect */select){ +		// summary: Move the selected nodes af an passed Select widget +		//			instance to this Select widget. +		// +		// example: +		// |	// move all the selected values from "bar" to "foo" +		// | 	dijit.byId("foo").addSelected(dijit.byId("bar")); +		 +		select.getSelected().forEach(function(n){ +			this.containerNode.appendChild(n); +		},this); +	}, +					 +	getSelected: function(){ +		// summary: Access the NodeList of the selected options directly +		return dojo.query("option",this.containerNode).filter(function(n){ +			return n.selected; // Boolean +		}); +	}, +	 +	_getValueDeprecated: false, // remove when _FormWidget:_getValueDeprecated is removed in 2.0 +	getValue: function(){ +		// summary: Returns an array of the selected options' values +		return this.getSelected().map(function(n){ +			return n.value; +		}); +	}, +	 +	_multiValue: true, // for Form +	setValue: function(/* Array */values){ +		// summary: Set the value(s) of this Select based on passed values +		dojo.query("option",this.containerNode).forEach(function(n){ +			n.selected = (dojo.indexOf(values,n.value) != -1); +		}); +	}, +		 +	invertSelection: function(onChange){ +		// summary: Invert the selection +		// onChange: Boolean +		//		If null, onChange is not fired. +		dojo.query("option",this.containerNode).forEach(function(n){ +			n.selected = !n.selected; +		}); +		this._handleOnChange(this.getValue(), onChange==true); +	}, + +	_onChange: function(/*Event*/ e){ +		this._handleOnChange(this.getValue(), true); +	}, +	 +	// for layout widgets: +	resize: function(/* Object */size){ +		if(size){ +			dojo.marginBox(this.domNode, size); +		} +	}, +	 +	postCreate: function(){ +		this._onChange(); +	} +}); + +} diff --git a/includes/js/dijit/form/NumberSpinner.js b/includes/js/dijit/form/NumberSpinner.js new file mode 100644 index 0000000..a9054b0 --- /dev/null +++ b/includes/js/dijit/form/NumberSpinner.js @@ -0,0 +1,31 @@ +if(!dojo._hasResource["dijit.form.NumberSpinner"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. +dojo._hasResource["dijit.form.NumberSpinner"] = true; +dojo.provide("dijit.form.NumberSpinner"); + +dojo.require("dijit.form._Spinner"); +dojo.require("dijit.form.NumberTextBox"); + +dojo.declare( +"dijit.form.NumberSpinner", +[dijit.form._Spinner, dijit.form.NumberTextBoxMixin], +{ +	// summary: +	// extends NumberTextBox to add up/down arrows for incremental change to the value + +	required: true, + +	adjust: function(/* Object */ val, /*Number*/ delta){ +		// summary: change Number val by the given amount +		var newval = val+delta; +		if(isNaN(val) || isNaN(newval)){ return val; } +		if((typeof this.constraints.max == "number") && (newval > this.constraints.max)){ +			newval = this.constraints.max; +		} +		if((typeof this.constraints.min == "number") && (newval < this.constraints.min)){ +			newval = this.constraints.min; +		} +		return newval; +	} +}); + +} diff --git a/includes/js/dijit/form/NumberTextBox.js b/includes/js/dijit/form/NumberTextBox.js new file mode 100644 index 0000000..f8344a9 --- /dev/null +++ b/includes/js/dijit/form/NumberTextBox.js @@ -0,0 +1,79 @@ +if(!dojo._hasResource["dijit.form.NumberTextBox"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. +dojo._hasResource["dijit.form.NumberTextBox"] = true; +dojo.provide("dijit.form.NumberTextBox"); + +dojo.require("dijit.form.ValidationTextBox"); +dojo.require("dojo.number"); + +/*===== +dojo.declare( +	"dijit.form.NumberTextBox.__Constraints", +	[dijit.form.RangeBoundTextBox.__Constraints, dojo.number.__FormatOptions, dojo.number.__ParseOptions] +); +=====*/ + +dojo.declare( +	"dijit.form.NumberTextBoxMixin", +	null, +	{ +		// summary: +		//		A mixin for all number textboxes + +		regExpGen: dojo.number.regexp, + +		/*===== +		// constraints: dijit.form.NumberTextBox.__Constraints  +		constraints: {}, +		======*/ + +		// editOptions: Object +		//		properties to mix into constraints when the value is being edited +		editOptions: { pattern: '#.######' }, + +		_onFocus: function(){ +			this.setValue(this.getValue(), false);	 +			this.inherited(arguments); +		}, + +		_formatter: dojo.number.format, + +		format: function(/*Number*/ value, /*dojo.number.__FormatOptions*/ constraints){ +			//	summary: formats the value as a Number, according to constraints + +			if(typeof value == "string") { return value; } +			if(isNaN(value)){ return ""; } +			if(this.editOptions && this._focused){ +				constraints = dojo.mixin(dojo.mixin({}, this.editOptions), this.constraints); +			} +			return this._formatter(value, constraints); +		}, + +		parse: dojo.number.parse, +		/*===== +		parse: function(value, constraints){ +			//	summary: parses the value as a Number, according to constraints +			//	value: String +			// +			//	constraints: dojo.number.__ParseOptions +		}, +		=====*/ + +		filter: function(/*Number*/ value){ +			if(typeof value == "string"){ return this.inherited('filter', arguments); } +			return isNaN(value) ? '' : value; +		}, + +		value: NaN +	} +); + +dojo.declare( +	"dijit.form.NumberTextBox", +	[dijit.form.RangeBoundTextBox,dijit.form.NumberTextBoxMixin], +	{ +		// summary: +		//		A validating, serializable, range-bound text box. +	} +); + +} diff --git a/includes/js/dijit/form/SimpleTextarea.js b/includes/js/dijit/form/SimpleTextarea.js new file mode 100644 index 0000000..54db151 --- /dev/null +++ b/includes/js/dijit/form/SimpleTextarea.js @@ -0,0 +1,50 @@ +if(!dojo._hasResource["dijit.form.SimpleTextarea"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. +dojo._hasResource["dijit.form.SimpleTextarea"] = true; +dojo.provide("dijit.form.SimpleTextarea"); + +dojo.require("dijit.form._FormWidget"); + +dojo.declare("dijit.form.SimpleTextarea", +	dijit.form._FormValueWidget, +{ +	// summary: +	//		A simple textarea that degrades, and responds to +	// 		minimal LayoutContainer usage, and works with dijit.form.Form. +	//		Doesn't automatically size according to input, like Textarea. +	// +	// example: +	//	|	<textarea dojoType="dijit.form.SimpleTextarea" name="foo" value="bar" rows=30 cols=40/> +	// + +	baseClass: "dijitTextArea", + +	attributeMap: dojo.mixin(dojo.clone(dijit.form._FormValueWidget.prototype.attributeMap), +		{rows:"focusNode", cols: "focusNode"}), + +	// rows: Number +	//		The number of rows of text. +	rows: "", + +	// rows: Number +	//		The number of characters per line. +	cols: "", + +	templateString: "<textarea name='${name}' dojoAttachPoint='focusNode,containerNode'>", + +	postMixInProperties: function(){ +		if(this.srcNodeRef){ +			this.value = this.srcNodeRef.value; +		} +	}, + +	setValue: function(/*String*/ val){ +		this.domNode.value = val; +		this.inherited(arguments); +	}, + +	getValue: function(){ +		return this.domNode.value.replace(/\r/g,""); +	} +}); + +} diff --git a/includes/js/dijit/form/Slider.js b/includes/js/dijit/form/Slider.js new file mode 100644 index 0000000..2290376 --- /dev/null +++ b/includes/js/dijit/form/Slider.js @@ -0,0 +1,481 @@ +if(!dojo._hasResource["dijit.form.Slider"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. +dojo._hasResource["dijit.form.Slider"] = true; +dojo.provide("dijit.form.Slider"); + +dojo.require("dijit.form._FormWidget"); +dojo.require("dijit._Container"); +dojo.require("dojo.dnd.move"); +dojo.require("dijit.form.Button"); +dojo.require("dojo.number"); +dojo.require("dojo._base.fx"); + +dojo.declare( +	"dijit.form.HorizontalSlider", +	[dijit.form._FormValueWidget, dijit._Container], +{ +	// summary +	//	A form widget that allows one to select a value with a horizontally draggable image + +	templateString:"<table class=\"dijit dijitReset dijitSlider\" cellspacing=\"0\" cellpadding=\"0\" border=\"0\" rules=\"none\"\n\t><tr class=\"dijitReset\"\n\t\t><td class=\"dijitReset\" colspan=\"2\"></td\n\t\t><td dojoAttachPoint=\"containerNode,topDecoration\" class=\"dijitReset\" style=\"text-align:center;width:100%;\"></td\n\t\t><td class=\"dijitReset\" colspan=\"2\"></td\n\t></tr\n\t><tr class=\"dijitReset\"\n\t\t><td class=\"dijitReset dijitSliderButtonContainer dijitSliderButtonContainerH\"\n\t\t\t><div class=\"dijitSliderDecrementIconH\" tabIndex=\"-1\" style=\"display:none\" dojoAttachPoint=\"decrementButton\" dojoAttachEvent=\"onclick: decrement\"><span class=\"dijitSliderButtonInner\">-</span></div\n\t\t></td\n\t\t><td class=\"dijitReset\"\n\t\t\t><div class=\"dijitSliderBar dijitSliderBumper dijitSliderBumperH dijitSliderLeftBumper dijitSliderLeftBumper\" dojoAttachEvent=\"onclick:_onClkDecBumper\"></div\n\t\t></td\n\t\t><td class=\"dijitReset\"\n\t\t\t><input dojoAttachPoint=\"valueNode\" type=\"hidden\" name=\"${name}\"\n\t\t\t/><div waiRole=\"presentation\" style=\"position:relative;\" dojoAttachPoint=\"sliderBarContainer\"\n\t\t\t\t><div waiRole=\"presentation\" dojoAttachPoint=\"progressBar\" class=\"dijitSliderBar dijitSliderBarH dijitSliderProgressBar dijitSliderProgressBarH\" dojoAttachEvent=\"onclick:_onBarClick\"\n\t\t\t\t\t><div dojoAttachPoint=\"sliderHandle,focusNode\" class=\"dijitSliderMoveable dijitSliderMoveableH\" dojoAttachEvent=\"onkeypress:_onKeyPress,onmousedown:_onHandleClick\" waiRole=\"slider\" valuemin=\"${minimum}\" valuemax=\"${maximum}\"\n\t\t\t\t\t\t><div class=\"dijitSliderImageHandle dijitSliderImageHandleH\"></div\n\t\t\t\t\t></div\n\t\t\t\t></div\n\t\t\t\t><div waiRole=\"presentation\" dojoAttachPoint=\"remainingBar\" class=\"dijitSliderBar dijitSliderBarH dijitSliderRemainingBar dijitSliderRemainingBarH\" dojoAttachEvent=\"onclick:_onBarClick\"></div\n\t\t\t></div\n\t\t></td\n\t\t><td class=\"dijitReset\"\n\t\t\t><div class=\"dijitSliderBar dijitSliderBumper dijitSliderBumperH dijitSliderRightBumper dijitSliderRightBumper\" dojoAttachEvent=\"onclick:_onClkIncBumper\"></div\n\t\t></td\n\t\t><td class=\"dijitReset dijitSliderButtonContainer dijitSliderButtonContainerH\" style=\"right:0px;\"\n\t\t\t><div class=\"dijitSliderIncrementIconH\" tabIndex=\"-1\" style=\"display:none\" dojoAttachPoint=\"incrementButton\" dojoAttachEvent=\"onclick: increment\"><span class=\"dijitSliderButtonInner\">+</span></div\n\t\t></td\n\t></tr\n\t><tr class=\"dijitReset\"\n\t\t><td class=\"dijitReset\" colspan=\"2\"></td\n\t\t><td dojoAttachPoint=\"containerNode,bottomDecoration\" class=\"dijitReset\" style=\"text-align:center;\"></td\n\t\t><td class=\"dijitReset\" colspan=\"2\"></td\n\t></tr\n></table>\n", +	value: 0, + +	// showButtons: boolean +	//	Show increment/decrement buttons at the ends of the slider? +	showButtons: true, + +	// minimum:: integer +	//	The minimum value allowed. +	minimum: 0, + +	// maximum: integer +	//	The maximum allowed value. +	maximum: 100, + +	// discreteValues: integer +	//	The maximum allowed values dispersed evenly between minimum and maximum (inclusive). +	discreteValues: Infinity, + +	// pageIncrement: integer +	//	The amount of change with shift+arrow +	pageIncrement: 2, + +	// clickSelect: boolean +	//	If clicking the progress bar changes the value or not +	clickSelect: true, + +	// slideDuration: Number +	//	The time in ms to take to animate the slider handle from 0% to 100% +	slideDuration: 1000, + +	widgetsInTemplate: true, + +	attributeMap: dojo.mixin(dojo.clone(dijit.form._FormWidget.prototype.attributeMap), +		{id:"", name:"valueNode"}), + +	baseClass: "dijitSlider", + +	_mousePixelCoord: "pageX", +	_pixelCount: "w", +	_startingPixelCoord: "x", +	_startingPixelCount: "l", +	_handleOffsetCoord: "left", +	_progressPixelSize: "width", + +	_onKeyPress: function(/*Event*/ e){ +		if(this.disabled || this.readOnly || e.altKey || e.ctrlKey){ return; } +		switch(e.keyCode){ +			case dojo.keys.HOME: +				this.setValue(this.minimum, true); +				break; +			case dojo.keys.END: +				this.setValue(this.maximum, true); +				break; +			// this._descending === false: if ascending vertical (min on top) +			// (this._descending || this.isLeftToRight()): if left-to-right horizontal or descending vertical +			case ((this._descending || this.isLeftToRight()) ? dojo.keys.RIGHT_ARROW : dojo.keys.LEFT_ARROW): +			case (this._descending === false ? dojo.keys.DOWN_ARROW : dojo.keys.UP_ARROW): +			case (this._descending === false ? dojo.keys.PAGE_DOWN : dojo.keys.PAGE_UP): +				this.increment(e); +				break; +			case ((this._descending || this.isLeftToRight()) ? dojo.keys.LEFT_ARROW : dojo.keys.RIGHT_ARROW): +			case (this._descending === false ? dojo.keys.UP_ARROW : dojo.keys.DOWN_ARROW): +			case (this._descending === false ? dojo.keys.PAGE_UP : dojo.keys.PAGE_DOWN): +				this.decrement(e); +				break; +			default: +				this.inherited(arguments); +				return; +		} +		dojo.stopEvent(e); +	}, + +	_onHandleClick: function(e){ +		if(this.disabled || this.readOnly){ return; } +		if(!dojo.isIE){ +			// make sure you get focus when dragging the handle +			// (but don't do on IE because it causes a flicker on mouse up (due to blur then focus) +			dijit.focus(this.sliderHandle); +		} +		dojo.stopEvent(e); +	}, +	 +	_isReversed: function(){ +		return !this.isLeftToRight(); +	}, + +	_onBarClick: function(e){ +		if(this.disabled || this.readOnly || !this.clickSelect){ return; } +		dijit.focus(this.sliderHandle); +		dojo.stopEvent(e); +		var abspos = dojo.coords(this.sliderBarContainer, true); +		var pixelValue = e[this._mousePixelCoord] - abspos[this._startingPixelCoord]; +		this._setPixelValue(this._isReversed() ? (abspos[this._pixelCount] - pixelValue) : pixelValue, abspos[this._pixelCount], true); +	}, + +	_setPixelValue: function(/*Number*/ pixelValue, /*Number*/ maxPixels, /*Boolean, optional*/ priorityChange){ +		if(this.disabled || this.readOnly){ return; } +		pixelValue = pixelValue < 0 ? 0 : maxPixels < pixelValue ? maxPixels : pixelValue; +		var count = this.discreteValues; +		if(count <= 1 || count == Infinity){ count = maxPixels; } +		count--; +		var pixelsPerValue = maxPixels / count; +		var wholeIncrements = Math.round(pixelValue / pixelsPerValue); +		this.setValue((this.maximum-this.minimum)*wholeIncrements/count + this.minimum, priorityChange); +	}, + +	setValue: function(/*Number*/ value, /*Boolean, optional*/ priorityChange){ +		this.valueNode.value = this.value = value; +		dijit.setWaiState(this.focusNode, "valuenow", value); +		this.inherited(arguments); +		var percent = (value - this.minimum) / (this.maximum - this.minimum); +		var progressBar = (this._descending === false) ? this.remainingBar : this.progressBar; +		var remainingBar = (this._descending === false) ? this.progressBar : this.remainingBar; +		if(priorityChange && this.slideDuration > 0 && progressBar.style[this._progressPixelSize]){ +			// animate the slider +			var _this = this; +			var props = {}; +			var start = parseFloat(progressBar.style[this._progressPixelSize]); +			var duration = this.slideDuration * (percent-start/100); +			if(duration == 0){ return; } +			if(duration < 0){ duration = 0 - duration; } +			props[this._progressPixelSize] = { start: start, end: percent*100, units:"%" }; +			dojo.animateProperty({ node: progressBar, duration: duration,  +				onAnimate: function(v){ remainingBar.style[_this._progressPixelSize] = (100-parseFloat(v[_this._progressPixelSize])) + "%"; }, +			        properties: props +			}).play(); +		} +		else{ +			progressBar.style[this._progressPixelSize] = (percent*100) + "%"; +			remainingBar.style[this._progressPixelSize] = ((1-percent)*100) + "%"; +		} +	}, + +	_bumpValue: function(signedChange){ +		if(this.disabled || this.readOnly){ return; } +		var s = dojo.getComputedStyle(this.sliderBarContainer); +		var c = dojo._getContentBox(this.sliderBarContainer, s); +		var count = this.discreteValues; +		if(count <= 1 || count == Infinity){ count = c[this._pixelCount]; } +		count--; +		var value = (this.value - this.minimum) * count / (this.maximum - this.minimum) + signedChange; +		if(value < 0){ value = 0; } +		if(value > count){ value = count; } +		value = value * (this.maximum - this.minimum) / count + this.minimum; +		this.setValue(value, true); +	}, + +	_onClkIncBumper: function(){ +		this.setValue(this._descending === false ? this.minimum : this.maximum, true); +	}, + +	_onClkDecBumper: function(){ +		this.setValue(this._descending === false ? this.maximum : this.minimum, true); +	}, + +	decrement: function(e){ +		// summary +		//	decrement slider by 1 unit +		this._bumpValue(e.keyCode == dojo.keys.PAGE_DOWN?-this.pageIncrement:-1); +	}, + +	increment: function(e){ +		// summary +		//	increment slider by 1 unit +		this._bumpValue(e.keyCode == dojo.keys.PAGE_UP?this.pageIncrement:1); +	}, + +	_mouseWheeled: function(/*Event*/ evt){ +		dojo.stopEvent(evt); +		var scrollAmount = 0; +		if(typeof evt.wheelDelta == 'number'){ // IE +			scrollAmount = evt.wheelDelta; +		}else if(typeof evt.detail == 'number'){ // Mozilla+Firefox +			scrollAmount = -evt.detail; +		} +		if(scrollAmount > 0){ +			this.increment(evt); +		}else if(scrollAmount < 0){ +			this.decrement(evt); +		} +	}, + +	startup: function(){ +		dojo.forEach(this.getChildren(), function(child){ +			if(this[child.container] != this.containerNode){ +				this[child.container].appendChild(child.domNode); +			} +		}, this); +	}, + +	postCreate: function(){ +		if(this.showButtons){ +			this.incrementButton.style.display=""; +			this.decrementButton.style.display=""; +		} +		this.connect(this.domNode, dojo.isIE ? "onmousewheel" : 'DOMMouseScroll', "_mouseWheeled"); + +		// define a custom constructor for a SliderMover that points back to me +		var _self = this; +		var mover = function(){ +			dijit.form._SliderMover.apply(this, arguments); +			this.widget = _self; +		}; +		dojo.extend(mover, dijit.form._SliderMover.prototype); + +		this._movable = new dojo.dnd.Moveable(this.sliderHandle, {mover: mover}); +		dijit.setWaiState(this.focusNode, "valuemin", this.minimum); +		dijit.setWaiState(this.focusNode, "valuemax", this.maximum); + +		this.inherited(arguments); +	}, + +	destroy: function(){ +		this._movable.destroy(); +		this.inherited(arguments);	 +	} +}); + +dojo.declare( +	"dijit.form.VerticalSlider", +	dijit.form.HorizontalSlider, +{ +	// summary +	//	A form widget that allows one to select a value with a vertically draggable image + +	templateString:"<table class=\"dijitReset dijitSlider\" cellspacing=\"0\" cellpadding=\"0\" border=\"0\" rules=\"none\"\n><tbody class=\"dijitReset\"\n\t><tr class=\"dijitReset\"\n\t\t><td class=\"dijitReset\"></td\n\t\t><td class=\"dijitReset dijitSliderButtonContainer dijitSliderButtonContainerV\"\n\t\t\t><div class=\"dijitSliderIncrementIconV\" tabIndex=\"-1\" style=\"display:none\" dojoAttachPoint=\"incrementButton\" dojoAttachEvent=\"onclick:_topButtonClicked\"><span class=\"dijitSliderButtonInner\">+</span></div\n\t\t></td\n\t\t><td class=\"dijitReset\"></td\n\t></tr\n\t><tr class=\"dijitReset\"\n\t\t><td class=\"dijitReset\"></td\n\t\t><td class=\"dijitReset\"\n\t\t\t><center><div class=\"dijitSliderBar dijitSliderBumper dijitSliderBumperV dijitSliderTopBumper dijitSliderTopBumper\" dojoAttachEvent=\"onclick:_onClkIncBumper\"></div></center\n\t\t></td\n\t\t><td class=\"dijitReset\"></td\n\t></tr\n\t><tr class=\"dijitReset\"\n\t\t><td dojoAttachPoint=\"leftDecoration\" class=\"dijitReset\" style=\"text-align:center;height:100%;\"></td\n\t\t><td class=\"dijitReset\" style=\"height:100%;\"\n\t\t\t><input dojoAttachPoint=\"valueNode\" type=\"hidden\" name=\"${name}\"\n\t\t\t/><center waiRole=\"presentation\" style=\"position:relative;height:100%;\" dojoAttachPoint=\"sliderBarContainer\"\n\t\t\t\t><div waiRole=\"presentation\" dojoAttachPoint=\"remainingBar\" class=\"dijitSliderBar dijitSliderBarV dijitSliderRemainingBar dijitSliderRemainingBarV\" dojoAttachEvent=\"onclick:_onBarClick\"><!--#5629--></div\n\t\t\t\t><div waiRole=\"presentation\" dojoAttachPoint=\"progressBar\" class=\"dijitSliderBar dijitSliderBarV dijitSliderProgressBar dijitSliderProgressBarV\" dojoAttachEvent=\"onclick:_onBarClick\"\n\t\t\t\t\t><div dojoAttachPoint=\"sliderHandle,focusNode\" class=\"dijitSliderMoveable\" dojoAttachEvent=\"onkeypress:_onKeyPress,onmousedown:_onHandleClick\" style=\"vertical-align:top;\" waiRole=\"slider\" valuemin=\"${minimum}\" valuemax=\"${maximum}\"\n\t\t\t\t\t\t><div class=\"dijitSliderImageHandle dijitSliderImageHandleV\"></div\n\t\t\t\t\t></div\n\t\t\t\t></div\n\t\t\t></center\n\t\t></td\n\t\t><td dojoAttachPoint=\"containerNode,rightDecoration\" class=\"dijitReset\" style=\"text-align:center;height:100%;\"></td\n\t></tr\n\t><tr class=\"dijitReset\"\n\t\t><td class=\"dijitReset\"></td\n\t\t><td class=\"dijitReset\"\n\t\t\t><center><div class=\"dijitSliderBar dijitSliderBumper dijitSliderBumperV dijitSliderBottomBumper dijitSliderBottomBumper\" dojoAttachEvent=\"onclick:_onClkDecBumper\"></div></center\n\t\t></td\n\t\t><td class=\"dijitReset\"></td\n\t></tr\n\t><tr class=\"dijitReset\"\n\t\t><td class=\"dijitReset\"></td\n\t\t><td class=\"dijitReset dijitSliderButtonContainer dijitSliderButtonContainerV\"\n\t\t\t><div class=\"dijitSliderDecrementIconV\" tabIndex=\"-1\" style=\"display:none\" dojoAttachPoint=\"decrementButton\" dojoAttachEvent=\"onclick:_bottomButtonClicked\"><span class=\"dijitSliderButtonInner\">-</span></div\n\t\t></td\n\t\t><td class=\"dijitReset\"></td\n\t></tr\n></tbody></table>\n", +	_mousePixelCoord: "pageY", +	_pixelCount: "h", +	_startingPixelCoord: "y", +	_startingPixelCount: "t", +	_handleOffsetCoord: "top", +	_progressPixelSize: "height", + +	// _descending: boolean +	//      Specifies if the slider values go from high-on-top (true), or low-on-top (false) +	//	TODO: expose this in 1.2 - the css progress/remaining bar classes need to be reversed +	_descending: true, + +	startup: function(){ +		if(this._started){ return; } + +		if(!this.isLeftToRight() && dojo.isMoz){ +			if(this.leftDecoration){this._rtlRectify(this.leftDecoration);} +			if(this.rightDecoration){this._rtlRectify(this.rightDecoration);} +		} + +		this.inherited(arguments); +	}, +		 +	_isReversed: function(){ +		return this._descending; +	}, + +	_topButtonClicked: function(e){ +		if(this._descending){ +			this.increment(e); +		}else{ +			this.decrement(e); +		} +	}, + +	_bottomButtonClicked: function(e){ +		if(this._descending){ +			this.decrement(e); +		}else{ +			this.increment(e); +		} +	}, + +	_rtlRectify: function(decorationNode/*NodeList*/){ +		// summary: +		//      Rectify children nodes for left/right decoration in rtl case. +		//		Simply switch the rule and label child for each decoration node. +		var childNodes = []; +		while(decorationNode.firstChild){ +				childNodes.push(decorationNode.firstChild); +				decorationNode.removeChild(decorationNode.firstChild); +		} +		for(var i = childNodes.length-1; i >=0; i--){ +			if(childNodes[i]){ +				decorationNode.appendChild(childNodes[i]); +			} +		} +	} +}); + +dojo.declare("dijit.form._SliderMover", +	dojo.dnd.Mover, +{ +	onMouseMove: function(e){ +		var widget = this.widget; +		var abspos = widget._abspos; +		if(!abspos){ +			abspos = widget._abspos = dojo.coords(widget.sliderBarContainer, true); +			widget._setPixelValue_ = dojo.hitch(widget, "_setPixelValue"); +			widget._isReversed_ = widget._isReversed(); +		} +		var pixelValue = e[widget._mousePixelCoord] - abspos[widget._startingPixelCoord]; +		widget._setPixelValue_(widget._isReversed_ ? (abspos[widget._pixelCount]-pixelValue) : pixelValue, abspos[widget._pixelCount], false); +	}, +	 +	destroy: function(e){ +		dojo.dnd.Mover.prototype.destroy.apply(this, arguments); +		var widget = this.widget; +		widget.setValue(widget.value, true); +	} +}); + + +dojo.declare("dijit.form.HorizontalRule", [dijit._Widget, dijit._Templated], +{ +	//	Summary: +	//		Create hash marks for the Horizontal slider +	templateString: '<div class="dijitRuleContainer dijitRuleContainerH"></div>', + +	// count: Integer +	//		Number of hash marks to generate +	count: 3, + +	// container: Node +	//		If this is a child widget, connect it to this parent node +	container: "containerNode", + +	// ruleStyle: String +	//		CSS style to apply to individual hash marks +	ruleStyle: "", + +	_positionPrefix: '<div class="dijitRuleMark dijitRuleMarkH" style="left:', +	_positionSuffix: '%;', +	_suffix: '"></div>', + +	_genHTML: function(pos, ndx){ +		return this._positionPrefix + pos + this._positionSuffix + this.ruleStyle + this._suffix; +	}, +	 +	_isHorizontal: true, + +	postCreate: function(){ +		var innerHTML; +		if(this.count==1){ +			innerHTML = this._genHTML(50, 0); +		}else{ +			var i; +			var interval = 100 / (this.count-1); +			if(!this._isHorizontal || this.isLeftToRight()){ +				innerHTML = this._genHTML(0, 0); +				for(i=1; i < this.count-1; i++){ +					innerHTML += this._genHTML(interval*i, i); +				} +				innerHTML += this._genHTML(100, this.count-1); +			}else{ +				innerHTML = this._genHTML(100, 0); +				for(i=1; i < this.count-1; i++){ +					innerHTML += this._genHTML(100-interval*i, i); +				} +				innerHTML += this._genHTML(0, this.count-1); +			} +		} +		this.domNode.innerHTML = innerHTML; +	} +}); + +dojo.declare("dijit.form.VerticalRule", dijit.form.HorizontalRule, +{ +	//	Summary: +	//		Create hash marks for the Vertical slider +	templateString: '<div class="dijitRuleContainer dijitRuleContainerV"></div>', +	_positionPrefix: '<div class="dijitRuleMark dijitRuleMarkV" style="top:', +	 +	_isHorizontal: false +}); + +dojo.declare("dijit.form.HorizontalRuleLabels", dijit.form.HorizontalRule, +{ +	//	Summary: +	//		Create labels for the Horizontal slider +	templateString: '<div class="dijitRuleContainer dijitRuleContainerH"></div>', + +	// labelStyle: String +	//		CSS style to apply to individual text labels +	labelStyle: "", + +	// labels: Array +	//	Array of text labels to render - evenly spaced from left-to-right or bottom-to-top +	labels: [], + +	// numericMargin: Integer +	//	Number of generated numeric labels that should be rendered as '' on the ends when labels[] are not specified +	numericMargin: 0, + +	// numericMinimum: Integer +	//	Leftmost label value for generated numeric labels when labels[] are not specified +	minimum: 0, + +	// numericMaximum: Integer +	//	Rightmost label value for generated numeric labels when labels[] are not specified +	maximum: 1, + +	// constraints: object +	//	pattern, places, lang, et al (see dojo.number) for generated numeric labels when labels[] are not specified +	constraints: {pattern:"#%"}, + +	_positionPrefix: '<div class="dijitRuleLabelContainer dijitRuleLabelContainerH" style="left:', +	_labelPrefix: '"><span class="dijitRuleLabel dijitRuleLabelH">', +	_suffix: '</span></div>', + +	_calcPosition: function(pos){ +		return pos; +	}, + +	_genHTML: function(pos, ndx){ +		return this._positionPrefix + this._calcPosition(pos) + this._positionSuffix + this.labelStyle + this._labelPrefix + this.labels[ndx] + this._suffix; +	}, + +	getLabels: function(){ +		// summary: user replaceable function to return the labels array + +		// if the labels array was not specified directly, then see if <li> children were +		var labels = this.labels; +		if(!labels.length){ +			// for markup creation, labels are specified as child elements +			labels = dojo.query("> li", this.srcNodeRef).map(function(node){ +				return String(node.innerHTML); +			}); +		} +		this.srcNodeRef.innerHTML = ''; +		// if the labels were not specified directly and not as <li> children, then calculate numeric labels +		if(!labels.length && this.count > 1){ +			var start = this.minimum; +			var inc = (this.maximum - start) / (this.count-1); +			for (var i=0; i < this.count; i++){ +				labels.push((i<this.numericMargin||i>=(this.count-this.numericMargin))? '' : dojo.number.format(start, this.constraints)); +				start += inc; +			} +		} +		return labels; +	}, + +	postMixInProperties: function(){ +		this.inherited(arguments); +		this.labels = this.getLabels(); +		this.count = this.labels.length; +	} +}); + +dojo.declare("dijit.form.VerticalRuleLabels", dijit.form.HorizontalRuleLabels, +{ +	//	Summary: +	//		Create labels for the Vertical slider +	templateString: '<div class="dijitRuleContainer dijitRuleContainerV"></div>', + +	_positionPrefix: '<div class="dijitRuleLabelContainer dijitRuleLabelContainerV" style="top:', +	_labelPrefix: '"><span class="dijitRuleLabel dijitRuleLabelV">', + +	_calcPosition: function(pos){ +		return 100-pos; +	}, +	 +	_isHorizontal: false +}); + +} diff --git a/includes/js/dijit/form/TextBox.js b/includes/js/dijit/form/TextBox.js new file mode 100644 index 0000000..f36aff4 --- /dev/null +++ b/includes/js/dijit/form/TextBox.js @@ -0,0 +1,185 @@ +if(!dojo._hasResource["dijit.form.TextBox"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. +dojo._hasResource["dijit.form.TextBox"] = true; +dojo.provide("dijit.form.TextBox"); + +dojo.require("dijit.form._FormWidget"); + +dojo.declare( +	"dijit.form.TextBox", +	dijit.form._FormValueWidget, +	{ +		//	summary: +		//		A base class for textbox form inputs +		// +		//	trim: Boolean +		//		Removes leading and trailing whitespace if true.  Default is false. +		trim: false, + +		//	uppercase: Boolean +		//		Converts all characters to uppercase if true.  Default is false. +		uppercase: false, + +		//	lowercase: Boolean +		//		Converts all characters to lowercase if true.  Default is false. +		lowercase: false, + +		//	propercase: Boolean +		//		Converts the first character of each word to uppercase if true. +		propercase: false, + +		//	maxLength: String +		//		HTML INPUT tag maxLength declaration. +		maxLength: "", + +		templateString:"<input class=\"dijit dijitReset dijitLeft\" dojoAttachPoint='textbox,focusNode' name=\"${name}\"\n\tdojoAttachEvent='onmouseenter:_onMouse,onmouseleave:_onMouse,onfocus:_onMouse,onblur:_onMouse,onkeypress:_onKeyPress,onkeyup'\n\tautocomplete=\"off\" type=\"${type}\"\n\t/>\n", +		baseClass: "dijitTextBox", + +		attributeMap: dojo.mixin(dojo.clone(dijit.form._FormValueWidget.prototype.attributeMap), +			{maxLength:"focusNode"}), + +		getDisplayedValue: function(){ +			//	summary: +			//		Returns the formatted value that the user sees in the textbox, which may be different +			//		from the serialized value that's actually sent to the server (see dijit.form.ValidationTextBox.serialize) +			return this.filter(this.textbox.value); +		}, + +		getValue: function(){ +			return this.parse(this.getDisplayedValue(), this.constraints); +		}, + +		setValue: function(value, /*Boolean?*/ priorityChange, /*String?*/ formattedValue){ +			//	summary:  +			//		Sets the value of the widget to "value" which can be of +			//		any type as determined by the widget. +			// +			//	value: +			//		The visual element value is also set to a corresponding, +			//		but not necessarily the same, value. +			// +			//	formattedValue: +			//		If specified, used to set the visual element value, +			//		otherwise a computed visual value is used. +			// +			//	priorityChange: +			//		If true, an onChange event is fired immediately instead of  +			//		waiting for the next blur event. + +			var filteredValue = this.filter(value); +			if((((typeof filteredValue == typeof value) && (value !== undefined/*#5317*/)) || (value === null/*#5329*/)) && (formattedValue == null || formattedValue == undefined)){ +				formattedValue = this.format(filteredValue, this.constraints); +			} +			if(formattedValue != null && formattedValue != undefined){ +				this.textbox.value = formattedValue; +			} +			dijit.form.TextBox.superclass.setValue.call(this, filteredValue, priorityChange); +		}, + +		setDisplayedValue: function(/*String*/value, /*Boolean?*/ priorityChange){ +			//	summary:  +			//		Sets the value of the visual element to the string "value". +			//		The widget value is also set to a corresponding, +			//		but not necessarily the same, value. +			// +			//	priorityChange: +			//		If true, an onChange event is fired immediately instead of  +			//		waiting for the next blur event. + +			this.textbox.value = value; +			this.setValue(this.getValue(), priorityChange); +		}, + +		format: function(/* String */ value, /* Object */ constraints){ +			//	summary: +			//		Replacable function to convert a value to a properly formatted string +			return ((value == null || value == undefined) ? "" : (value.toString ? value.toString() : value)); +		}, + +		parse: function(/* String */ value, /* Object */ constraints){ +			//	summary: +			//		Replacable function to convert a formatted string to a value +			return value; +		}, + +		postCreate: function(){ +			// setting the value here is needed since value="" in the template causes "undefined" +			// and setting in the DOM (instead of the JS object) helps with form reset actions +			this.textbox.setAttribute("value", this.getDisplayedValue()); +			this.inherited(arguments); + +			/*#5297:if(this.srcNodeRef){ +				dojo.style(this.textbox, "cssText", this.style); +				this.textbox.className += " " + this["class"]; +			}*/ +			this._layoutHack(); +		}, + +		filter: function(val){ +			//	summary: +			//		Apply specified filters to textbox value +			if(val === null || val === undefined){ return ""; } +			else if(typeof val != "string"){ return val; } +			if(this.trim){ +				val = dojo.trim(val); +			} +			if(this.uppercase){ +				val = val.toUpperCase(); +			} +			if(this.lowercase){ +				val = val.toLowerCase(); +			} +			if(this.propercase){ +				val = val.replace(/[^\s]+/g, function(word){ +					return word.substring(0,1).toUpperCase() + word.substring(1); +				}); +			} +			return val; +		}, + +		_setBlurValue: function(){ +			this.setValue(this.getValue(), (this.isValid ? this.isValid() : true)); +		}, + +		_onBlur: function(){ +			this._setBlurValue(); +			this.inherited(arguments); +		}, + +		onkeyup: function(){ +			//	summary: +			//		User replaceable keyup event handler +		} +	} +); + +dijit.selectInputText = function(/*DomNode*/element, /*Number?*/ start, /*Number?*/ stop){ +	//	summary: +	//		Select text in the input element argument, from start (default 0), to stop (default end). + +	// TODO: use functions in _editor/selection.js? +	var _window = dojo.global; +	var _document = dojo.doc; +	element = dojo.byId(element); +	if(isNaN(start)){ start = 0; } +	if(isNaN(stop)){ stop = element.value ? element.value.length : 0; } +	element.focus(); +	if(_document["selection"] && dojo.body()["createTextRange"]){ // IE +		if(element.createTextRange){ +			var range = element.createTextRange(); +			with(range){ +				collapse(true); +				moveStart("character", start); +				moveEnd("character", stop); +				select(); +			} +		} +	}else if(_window["getSelection"]){ +		var selection = _window.getSelection(); +		// FIXME: does this work on Safari? +		if(element.setSelectionRange){ +			element.setSelectionRange(start, stop); +		} +	} +} + +} diff --git a/includes/js/dijit/form/Textarea.js b/includes/js/dijit/form/Textarea.js new file mode 100644 index 0000000..b879aae --- /dev/null +++ b/includes/js/dijit/form/Textarea.js @@ -0,0 +1,261 @@ +if(!dojo._hasResource["dijit.form.Textarea"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. +dojo._hasResource["dijit.form.Textarea"] = true; +dojo.provide("dijit.form.Textarea"); + +dojo.require("dijit.form._FormWidget"); +dojo.require("dojo.i18n"); +dojo.requireLocalization("dijit.form", "Textarea", null, "zh,pt,da,tr,ru,de,ROOT,sv,ja,he,fi,nb,el,ar,pt-pt,cs,fr,es,ko,nl,zh-tw,pl,it,hu"); + +dojo.declare( +	"dijit.form.Textarea", +	dijit.form._FormValueWidget, +	{ +	// summary: A resizing textarea widget +	// +	// description: +	//	A textarea that resizes vertically to contain the data. +	//	Takes nearly all the parameters (name, value, etc.) that a vanilla textarea takes. +	//	Cols is not supported and the width should be specified with style width. +	//	Rows is not supported since this widget adjusts the height. +	// +	// example: +	// |	<textarea dojoType="dijit.form.TextArea">...</textarea> +	// + +	attributeMap: dojo.mixin(dojo.clone(dijit.form._FormValueWidget.prototype.attributeMap), +		{style:"styleNode", 'class':"styleNode"}), + +	templateString: (dojo.isIE || dojo.isSafari || dojo.isFF) ? +				((dojo.isIE || dojo.isSafari || dojo.isFF >= 3) ? '<fieldset id="${id}" class="dijitInline dijitInputField dijitTextArea" dojoAttachPoint="styleNode" waiRole="presentation"><div dojoAttachPoint="editNode,focusNode,eventNode" dojoAttachEvent="onpaste:_changing,oncut:_changing" waiRole="textarea" style="text-decoration:none;display:block;overflow:auto;" contentEditable="true"></div>' +					: '<span id="${id}" class="dijitReset">'+ +					'<iframe src="javascript:<html><head><title>${_iframeEditTitle}</title></head><body><script>var _postCreate=window.frameElement?window.frameElement.postCreate:null;if(_postCreate)_postCreate();</script></body></html>"'+ +							' dojoAttachPoint="iframe,styleNode" dojoAttachEvent="onblur:_onIframeBlur" class="dijitInline dijitInputField dijitTextArea"></iframe>') +				+ '<textarea name="${name}" value="${value}" dojoAttachPoint="formValueNode" style="display:none;"></textarea>' +				+ ((dojo.isIE || dojo.isSafari || dojo.isFF >= 3) ? '</fieldset>':'</span>') +			: '<textarea id="${id}" name="${name}" value="${value}" dojoAttachPoint="formValueNode,editNode,focusNode,styleNode" class="dijitInputField dijitTextArea">'+dojo.isFF+'</textarea>', + +	setAttribute: function(/*String*/ attr, /*anything*/ value){ +		this.inherited(arguments); +		switch(attr){ +			case "disabled": +				this.formValueNode.disabled = this.disabled; +			case "readOnly": +				if(dojo.isIE || dojo.isSafari || dojo.isFF >= 3){ +					this.editNode.contentEditable = (!this.disabled && !this.readOnly); +				}else if(dojo.isFF){ +					this.iframe.contentDocument.designMode = (this.disabled || this.readOnly)? "off" : "on"; +				} +		} +	}, + +	focus: function(){ +		// summary: Received focus, needed for the InlineEditBox widget +		if(!this.disabled && !this.readOnly){ +			this._changing(); // set initial height +		} +		dijit.focus(this.iframe || this.focusNode); +	}, + +	setValue: function(/*String*/ value, /*Boolean, optional*/ priorityChange){ +		var editNode = this.editNode; +		if(typeof value == "string"){ +			editNode.innerHTML = ""; // wipe out old nodes +			if(value.split){ +				var _this=this; +				var isFirst = true; +				dojo.forEach(value.split("\n"), function(line){ +					if(isFirst){ isFirst = false; } +					else{ +						editNode.appendChild(dojo.doc.createElement("BR")); // preserve line breaks +					} +					if(line){ +						editNode.appendChild(dojo.doc.createTextNode(line)); // use text nodes so that imbedded tags can be edited +					} +				}); +			}else if(value){ +				editNode.appendChild(dojo.doc.createTextNode(value)); +			} +			if(!dojo.isIE){ +				editNode.appendChild(dojo.doc.createElement("BR")); // so that you see a cursor +			} +		}else{ +			// blah<BR>blah --> blah\nblah +			// <P>blah</P><P>blah</P> --> blah\nblah +			// <DIV>blah</DIV><DIV>blah</DIV> --> blah\nblah +			// &<> -->&< > +			value = editNode.innerHTML; +			if(this.iframe){ // strip sizeNode +				value = value.replace(/<div><\/div>\r?\n?$/i,""); +			} +			value = value.replace(/\s*\r?\n|^\s+|\s+$| /g,"").replace(/>\s+</g,"><").replace(/<\/(p|div)>$|^<(p|div)[^>]*>/gi,"").replace(/([^>])<div>/g,"$1\n").replace(/<\/p>\s*<p[^>]*>|<br[^>]*>|<\/div>\s*<div[^>]*>/gi,"\n").replace(/<[^>]*>/g,"").replace(/&/gi,"\&").replace(/</gi,"<").replace(/>/gi,">"); +			if(!dojo.isIE){ +				value = value.replace(/\n$/,""); // remove added <br> +			} +		} +		this.value = this.formValueNode.value = value; +		if(this.iframe){ +			var sizeNode = dojo.doc.createElement('div'); +			editNode.appendChild(sizeNode); +			var newHeight = sizeNode.offsetTop; +			if(editNode.scrollWidth > editNode.clientWidth){ newHeight+=16; } // scrollbar space needed? +			if(this.lastHeight != newHeight){ // cache size so that we don't get a resize event because of a resize event +				if(newHeight == 0){ newHeight = 16; } // height = 0 causes the browser to not set scrollHeight +				dojo.contentBox(this.iframe, {h: newHeight}); +				this.lastHeight = newHeight; +			} +			editNode.removeChild(sizeNode); +		} +		dijit.form.Textarea.superclass.setValue.call(this, this.getValue(), priorityChange); +	}, + +	getValue: function(){ +		return this.value.replace(/\r/g,""); +	}, + +	postMixInProperties: function(){ +		this.inherited(arguments); +		// don't let the source text be converted to a DOM structure since we just want raw text +		if(this.srcNodeRef && this.srcNodeRef.innerHTML != ""){ +			this.value = this.srcNodeRef.innerHTML; +			this.srcNodeRef.innerHTML = ""; +		} +		if((!this.value || this.value == "") && this.srcNodeRef && this.srcNodeRef.value){ +			this.value = this.srcNodeRef.value; +		} +		if(!this.value){ this.value = ""; } +		this.value = this.value.replace(/\r\n/g,"\n").replace(/>/g,">").replace(/</g,"<").replace(/&/g,"&"); +		if(dojo.isFF == 2){ +			// In the case of Firefox an iframe is used and when the text gets focus, +			// focus is fired from the document object.  There isn't a way to put a +			// waiRole on the document object and as a result screen readers don't +			// announce the role.  As a result screen reader users are lost. +			// +			// An additional problem is that the browser gives the document object a +			// very cryptic accessible name, e.g. +			// wysiwyg://13/http://archive.dojotoolkit.org/nightly/dojotoolkit/dijit/tests/form/test_InlineEditBox.html +			// When focus is fired from the document object, the screen reader speaks +			// the accessible name.  The cyptic accessile name is confusing. +			// +			// A workaround for both of these problems is to give the iframe's +			// document a title, the name of which is similar to a role name, i.e. +			// "edit area".  This will be used as the accessible name which will replace +			// the cryptic name and will also convey the role information to the user. +			// Because it is read directly to the user, the string must be localized. +			// In addition, since a <label> element can not be associated with an iframe, if  +			// this control has a label, insert the label text into the title as well. +			var _nlsResources = dojo.i18n.getLocalization("dijit.form", "Textarea"); +			this._iframeEditTitle = _nlsResources.iframeEditTitle; +			this._iframeFocusTitle = _nlsResources.iframeFocusTitle; +			var label=dojo.query('label[for="'+this.id+'"]'); +			if(label.length){ +				this._iframeEditTitle = label[0].innerHTML + " " + this._iframeEditTitle; +			} +			var body = this.focusNode = this.editNode = dojo.doc.createElement('BODY'); +			body.style.margin="0px"; +			body.style.padding="0px"; +			body.style.border="0px"; +		} +	}, + +	postCreate: function(){ +		if(dojo.isIE || dojo.isSafari || dojo.isFF >= 3){ +			this.domNode.style.overflowY = 'hidden'; +		}else if(dojo.isFF){ +			var w = this.iframe.contentWindow; +			var title = ''; +			try { // #4715: peeking at the title can throw a security exception during iframe setup +				title = this.iframe.contentDocument.title; +			} catch(e) {} +			if(!w || !title){ +				this.iframe.postCreate = dojo.hitch(this, this.postCreate); +				return; +			} +			var d = w.document; +			d.getElementsByTagName('HTML')[0].replaceChild(this.editNode, d.getElementsByTagName('BODY')[0]); +			if(!this.isLeftToRight()){ +				d.getElementsByTagName('HTML')[0].dir = "rtl"; +			}			 +			this.iframe.style.overflowY = 'hidden'; +			this.eventNode = d; +			// this.connect won't destroy this handler cleanly since its on the iframe's window object +			// resize is a method of window, not document +			w.addEventListener("resize", dojo.hitch(this, this._changed), false); // resize is only on the window object +		}else{ +			this.focusNode = this.domNode; +		} +		if(this.eventNode){ +			this.connect(this.eventNode, "keypress", this._onKeyPress); +			this.connect(this.eventNode, "mousemove", this._changed); +			this.connect(this.eventNode, "focus", this._focused); +			this.connect(this.eventNode, "blur", this._blurred); +		} +		if(this.editNode){ +			this.connect(this.editNode, "change", this._changed); // needed for mouse paste events per #3479 +		} +		this.inherited('postCreate', arguments); +	}, + +	// event handlers, you can over-ride these in your own subclasses +	_focused: function(e){ +		dojo.addClass(this.iframe||this.domNode, "dijitInputFieldFocused"); +		this._changed(e); +	}, + +	_blurred: function(e){ +		dojo.removeClass(this.iframe||this.domNode, "dijitInputFieldFocused"); +		this._changed(e, true); +	}, + +	_onIframeBlur: function(){ +		// Reset the title back to "edit area". +		this.iframe.contentDocument.title = this._iframeEditTitle; +	}, + +	_onKeyPress: function(e){ +		if(e.keyCode == dojo.keys.TAB && !e.shiftKey && !e.ctrlKey && !e.altKey && this.iframe){ +			// Pressing the tab key in the iframe (with designMode on) will cause the +			// entry of a tab character so we have to trap that here.  Since we don't +			// know the next focusable object we put focus on the iframe and then the +			// user has to press tab again (which then does the expected thing). +			// A problem with that is that the screen reader user hears "edit area" +			// announced twice which causes confusion.  By setting the +			// contentDocument's title to "edit area frame" the confusion should be +			// eliminated. +			this.iframe.contentDocument.title = this._iframeFocusTitle; +			// Place focus on the iframe. A subsequent tab or shift tab will put focus +			// on the correct control. +			// Note: Can't use this.focus() because that results in a call to +			// dijit.focus and if that receives an iframe target it will set focus +			// on the iframe's contentWindow. +			this.iframe.focus();  // this.focus(); won't work +			dojo.stopEvent(e); +		}else if(e.keyCode == dojo.keys.ENTER){ +			e.stopPropagation(); +		}else if(this.inherited("_onKeyPress", arguments) && this.iframe){ +			// #3752: +			// The key press will not make it past the iframe. +			// If a widget is listening outside of the iframe, (like InlineEditBox) +			// it will not hear anything. +			// Create an equivalent event so everyone else knows what is going on. +			var te = dojo.doc.createEvent("KeyEvents"); +			te.initKeyEvent("keypress", true, true, null, e.ctrlKey, e.altKey, e.shiftKey, e.metaKey, e.keyCode, e.charCode); +			this.iframe.dispatchEvent(te); +		} +		this._changing(); +	}, + +	_changing: function(e){ +		// summary: event handler for when a change is imminent +		setTimeout(dojo.hitch(this, "_changed", e, false), 1); +	}, + +	_changed: function(e, priorityChange){ +		// summary: event handler for when a change has already happened +		if(this.iframe && this.iframe.contentDocument.designMode != "on" && !this.disabled && !this.readOnly){ +			this.iframe.contentDocument.designMode="on"; // in case this failed on init due to being hidden +		} +		this.setValue(null, priorityChange || false); +	} +}); + +} diff --git a/includes/js/dijit/form/TimeTextBox.js b/includes/js/dijit/form/TimeTextBox.js new file mode 100644 index 0000000..1774e61 --- /dev/null +++ b/includes/js/dijit/form/TimeTextBox.js @@ -0,0 +1,33 @@ +if(!dojo._hasResource["dijit.form.TimeTextBox"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. +dojo._hasResource["dijit.form.TimeTextBox"] = true; +dojo.provide("dijit.form.TimeTextBox"); + +dojo.require("dijit._TimePicker"); +dojo.require("dijit.form._DateTimeTextBox"); + +/*===== +dojo.declare( +	"dijit.form.TimeTextBox.__Constraints", +	[dijit.form._DateTimeTextBox.__Constraints, dijit._TimePicker.__Constraints] +); +=====*/ + +dojo.declare( +	"dijit.form.TimeTextBox", +	dijit.form._DateTimeTextBox, +	{ +		// summary: +		//		A validating, serializable, range-bound time text box with a popup time picker + +		popupClass: "dijit._TimePicker", +		_selector: "time" + +/*===== +		, +		// constraints: dijit.form.TimeTextBox.__Constraints  +		constraints:{} +=====*/ +	} +); + +} diff --git a/includes/js/dijit/form/ValidationTextBox.js b/includes/js/dijit/form/ValidationTextBox.js new file mode 100644 index 0000000..4f354d0 --- /dev/null +++ b/includes/js/dijit/form/ValidationTextBox.js @@ -0,0 +1,308 @@ +if(!dojo._hasResource["dijit.form.ValidationTextBox"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. +dojo._hasResource["dijit.form.ValidationTextBox"] = true; +dojo.provide("dijit.form.ValidationTextBox"); + +dojo.require("dojo.i18n"); + +dojo.require("dijit.form.TextBox"); +dojo.require("dijit.Tooltip"); + +dojo.requireLocalization("dijit.form", "validate", null, "zh,pt,da,tr,ru,de,sv,ja,he,fi,nb,el,ar,pt-pt,ROOT,cs,fr,es,ko,nl,zh-tw,pl,it,hu"); + +/*===== +	dijit.form.ValidationTextBox.__Constraints = function(){ +		// locale: String +		//		locale used for validation, picks up value from this widget's lang attribute +		// _flags_: anything +		//		various flags passed to regExpGen function +		this.locale = ""; +		this._flags_ = ""; +	} +=====*/ + +dojo.declare( +	"dijit.form.ValidationTextBox", +	dijit.form.TextBox, +	{ +		// summary: +		//		A TextBox subclass with the ability to validate content of various types and provide user feedback. + +		templateString:"<div class=\"dijit dijitReset dijitInlineTable dijitLeft\"\n\tid=\"widget_${id}\"\n\tdojoAttachEvent=\"onmouseenter:_onMouse,onmouseleave:_onMouse,onmousedown:_onMouse\" waiRole=\"presentation\"\n\t><div style=\"overflow:hidden;\"\n\t\t><div class=\"dijitReset dijitValidationIcon\"><br></div\n\t\t><div class=\"dijitReset dijitValidationIconText\">Χ</div\n\t\t><div class=\"dijitReset dijitInputField\"\n\t\t\t><input class=\"dijitReset\" dojoAttachPoint='textbox,focusNode' dojoAttachEvent='onfocus:_update,onkeyup:_onkeyup,onblur:_onMouse,onkeypress:_onKeyPress' autocomplete=\"off\"\n\t\t\ttype='${type}' name='${name}'\n\t\t/></div\n\t></div\n></div>\n", +		baseClass: "dijitTextBox", + +		// default values for new subclass properties +		// required: Boolean +		//		Can be true or false, default is false. +		required: false, + +		// promptMessage: String +		//		Hint string +		promptMessage: "", + +		// invalidMessage: String +		// 		The message to display if value is invalid. +		invalidMessage: "$_unset_$", // read from the message file if not overridden + +		// constraints: dijit.form.ValidationTextBox.__Constraints +		//		user-defined object needed to pass parameters to the validator functions +		constraints: {}, + +		// regExp: String +		//		regular expression string used to validate the input +		//		Do not specify both regExp and regExpGen +		regExp: ".*", + +		// regExpGen: Function +		//		user replaceable function used to generate regExp when dependent on constraints +		//		Do not specify both regExp and regExpGen +		regExpGen: function(/*dijit.form.ValidationTextBox.__Constraints*/constraints){ return this.regExp; }, + +		// state: String +		//		Shows current state (ie, validation result) of input (Normal, Warning, or Error) +		state: "", + +		//	tooltipPosition: String[] +		//		See description of dijit.Tooltip.defaultPosition for details on this parameter. +		tooltipPosition: [], + +		setValue: function(){ +			this.inherited(arguments); +			this.validate(this._focused); +		}, + +		validator: function(/*anything*/value, /*dijit.form.ValidationTextBox.__Constraints*/constraints){ +			// summary: user replaceable function used to validate the text input against the regular expression. +			return (new RegExp("^(" + this.regExpGen(constraints) + ")"+(this.required?"":"?")+"$")).test(value) && +				(!this.required || !this._isEmpty(value)) && +				(this._isEmpty(value) || this.parse(value, constraints) !== undefined); // Boolean +		}, + +		isValid: function(/*Boolean*/ isFocused){ +			// summary: Need to over-ride with your own validation code in subclasses +			return this.validator(this.textbox.value, this.constraints); +		}, + +		_isEmpty: function(value){ +			// summary: Checks for whitespace +			return /^\s*$/.test(value); // Boolean +		}, + +		getErrorMessage: function(/*Boolean*/ isFocused){ +			// summary: return an error message to show if appropriate +			return this.invalidMessage; // String +		}, + +		getPromptMessage: function(/*Boolean*/ isFocused){ +			// summary: return a hint to show if appropriate +			return this.promptMessage; // String +		}, + +		validate: function(/*Boolean*/ isFocused){ +			// summary: +			//		Called by oninit, onblur, and onkeypress. +			// description: +			//		Show missing or invalid messages if appropriate, and highlight textbox field. +			var message = ""; +			var isValid = this.isValid(isFocused); +			var isEmpty = this._isEmpty(this.textbox.value); +			this.state = (isValid || (!this._hasBeenBlurred && isEmpty)) ? "" : "Error"; +			this._setStateClass(); +			dijit.setWaiState(this.focusNode, "invalid", isValid ? "false" : "true"); +			if(isFocused){ +				if(isEmpty){ +					message = this.getPromptMessage(true); +				} +				if(!message && this.state == "Error"){ +					message = this.getErrorMessage(true); +				} +			} +			this.displayMessage(message); +			return isValid; +		}, + +		// currently displayed message +		_message: "", + +		displayMessage: function(/*String*/ message){ +			// summary: +			//		User overridable method to display validation errors/hints. +			//		By default uses a tooltip. +			if(this._message == message){ return; } +			this._message = message; +			dijit.hideTooltip(this.domNode); +			if(message){ +				dijit.showTooltip(message, this.domNode, this.tooltipPosition); +			} +		}, + +		_refreshState: function(){ +			this.validate(this._focused); +		}, + +		_update: function(/*Event*/e){ +			this._refreshState(); +			this._onMouse(e);	// update CSS classes +		}, + +		_onkeyup: function(/*Event*/e){ +			this._update(e); +			this.onkeyup(e); +		}, + +		//////////// INITIALIZATION METHODS /////////////////////////////////////// + +		constructor: function(){ +			this.constraints = {}; +		}, + +		postMixInProperties: function(){ +			this.inherited(arguments); +			this.constraints.locale = this.lang; +			this.messages = dojo.i18n.getLocalization("dijit.form", "validate", this.lang); +			if(this.invalidMessage == "$_unset_$"){ this.invalidMessage = this.messages.invalidMessage; } +			var p = this.regExpGen(this.constraints); +			this.regExp = p; +		} +	} +); + +dojo.declare( +	"dijit.form.MappedTextBox", +	dijit.form.ValidationTextBox, +	{ +		// summary: +		//		A dijit.form.ValidationTextBox subclass which provides a visible formatted display and a serializable +		//		value in a hidden input field which is actually sent to the server.  The visible display may +		//		be locale-dependent and interactive.  The value sent to the server is stored in a hidden +		//		input field which uses the `name` attribute declared by the original widget.  That value sent +		//		to the serveris defined by the dijit.form.MappedTextBox.serialize method and is typically +		//		locale-neutral. + +		serialize: function(/*anything*/val, /*Object?*/options){ +			// summary: user replaceable function used to convert the getValue() result to a String +			return val.toString ? val.toString() : ""; // String +		}, + +		toString: function(){ +			// summary: display the widget as a printable string using the widget's value +			var val = this.filter(this.getValue()); +			return val != null ? (typeof val == "string" ? val : this.serialize(val, this.constraints)) : ""; // String +		}, + +		validate: function(){ +			this.valueNode.value = this.toString(); +			return this.inherited(arguments); +		}, + +		setAttribute: function(/*String*/ attr, /*anything*/ value){ +			this.inherited(arguments); +			switch(attr){ +				case "disabled": +					if(this.valueNode){ +						this.valueNode.disabled = this.disabled; +					} +			} +		}, + +		postCreate: function(){ +			var textbox = this.textbox; +			var valueNode = (this.valueNode = dojo.doc.createElement("input")); +			valueNode.setAttribute("type", textbox.type); +			valueNode.setAttribute("value", this.toString()); +			dojo.style(valueNode, "display", "none"); +			valueNode.name = this.textbox.name; +			valueNode.disabled = this.textbox.disabled; +			this.textbox.name = this.textbox.name + "_displayed_"; +			this.textbox.removeAttribute("name"); +			dojo.place(valueNode, textbox, "after"); + +			this.inherited(arguments); +		} +	} +); + +/*===== +	dijit.form.RangeBoundTextBox.__Constraints = function(){ +		// min: Number +		//		Minimum signed value.  Default is -Infinity +		// max: Number +		//		Maximum signed value.  Default is +Infinity +		this.min = min; +		this.max = max; +	} +=====*/ + +dojo.declare( +	"dijit.form.RangeBoundTextBox", +	dijit.form.MappedTextBox, +	{ +		// summary: +		//		A dijit.form.MappedTextBox subclass which defines a range of valid values +		// +		// constraints: dijit.form.RangeBoundTextBox.__Constraints +		// +		// rangeMessage: String +		//		The message to display if value is out-of-range + +		/*===== +		constraints: {}, +		======*/ +		rangeMessage: "", + +		compare: function(/*anything*/val1, /*anything*/val2){ +			// summary: compare 2 values +			return val1 - val2; // anything +		}, + +		rangeCheck: function(/*Number*/ primitive, /*dijit.form.RangeBoundTextBox.__Constraints*/ constraints){ +			// summary: user replaceable function used to validate the range of the numeric input value +			var isMin = "min" in constraints; +			var isMax = "max" in constraints; +			if(isMin || isMax){ +				return (!isMin || this.compare(primitive,constraints.min) >= 0) && +					(!isMax || this.compare(primitive,constraints.max) <= 0); +			} +			return true; // Boolean +		}, + +		isInRange: function(/*Boolean*/ isFocused){ +			// summary: Need to over-ride with your own validation code in subclasses +			return this.rangeCheck(this.getValue(), this.constraints); +		}, + +		isValid: function(/*Boolean*/ isFocused){ +			return this.inherited(arguments) && +				((this._isEmpty(this.textbox.value) && !this.required) || this.isInRange(isFocused)); // Boolean +		}, + +		getErrorMessage: function(/*Boolean*/ isFocused){ +			if(dijit.form.RangeBoundTextBox.superclass.isValid.call(this, false) && !this.isInRange(isFocused)){ return this.rangeMessage; } // String +			return this.inherited(arguments); +		}, + +		postMixInProperties: function(){ +			this.inherited(arguments); +			if(!this.rangeMessage){ +				this.messages = dojo.i18n.getLocalization("dijit.form", "validate", this.lang); +				this.rangeMessage = this.messages.rangeMessage; +			} +		}, + +		postCreate: function(){ +			this.inherited(arguments); +			if(this.constraints.min !== undefined){ +				dijit.setWaiState(this.focusNode, "valuemin", this.constraints.min); +			} +			if(this.constraints.max !== undefined){ +				dijit.setWaiState(this.focusNode, "valuemax", this.constraints.max); +			} +		}, +		 +		setValue: function(/*Number*/ value, /*Boolean?*/ priorityChange){ +			dijit.setWaiState(this.focusNode, "valuenow", value); +			this.inherited('setValue', arguments); +		} +	} +); + +} diff --git a/includes/js/dijit/form/_DateTimeTextBox.js b/includes/js/dijit/form/_DateTimeTextBox.js new file mode 100644 index 0000000..2f3b933 --- /dev/null +++ b/includes/js/dijit/form/_DateTimeTextBox.js @@ -0,0 +1,175 @@ +if(!dojo._hasResource["dijit.form._DateTimeTextBox"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. +dojo._hasResource["dijit.form._DateTimeTextBox"] = true; +dojo.provide("dijit.form._DateTimeTextBox"); + +dojo.require("dojo.date"); +dojo.require("dojo.date.locale"); +dojo.require("dojo.date.stamp"); +dojo.require("dijit.form.ValidationTextBox"); + +/*===== +dojo.declare( +	"dijit.form._DateTimeTextBox.__Constraints", +	[dijit.form.RangeBoundTextBox.__Constraints, dojo.date.locale.__FormatOptions] +); +=====*/ + +dojo.declare( +	"dijit.form._DateTimeTextBox", +	dijit.form.RangeBoundTextBox, +	{ +		// summary: +		//		A validating, serializable, range-bound date or time text box. +		// +		// constraints: dijit.form._DateTimeTextBox.__Constraints  + +		/*===== +		constraints: {}, +		======*/ +		regExpGen: dojo.date.locale.regexp, +		compare: dojo.date.compare, +		format: function(/*Date*/ value, /*dojo.date.locale.__FormatOptions*/ constraints){ +			//	summary: formats the value as a Date, according to constraints +			if(!value){ return ''; } +			return dojo.date.locale.format(value, constraints); +		}, +		parse: function(/*String*/ value, /*dojo.date.locale.__FormatOptions*/ constraints){ +			//	summary: parses the value as a Date, according to constraints +			return dojo.date.locale.parse(value, constraints) || undefined; /* can't return null to getValue since that's special */ +		}, + +		serialize: dojo.date.stamp.toISOString, + +		//	value: Date +		//		The value of this widget as a JavaScript Date object.  Use `getValue`/`setValue` to manipulate. +		//		When passed to the parser in markup, must be specified according to `dojo.date.stamp.fromISOString` +		value: new Date(""),	// value.toString()="NaN" + +		//	popupClass: String +		//		Name of the popup widget class used to select a date/time +		popupClass: "", // default is no popup = text only +		_selector: "", + +		postMixInProperties: function(){ +			//dijit.form.RangeBoundTextBox.prototype.postMixInProperties.apply(this, arguments); +			this.inherited(arguments); +			if(!this.value || this.value.toString() == dijit.form._DateTimeTextBox.prototype.value.toString()){ +				this.value = undefined; +			} +			var constraints = this.constraints; +			constraints.selector = this._selector; +			constraints.fullYear = true; // see #5465 - always format with 4-digit years +			var fromISO = dojo.date.stamp.fromISOString; +			if(typeof constraints.min == "string"){ constraints.min = fromISO(constraints.min); } + 			if(typeof constraints.max == "string"){ constraints.max = fromISO(constraints.max); } +		}, + +		_onFocus: function(/*Event*/ evt){ +			// summary: open the TimePicker popup +			this._open(); +		}, + +		setValue: function(/*Date*/ value, /*Boolean?*/ priorityChange, /*String?*/ formattedValue){ +			// summary: +			//	Sets the date on this textbox.  Note that `value` must be a Javascript Date object. +			this.inherited(arguments); +			if(this._picker){ +				// #3948: fix blank date on popup only +				if(!value){value=new Date();} +				this._picker.setValue(value); +			} +		}, + +		_open: function(){ +			// summary: +			//	opens the TimePicker, and sets the onValueSelected value + +			if(this.disabled || this.readOnly || !this.popupClass){return;} + +			var textBox = this; + +			if(!this._picker){ +				var PopupProto=dojo.getObject(this.popupClass, false); +				this._picker = new PopupProto({ +					onValueSelected: function(value){ + +						textBox.focus(); // focus the textbox before the popup closes to avoid reopening the popup +						setTimeout(dojo.hitch(textBox, "_close"), 1); // allow focus time to take + +						// this will cause InlineEditBox and other handlers to do stuff so make sure it's last +						dijit.form._DateTimeTextBox.superclass.setValue.call(textBox, value, true); +					}, +					lang: textBox.lang, +					constraints: textBox.constraints, +					isDisabledDate: function(/*Date*/ date){ +						// summary: +						// 	disables dates outside of the min/max of the _DateTimeTextBox +						var compare = dojo.date.compare; +						var constraints = textBox.constraints; +						return constraints && (constraints.min && (compare(constraints.min, date, "date") > 0) ||  +							(constraints.max && compare(constraints.max, date, "date") < 0)); +					} +				}); +				this._picker.setValue(this.getValue() || new Date()); +			} +			if(!this._opened){ +				dijit.popup.open({ +					parent: this, +					popup: this._picker, +					around: this.domNode, +					onCancel: dojo.hitch(this, this._close), +					onClose: function(){ textBox._opened=false; } +				}); +				this._opened=true; +			} +			 +			dojo.marginBox(this._picker.domNode,{ w:this.domNode.offsetWidth }); +		}, + +		_close: function(){ +			if(this._opened){ +				dijit.popup.close(this._picker); +				this._opened=false; +			}			 +		}, + +		_onBlur: function(){ +			// summary: called magically when focus has shifted away from this widget and it's dropdown +			this._close(); +			if(this._picker){ +				// teardown so that constraints will be rebuilt next time (redundant reference: #6002) +				this._picker.destroy(); +				delete this._picker; +			} +			this.inherited(arguments); +			// don't focus on <input>.  the user has explicitly focused on something else. +		}, + +		getDisplayedValue:function(){ +			return this.textbox.value; +		}, + +		setDisplayedValue:function(/*String*/ value, /*Boolean?*/ priorityChange){ +			this.setValue(this.parse(value, this.constraints), priorityChange, value); +		}, + +		destroy: function(){ +			if(this._picker){ +				this._picker.destroy(); +				delete this._picker; +			} +			this.inherited(arguments); +		}, + +		_onKeyPress: function(/*Event*/e){ +			if(dijit.form._DateTimeTextBox.superclass._onKeyPress.apply(this, arguments)){ +				if(this._opened && e.keyCode == dojo.keys.ESCAPE && !e.shiftKey && !e.ctrlKey && !e.altKey){ +					this._close(); +					dojo.stopEvent(e); +				} +			} +		} +	} +); + +} diff --git a/includes/js/dijit/form/_FormWidget.js b/includes/js/dijit/form/_FormWidget.js new file mode 100644 index 0000000..5f29df2 --- /dev/null +++ b/includes/js/dijit/form/_FormWidget.js @@ -0,0 +1,340 @@ +if(!dojo._hasResource["dijit.form._FormWidget"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. +dojo._hasResource["dijit.form._FormWidget"] = true; +dojo.provide("dijit.form._FormWidget"); + +dojo.require("dijit._Widget"); +dojo.require("dijit._Templated"); + +dojo.declare("dijit.form._FormWidget", [dijit._Widget, dijit._Templated], +{ +	/* +	Summary: +		_FormWidget's correspond to native HTML elements such as <checkbox> or <button>. +		Each _FormWidget represents a single HTML element. + +		All these widgets should have these attributes just like native HTML input elements. +		You can set them during widget construction. + +		They also share some common methods. +	*/ + +	// baseClass: String +	//		Root CSS class of the widget (ex: dijitTextBox), used to add CSS classes of widget +	//		(ex: "dijitTextBox dijitTextBoxInvalid dijitTextBoxFocused dijitTextBoxInvalidFocused") +	//		See _setStateClass(). +	baseClass: "", + +	// name: String +	//		Name used when submitting form; same as "name" attribute or plain HTML elements +	name: "", + +	// alt: String +	//		Corresponds to the native HTML <input> element's attribute. +	alt: "", + +	// value: String +	//		Corresponds to the native HTML <input> element's attribute. +	value: "", + +	// type: String +	//		Corresponds to the native HTML <input> element's attribute. +	type: "text", + +	// tabIndex: Integer +	//		Order fields are traversed when user hits the tab key +	tabIndex: "0", + +	// disabled: Boolean +	//		Should this widget respond to user input? +	//		In markup, this is specified as "disabled='disabled'", or just "disabled". +	disabled: false, + +	// readOnly: Boolean +	//		Should this widget respond to user input? +	//		In markup, this is specified as "readOnly". +	//		Similar to disabled except readOnly form values are submitted +	readOnly: false, + +	// intermediateChanges: Boolean +	//		Fires onChange for each value change or only on demand +	intermediateChanges: false, + +	// These mixins assume that the focus node is an INPUT, as many but not all _FormWidgets are. +	// Don't attempt to mixin the 'type', 'name' attributes here programatically -- they must be declared +	// directly in the template as read by the parser in order to function. IE is known to specifically  +	// require the 'name' attribute at element creation time. +	attributeMap: dojo.mixin(dojo.clone(dijit._Widget.prototype.attributeMap), +		{value:"focusNode", disabled:"focusNode", readOnly:"focusNode", id:"focusNode", tabIndex:"focusNode", alt:"focusNode"}), + +	setAttribute: function(/*String*/ attr, /*anything*/ value){ +		this.inherited(arguments); +		switch(attr){ +			case "disabled": +				var tabIndexNode = this[this.attributeMap['tabIndex']||'domNode']; +				if(value){ +					//reset those, because after the domNode is disabled, we can no longer receive +					//mouse related events, see #4200 +					this._hovering = false; +					this._active = false; +					// remove the tabIndex, especially for FF +					tabIndexNode.removeAttribute('tabIndex'); +				}else{ +					tabIndexNode.setAttribute('tabIndex', this.tabIndex); +				} +				dijit.setWaiState(this[this.attributeMap['disabled']||'domNode'], "disabled", value); +				this._setStateClass(); +		} +	}, + +	setDisabled: function(/*Boolean*/ disabled){ +		// summary: +		//		Set disabled state of widget (Deprecated). +		dojo.deprecated("setDisabled("+disabled+") is deprecated. Use setAttribute('disabled',"+disabled+") instead.", "", "2.0"); +		this.setAttribute('disabled', disabled); +	}, + + +	_onMouse : function(/*Event*/ event){ +		// summary: +		//	Sets _hovering, _active, and stateModifier properties depending on mouse state, +		//	then calls setStateClass() to set appropriate CSS classes for this.domNode. +		// +		//	To get a different CSS class for hover, send onmouseover and onmouseout events to this method. +		//	To get a different CSS class while mouse button is depressed, send onmousedown to this method. + +		var mouseNode = event.currentTarget; +		if(mouseNode && mouseNode.getAttribute){ +			this.stateModifier = mouseNode.getAttribute("stateModifier") || ""; +		} + +		if(!this.disabled){ +			switch(event.type){ +				case "mouseenter":	 +				case "mouseover": +					this._hovering = true; +					this._active = this._mouseDown; +					break; + +				case "mouseout": +				case "mouseleave": +					this._hovering = false; +					this._active = false; +					break; + +				case "mousedown" : +					this._active = true; +					this._mouseDown = true; +					// set a global event to handle mouseup, so it fires properly +					//	even if the cursor leaves the button +					var mouseUpConnector = this.connect(dojo.body(), "onmouseup", function(){ +						this._active = false; +						this._mouseDown = false; +						this._setStateClass(); +						this.disconnect(mouseUpConnector); +					}); +					if(this.isFocusable()){ this.focus(); } +					break; +			} +			this._setStateClass(); +		} +	}, + +	isFocusable: function(){ +		return !this.disabled && !this.readOnly && this.focusNode && (dojo.style(this.domNode, "display") != "none"); +	}, + +	focus: function(){ +		setTimeout(dojo.hitch(this, dijit.focus, this.focusNode), 0); // cannot call focus() from an event handler directly +	}, + +	_setStateClass: function(){ +		// summary +		//	Update the visual state of the widget by setting the css classes on this.domNode +		//  (or this.stateNode if defined) by combining this.baseClass with +		//	various suffixes that represent the current widget state(s). +		// +		//	In the case where a widget has multiple +		//	states, it sets the class based on all possible +		//  combinations.  For example, an invalid form widget that is being hovered +		//	will be "dijitInput dijitInputInvalid dijitInputHover dijitInputInvalidHover". +		// +		//	For complex widgets with multiple regions, there can be various hover/active states, +		//	such as "Hover" or "CloseButtonHover" (for tab buttons). +		//	This is controlled by a stateModifier="CloseButton" attribute on the close button node. +		// +		//	The widget may have one or more of the following states, determined +		//	by this.state, this.checked, this.valid, and this.selected: +		//		Error - ValidationTextBox sets this.state to "Error" if the current input value is invalid +		//		Checked - ex: a checkmark or a ToggleButton in a checked state, will have this.checked==true +		//		Selected - ex: currently selected tab will have this.selected==true +		// +		//	In addition, it may have one or more of the following states, +		//	based on this.disabled and flags set in _onMouse (this._active, this._hovering, this._focused): +		//		Disabled	- if the widget is disabled +		//		Active		- if the mouse (or space/enter key?) is being pressed down +		//		Focused		- if the widget has focus +		//		Hover		- if the mouse is over the widget + +		// Get original (non state related, non baseClass related) class specified in template +		if(!("staticClass" in this)){ +			this.staticClass = (this.stateNode||this.domNode).className; +		} + +		// Compute new set of classes +		var classes = [ this.baseClass ]; + +		function multiply(modifier){ +			classes=classes.concat(dojo.map(classes, function(c){ return c+modifier; }), "dijit"+modifier); +		} + +		if(this.checked){ +			multiply("Checked"); +		} +		if(this.state){ +			multiply(this.state); +		} +		if(this.selected){ +			multiply("Selected"); +		} + +		if(this.disabled){ +			multiply("Disabled"); +		}else if(this.readOnly){ +			multiply("ReadOnly"); +		}else if(this._active){ +			multiply(this.stateModifier+"Active"); +		}else{ +			if(this._focused){ +				multiply("Focused"); +			} +			if(this._hovering){ +				multiply(this.stateModifier+"Hover"); +			} +		} + +		(this.stateNode || this.domNode).className = this.staticClass + " " + classes.join(" "); +	}, + +	onChange: function(newValue){ +		// summary: callback when value is changed +	}, + +	_onChangeMonitor: 'value', +	_onChangeActive: false, + +	_handleOnChange: function(/*anything*/ newValue, /*Boolean, optional*/ priorityChange){ +		// summary: set the value of the widget. +		this._lastValue = newValue; +		if(this._lastValueReported == undefined && (priorityChange === null || !this._onChangeActive)){ +			this._resetValue = this._lastValueReported = newValue; +		} +		if((this.intermediateChanges || priorityChange || priorityChange === undefined) &&  +			((newValue && newValue.toString)?newValue.toString():newValue) !== ((this._lastValueReported && this._lastValueReported.toString)?this._lastValueReported.toString():this._lastValueReported)){ +			this._lastValueReported = newValue; +			if(this._onChangeActive){ this.onChange(newValue); } +		} +	}, + +	reset: function(){ +		this._hasBeenBlurred = false; +		if(this.setValue && !this._getValueDeprecated){ +			this.setValue(this._resetValue, true); +		}else if(this._onChangeMonitor){ +			this.setAttribute(this._onChangeMonitor, (this._resetValue !== undefined && this._resetValue !== null)? this._resetValue : ''); +		} +	}, + +	create: function(){ +		this.inherited(arguments); +		this._onChangeActive = true; +		this._setStateClass(); +	}, +	 +	destroy: function(){ +		if(this._layoutHackHandle){ +			clearTimeout(this._layoutHackHandle); +		} +		this.inherited(arguments); +	}, + +	setValue: function(/*String*/ value){ +		dojo.deprecated("dijit.form._FormWidget:setValue("+value+") is deprecated.  Use setAttribute('value',"+value+") instead.", "", "2.0"); +		this.setAttribute('value', value); +	}, + +	_getValueDeprecated: true, // Form uses this, remove when getValue is removed +	getValue: function(){ +		dojo.deprecated("dijit.form._FormWidget:getValue() is deprecated.  Use widget.value instead.", "", "2.0"); +		return this.value; +	}, + +	_layoutHack: function(){ +		// summary: work around table sizing bugs on FF2 by forcing redraw +		if(dojo.isFF == 2){ +			var node=this.domNode; +			var old = node.style.opacity; +			node.style.opacity = "0.999"; +			this._layoutHackHandle = setTimeout(dojo.hitch(this, function(){ +				this._layoutHackHandle = null; +				node.style.opacity = old; +			}), 0); +		} +	} +}); + +dojo.declare("dijit.form._FormValueWidget", dijit.form._FormWidget, +{ +	/* +	Summary: +		_FormValueWidget's correspond to native HTML elements such as <input> or <select> that have user changeable values. +		Each _ValueWidget represents a single input value, and has a (possibly hidden) <input> element, +		to which it serializes its input value, so that form submission (either normal submission or via FormBind?) +		works as expected. +	*/ + +	attributeMap: dojo.mixin(dojo.clone(dijit.form._FormWidget.prototype.attributeMap), +		{value:""}), + +	postCreate: function(){ +		this.setValue(this.value, null); +	}, + +	setValue: function(/*anything*/ newValue, /*Boolean, optional*/ priorityChange){ +		// summary: set the value of the widget. +		this.value = newValue; +		this._handleOnChange(newValue, priorityChange); +	}, + +	_getValueDeprecated: false, // remove when _FormWidget:getValue is removed +	getValue: function(){ +		// summary: get the value of the widget. +		return this._lastValue; +	}, + +	undo: function(){ +		// summary: restore the value to the last value passed to onChange +		this.setValue(this._lastValueReported, false); +	}, + +	_valueChanged: function(){ +		var v = this.getValue(); +		var lv = this._lastValueReported; +		// Equality comparison of objects such as dates are done by reference so +		// two distinct objects are != even if they have the same data. So use +		// toStrings in case the values are objects. +		return ((v !== null && (v !== undefined) && v.toString)?v.toString():'') !== ((lv !== null && (lv !== undefined) && lv.toString)?lv.toString():''); +	}, + +	_onKeyPress: function(e){ +		if(e.keyCode == dojo.keys.ESCAPE && !e.shiftKey && !e.ctrlKey && !e.altKey){ +			if(this._valueChanged()){ +				this.undo(); +				dojo.stopEvent(e); +				return false; +			} +		} +		return true; +	} +}); + +} diff --git a/includes/js/dijit/form/_Spinner.js b/includes/js/dijit/form/_Spinner.js new file mode 100644 index 0000000..6837552 --- /dev/null +++ b/includes/js/dijit/form/_Spinner.js @@ -0,0 +1,117 @@ +if(!dojo._hasResource["dijit.form._Spinner"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. +dojo._hasResource["dijit.form._Spinner"] = true; +dojo.provide("dijit.form._Spinner"); + +dojo.require("dijit.form.ValidationTextBox"); + +dojo.declare( +	"dijit.form._Spinner", +	dijit.form.RangeBoundTextBox, +	{ + +		// summary: Mixin for validation widgets with a spinner +		// description: This class basically (conceptually) extends dijit.form.ValidationTextBox. +		//	It modifies the template to have up/down arrows, and provides related handling code. + +		// defaultTimeout: Number +		//	  number of milliseconds before a held key or button becomes typematic +		defaultTimeout: 500, + +		// timeoutChangeRate: Number +		//	  fraction of time used to change the typematic timer between events +		//	  1.0 means that each typematic event fires at defaultTimeout intervals +		//	  < 1.0 means that each typematic event fires at an increasing faster rate +		timeoutChangeRate: 0.90, + +		// smallDelta: Number +		//	  adjust the value by this much when spinning using the arrow keys/buttons +		smallDelta: 1, +		// largeDelta: Number +		//	  adjust the value by this much when spinning using the PgUp/Dn keys +		largeDelta: 10, + +		templateString:"<div class=\"dijit dijitReset dijitInlineTable dijitLeft\"\n\tid=\"widget_${id}\"\n\tdojoAttachEvent=\"onmouseenter:_onMouse,onmouseleave:_onMouse,onmousedown:_onMouse\" waiRole=\"presentation\"\n\t><div class=\"dijitInputLayoutContainer\"\n\t\t><div class=\"dijitReset dijitSpinnerButtonContainer\"\n\t\t\t> <div class=\"dijitReset dijitLeft dijitButtonNode dijitArrowButton dijitUpArrowButton\"\n\t\t\t\tdojoAttachPoint=\"upArrowNode\"\n\t\t\t\tdojoAttachEvent=\"onmouseenter:_onMouse,onmouseleave:_onMouse\"\n\t\t\t\tstateModifier=\"UpArrow\"\n\t\t\t\t><div class=\"dijitArrowButtonInner\"> </div\n\t\t\t\t><div class=\"dijitArrowButtonChar\">▲</div\n\t\t\t></div\n\t\t\t><div class=\"dijitReset dijitLeft dijitButtonNode dijitArrowButton dijitDownArrowButton\"\n\t\t\t\tdojoAttachPoint=\"downArrowNode\"\n\t\t\t\tdojoAttachEvent=\"onmouseenter:_onMouse,onmouseleave:_onMouse\"\n\t\t\t\tstateModifier=\"DownArrow\"\n\t\t\t\t><div class=\"dijitArrowButtonInner\"> </div\n\t\t\t\t><div class=\"dijitArrowButtonChar\">▼</div\n\t\t\t></div\n\t\t></div\n\t\t><div class=\"dijitReset dijitValidationIcon\"><br></div\n\t\t><div class=\"dijitReset dijitValidationIconText\">Χ</div\n\t\t><div class=\"dijitReset dijitInputField\"\n\t\t\t><input class='dijitReset' dojoAttachPoint=\"textbox,focusNode\" type=\"${type}\" dojoAttachEvent=\"onfocus:_update,onkeyup:_onkeyup,onkeypress:_onKeyPress\"\n\t\t\t\twaiRole=\"spinbutton\" autocomplete=\"off\" name=\"${name}\"\n\t\t/></div\n\t></div\n></div>\n", +		baseClass: "dijitSpinner", + +		adjust: function(/* Object */ val, /*Number*/ delta){ +			// summary: user replaceable function used to adjust a primitive value(Number/Date/...) by the delta amount specified +			// the val is adjusted in a way that makes sense to the object type +			return val; +		}, + +		_arrowState: function(/*Node*/ node, /*Boolean*/ pressed){ +			this._active = pressed; +			this.stateModifier = node.getAttribute("stateModifier") || ""; +			this._setStateClass(); +		}, + +		_arrowPressed: function(/*Node*/ nodePressed, /*Number*/ direction){ +			if(this.disabled || this.readOnly){ return; } +			this._arrowState(nodePressed, true); +			this.setValue(this.adjust(this.getValue(), direction*this.smallDelta), false); +			dijit.selectInputText(this.textbox, this.textbox.value.length); +		}, + +		_arrowReleased: function(/*Node*/ node){ +			this._wheelTimer = null; +			if(this.disabled || this.readOnly){ return; } +			this._arrowState(node, false); +		}, + +		_typematicCallback: function(/*Number*/ count, /*DOMNode*/ node, /*Event*/ evt){ +			if(node == this.textbox){ node = (evt.keyCode == dojo.keys.UP_ARROW) ? this.upArrowNode : this.downArrowNode; } +			if(count == -1){ this._arrowReleased(node); } +			else{ this._arrowPressed(node, (node == this.upArrowNode) ? 1 : -1); } +		}, + +		_wheelTimer: null, +		_mouseWheeled: function(/*Event*/ evt){ +			dojo.stopEvent(evt); +			var scrollAmount = 0; +			if(typeof evt.wheelDelta == 'number'){ // IE +				scrollAmount = evt.wheelDelta; +			}else if(typeof evt.detail == 'number'){ // Mozilla+Firefox +				scrollAmount = -evt.detail; +			} +			var node, dir; +			if(scrollAmount > 0){ +				node = this.upArrowNode; +				dir = +1; +			}else if(scrollAmount < 0){ +				node = this.downArrowNode; +				dir = -1; +			}else{ return; } +			this._arrowPressed(node, dir); +			if(this._wheelTimer != null){ +				clearTimeout(this._wheelTimer); +			} +			var _this = this; +			this._wheelTimer = setTimeout(function(){_this._arrowReleased(node);}, 50); +		}, + +		postCreate: function(){ +			this.inherited('postCreate', arguments); + +			// extra listeners +			this.connect(this.textbox, dojo.isIE ? "onmousewheel" : 'DOMMouseScroll', "_mouseWheeled"); +			this._connects.push(dijit.typematic.addListener(this.upArrowNode, this.textbox, {keyCode:dojo.keys.UP_ARROW,ctrlKey:false,altKey:false,shiftKey:false}, this, "_typematicCallback", this.timeoutChangeRate, this.defaultTimeout)); +			this._connects.push(dijit.typematic.addListener(this.downArrowNode, this.textbox, {keyCode:dojo.keys.DOWN_ARROW,ctrlKey:false,altKey:false,shiftKey:false}, this, "_typematicCallback", this.timeoutChangeRate, this.defaultTimeout)); +			if(dojo.isIE){ +				// When spinner is moved from hidden to visible, call _setStateClass to remind IE to render it. (#6123) +				var _this = this; +				this.connect(this.domNode, "onresize",  +					function(){ setTimeout(dojo.hitch(_this, +						function(){ +							// cause the IE expressions to rerun +							this.upArrowNode.style.behavior = ''; +							this.downArrowNode.style.behavior = ''; +							// cause IE to rerender +							this._setStateClass(); +						}), 0); +					} +				); +			} +		} +}); + +} diff --git a/includes/js/dijit/form/nls/ComboBox.js b/includes/js/dijit/form/nls/ComboBox.js new file mode 100644 index 0000000..49bba39 --- /dev/null +++ b/includes/js/dijit/form/nls/ComboBox.js @@ -0,0 +1 @@ +({"previousMessage":"Previous choices","nextMessage":"More choices"})
\ No newline at end of file diff --git a/includes/js/dijit/form/nls/Textarea.js b/includes/js/dijit/form/nls/Textarea.js new file mode 100644 index 0000000..4b0e996 --- /dev/null +++ b/includes/js/dijit/form/nls/Textarea.js @@ -0,0 +1 @@ +({"iframeEditTitle":"edit area","iframeFocusTitle":"edit area frame"})
\ No newline at end of file diff --git a/includes/js/dijit/form/nls/ar/ComboBox.js b/includes/js/dijit/form/nls/ar/ComboBox.js new file mode 100644 index 0000000..d165d7e --- /dev/null +++ b/includes/js/dijit/form/nls/ar/ComboBox.js @@ -0,0 +1 @@ +({"previousMessage":"الاختيارات السابقة ","nextMessage":"مزيد من الاختيارات "})
\ No newline at end of file diff --git a/includes/js/dijit/form/nls/ar/Textarea.js b/includes/js/dijit/form/nls/ar/Textarea.js new file mode 100644 index 0000000..fe623c6 --- /dev/null +++ b/includes/js/dijit/form/nls/ar/Textarea.js @@ -0,0 +1 @@ +({"iframeEditTitle":"مساحة التحرير","iframeFocusTitle":"اطار مساحة التحرير"})
\ No newline at end of file diff --git a/includes/js/dijit/form/nls/ar/validate.js b/includes/js/dijit/form/nls/ar/validate.js new file mode 100644 index 0000000..81106f5 --- /dev/null +++ b/includes/js/dijit/form/nls/ar/validate.js @@ -0,0 +1 @@ +({"rangeMessage":"هذه القيمة ليس بالمدى الصحيح. ","invalidMessage":"القيمة التي تم ادخالها غير صحيحة. ","missingMessage":"يجب ادخال هذه القيمة. "})
\ No newline at end of file diff --git a/includes/js/dijit/form/nls/cs/ComboBox.js b/includes/js/dijit/form/nls/cs/ComboBox.js new file mode 100644 index 0000000..84e0841 --- /dev/null +++ b/includes/js/dijit/form/nls/cs/ComboBox.js @@ -0,0 +1 @@ +({"previousMessage":"Předchozí volby","nextMessage":"Další volby"})
\ No newline at end of file diff --git a/includes/js/dijit/form/nls/cs/Textarea.js b/includes/js/dijit/form/nls/cs/Textarea.js new file mode 100644 index 0000000..8a75ddc --- /dev/null +++ b/includes/js/dijit/form/nls/cs/Textarea.js @@ -0,0 +1 @@ +({"iframeEditTitle":"oblast úprav","iframeFocusTitle":"rámec oblasti úprav"})
\ No newline at end of file diff --git a/includes/js/dijit/form/nls/cs/validate.js b/includes/js/dijit/form/nls/cs/validate.js new file mode 100644 index 0000000..7bb7b9e --- /dev/null +++ b/includes/js/dijit/form/nls/cs/validate.js @@ -0,0 +1 @@ +({"rangeMessage":"Tato hodnota je mimo rozsah.","invalidMessage":"Zadaná hodnota není platná.","missingMessage":"Tato hodnota je vyžadována."})
\ No newline at end of file diff --git a/includes/js/dijit/form/nls/da/ComboBox.js b/includes/js/dijit/form/nls/da/ComboBox.js new file mode 100644 index 0000000..4ddc10d --- /dev/null +++ b/includes/js/dijit/form/nls/da/ComboBox.js @@ -0,0 +1 @@ +({"previousMessage":"Forrige valg","nextMessage":"Flere valg"})
\ No newline at end of file diff --git a/includes/js/dijit/form/nls/da/Textarea.js b/includes/js/dijit/form/nls/da/Textarea.js new file mode 100644 index 0000000..244c210 --- /dev/null +++ b/includes/js/dijit/form/nls/da/Textarea.js @@ -0,0 +1 @@ +({"iframeEditTitle":"redigeringsområde","iframeFocusTitle":"ramme om redigeringsområde"})
\ No newline at end of file diff --git a/includes/js/dijit/form/nls/da/validate.js b/includes/js/dijit/form/nls/da/validate.js new file mode 100644 index 0000000..2874dd8 --- /dev/null +++ b/includes/js/dijit/form/nls/da/validate.js @@ -0,0 +1 @@ +({"rangeMessage":"Værdien er uden for intervallet.","invalidMessage":"Den angivne værdi er ugyldig.","missingMessage":"Værdien er påkrævet."})
\ No newline at end of file diff --git a/includes/js/dijit/form/nls/de/ComboBox.js b/includes/js/dijit/form/nls/de/ComboBox.js new file mode 100644 index 0000000..6cce34b --- /dev/null +++ b/includes/js/dijit/form/nls/de/ComboBox.js @@ -0,0 +1 @@ +({"previousMessage":"Vorherige Auswahl","nextMessage":"Weitere Auswahlmöglichkeiten"})
\ No newline at end of file diff --git a/includes/js/dijit/form/nls/de/Textarea.js b/includes/js/dijit/form/nls/de/Textarea.js new file mode 100644 index 0000000..2cf75db --- /dev/null +++ b/includes/js/dijit/form/nls/de/Textarea.js @@ -0,0 +1 @@ +({"iframeEditTitle":"Editierbereich","iframeFocusTitle":"Rahmen für Editierbereich"})
\ No newline at end of file diff --git a/includes/js/dijit/form/nls/de/validate.js b/includes/js/dijit/form/nls/de/validate.js new file mode 100644 index 0000000..597796d --- /dev/null +++ b/includes/js/dijit/form/nls/de/validate.js @@ -0,0 +1 @@ +({"rangeMessage":"Dieser Wert liegt außerhalb des gültigen Bereichs. ","invalidMessage":"Der eingegebene Wert ist ungültig. ","missingMessage":"Dieser Wert ist erforderlich."})
\ No newline at end of file diff --git a/includes/js/dijit/form/nls/el/ComboBox.js b/includes/js/dijit/form/nls/el/ComboBox.js new file mode 100644 index 0000000..ec294d1 --- /dev/null +++ b/includes/js/dijit/form/nls/el/ComboBox.js @@ -0,0 +1 @@ +({"previousMessage":"Προηγούμενες επιλογές","nextMessage":"Περισσότερες επιλογές"})
\ No newline at end of file diff --git a/includes/js/dijit/form/nls/el/Textarea.js b/includes/js/dijit/form/nls/el/Textarea.js new file mode 100644 index 0000000..9ce37a9 --- /dev/null +++ b/includes/js/dijit/form/nls/el/Textarea.js @@ -0,0 +1 @@ +({"iframeEditTitle":"περιοχή επεξεργασίας","iframeFocusTitle":"πλαίσιο περιοχής επεξεργασίας"})
\ No newline at end of file diff --git a/includes/js/dijit/form/nls/el/validate.js b/includes/js/dijit/form/nls/el/validate.js new file mode 100644 index 0000000..cc57d55 --- /dev/null +++ b/includes/js/dijit/form/nls/el/validate.js @@ -0,0 +1 @@ +({"rangeMessage":"Η τιμή αυτή δεν ανήκει στο εύρος έγκυρων τιμών.","invalidMessage":"Η τιμή που καταχωρήσατε δεν είναι έγκυρη.","missingMessage":"Η τιμή αυτή πρέπει απαραίτητα να καθοριστεί."})
\ No newline at end of file diff --git a/includes/js/dijit/form/nls/es/ComboBox.js b/includes/js/dijit/form/nls/es/ComboBox.js new file mode 100644 index 0000000..5bf69f9 --- /dev/null +++ b/includes/js/dijit/form/nls/es/ComboBox.js @@ -0,0 +1 @@ +({"previousMessage":"Opciones anteriores","nextMessage":"Más opciones"})
\ No newline at end of file diff --git a/includes/js/dijit/form/nls/es/Textarea.js b/includes/js/dijit/form/nls/es/Textarea.js new file mode 100644 index 0000000..f92a50f --- /dev/null +++ b/includes/js/dijit/form/nls/es/Textarea.js @@ -0,0 +1 @@ +({"iframeEditTitle":"área de edición","iframeFocusTitle":"marco del área de edición"})
\ No newline at end of file diff --git a/includes/js/dijit/form/nls/es/validate.js b/includes/js/dijit/form/nls/es/validate.js new file mode 100644 index 0000000..65e190e --- /dev/null +++ b/includes/js/dijit/form/nls/es/validate.js @@ -0,0 +1 @@ +({"rangeMessage":"Este valor está fuera del intervalo.","invalidMessage":"El valor especificado no es válido.","missingMessage":"Este valor es necesario."})
\ No newline at end of file diff --git a/includes/js/dijit/form/nls/fi/ComboBox.js b/includes/js/dijit/form/nls/fi/ComboBox.js new file mode 100644 index 0000000..6d9b830 --- /dev/null +++ b/includes/js/dijit/form/nls/fi/ComboBox.js @@ -0,0 +1 @@ +({"previousMessage":"Edelliset valinnat","nextMessage":"Lisää valintoja"})
\ No newline at end of file diff --git a/includes/js/dijit/form/nls/fi/Textarea.js b/includes/js/dijit/form/nls/fi/Textarea.js new file mode 100644 index 0000000..5efaee9 --- /dev/null +++ b/includes/js/dijit/form/nls/fi/Textarea.js @@ -0,0 +1 @@ +({"iframeEditTitle":"muokkausalue","iframeFocusTitle":"muokkausalueen kehys"})
\ No newline at end of file diff --git a/includes/js/dijit/form/nls/fi/validate.js b/includes/js/dijit/form/nls/fi/validate.js new file mode 100644 index 0000000..276efcd --- /dev/null +++ b/includes/js/dijit/form/nls/fi/validate.js @@ -0,0 +1 @@ +({"rangeMessage":"Tämä arvo on sallitun alueen ulkopuolella.","invalidMessage":"Annettu arvo ei kelpaa.","missingMessage":"Tämä arvo on pakollinen."})
\ No newline at end of file diff --git a/includes/js/dijit/form/nls/fr/ComboBox.js b/includes/js/dijit/form/nls/fr/ComboBox.js new file mode 100644 index 0000000..14b3976 --- /dev/null +++ b/includes/js/dijit/form/nls/fr/ComboBox.js @@ -0,0 +1 @@ +({"previousMessage":"Choix précédents","nextMessage":"Plus de choix"})
\ No newline at end of file diff --git a/includes/js/dijit/form/nls/fr/Textarea.js b/includes/js/dijit/form/nls/fr/Textarea.js new file mode 100644 index 0000000..4abb6c3 --- /dev/null +++ b/includes/js/dijit/form/nls/fr/Textarea.js @@ -0,0 +1 @@ +({"iframeEditTitle":"zone d'édition","iframeFocusTitle":"cadre de la zone d'édition"})
\ No newline at end of file diff --git a/includes/js/dijit/form/nls/fr/validate.js b/includes/js/dijit/form/nls/fr/validate.js new file mode 100644 index 0000000..95a0169 --- /dev/null +++ b/includes/js/dijit/form/nls/fr/validate.js @@ -0,0 +1 @@ +({"rangeMessage":"Cette valeur n'est pas comprise dans la plage autorisée.","invalidMessage":"La valeur indiquée n'est pas correcte.","missingMessage":"Cette valeur est requise."})
\ No newline at end of file diff --git a/includes/js/dijit/form/nls/he/ComboBox.js b/includes/js/dijit/form/nls/he/ComboBox.js new file mode 100644 index 0000000..169d0f5 --- /dev/null +++ b/includes/js/dijit/form/nls/he/ComboBox.js @@ -0,0 +1 @@ +({"previousMessage":"האפשרויות הקודמות","nextMessage":"אפשרויות נוספות"})
\ No newline at end of file diff --git a/includes/js/dijit/form/nls/he/Textarea.js b/includes/js/dijit/form/nls/he/Textarea.js new file mode 100644 index 0000000..809eadf --- /dev/null +++ b/includes/js/dijit/form/nls/he/Textarea.js @@ -0,0 +1 @@ +({"iframeEditTitle":"אזור עריכה","iframeFocusTitle":"מסגרת אזור עריכה"})
\ No newline at end of file diff --git a/includes/js/dijit/form/nls/he/validate.js b/includes/js/dijit/form/nls/he/validate.js new file mode 100644 index 0000000..5b58183 --- /dev/null +++ b/includes/js/dijit/form/nls/he/validate.js @@ -0,0 +1 @@ +({"rangeMessage":"הערך מחוץ לטווח. ","invalidMessage":"הערך שצוין אינו חוקי.","missingMessage":"זהו ערך דרוש. "})
\ No newline at end of file diff --git a/includes/js/dijit/form/nls/hu/ComboBox.js b/includes/js/dijit/form/nls/hu/ComboBox.js new file mode 100644 index 0000000..4b6a620 --- /dev/null +++ b/includes/js/dijit/form/nls/hu/ComboBox.js @@ -0,0 +1 @@ +({"previousMessage":"Előző menüpontok","nextMessage":"További menüpontok"})
\ No newline at end of file diff --git a/includes/js/dijit/form/nls/hu/Textarea.js b/includes/js/dijit/form/nls/hu/Textarea.js new file mode 100644 index 0000000..9b4ca01 --- /dev/null +++ b/includes/js/dijit/form/nls/hu/Textarea.js @@ -0,0 +1 @@ +({"iframeEditTitle":"szerkesztési terület","iframeFocusTitle":"szerkesztési terület keret"})
\ No newline at end of file diff --git a/includes/js/dijit/form/nls/hu/validate.js b/includes/js/dijit/form/nls/hu/validate.js new file mode 100644 index 0000000..35edb8b --- /dev/null +++ b/includes/js/dijit/form/nls/hu/validate.js @@ -0,0 +1 @@ +({"rangeMessage":"Az érték kívül van a megengedett tartományon. ","invalidMessage":"A megadott érték érvénytelen. ","missingMessage":"Meg kell adni egy értéket. "})
\ No newline at end of file diff --git a/includes/js/dijit/form/nls/it/ComboBox.js b/includes/js/dijit/form/nls/it/ComboBox.js new file mode 100644 index 0000000..9f67072 --- /dev/null +++ b/includes/js/dijit/form/nls/it/ComboBox.js @@ -0,0 +1 @@ +({"previousMessage":"Scelte precedenti","nextMessage":"Altre scelte"})
\ No newline at end of file diff --git a/includes/js/dijit/form/nls/it/Textarea.js b/includes/js/dijit/form/nls/it/Textarea.js new file mode 100644 index 0000000..1b14ecc --- /dev/null +++ b/includes/js/dijit/form/nls/it/Textarea.js @@ -0,0 +1 @@ +({"iframeEditTitle":"modifica area","iframeFocusTitle":"modifica frame area"})
\ No newline at end of file diff --git a/includes/js/dijit/form/nls/it/validate.js b/includes/js/dijit/form/nls/it/validate.js new file mode 100644 index 0000000..af7227f --- /dev/null +++ b/includes/js/dijit/form/nls/it/validate.js @@ -0,0 +1 @@ +({"rangeMessage":"Questo valore non è compreso nell'intervallo.","invalidMessage":"Il valore immesso non è valido.","missingMessage":"Questo valore è obbligatorio."})
\ No newline at end of file diff --git a/includes/js/dijit/form/nls/ja/ComboBox.js b/includes/js/dijit/form/nls/ja/ComboBox.js new file mode 100644 index 0000000..6b34170 --- /dev/null +++ b/includes/js/dijit/form/nls/ja/ComboBox.js @@ -0,0 +1 @@ +({"previousMessage":"以前の選択項目","nextMessage":"追加の選択項目"})
\ No newline at end of file diff --git a/includes/js/dijit/form/nls/ja/Textarea.js b/includes/js/dijit/form/nls/ja/Textarea.js new file mode 100644 index 0000000..8a52f4a --- /dev/null +++ b/includes/js/dijit/form/nls/ja/Textarea.js @@ -0,0 +1 @@ +({"iframeEditTitle":"編集域","iframeFocusTitle":"編集域フレーム"})
\ No newline at end of file diff --git a/includes/js/dijit/form/nls/ja/validate.js b/includes/js/dijit/form/nls/ja/validate.js new file mode 100644 index 0000000..450cd7e --- /dev/null +++ b/includes/js/dijit/form/nls/ja/validate.js @@ -0,0 +1 @@ +({"rangeMessage":"この値は範囲外です。","invalidMessage":"入力した値は無効です。","missingMessage":"この値は必須です。"})
\ No newline at end of file diff --git a/includes/js/dijit/form/nls/ko/ComboBox.js b/includes/js/dijit/form/nls/ko/ComboBox.js new file mode 100644 index 0000000..87d0f06 --- /dev/null +++ b/includes/js/dijit/form/nls/ko/ComboBox.js @@ -0,0 +1 @@ +({"previousMessage":"이전 선택사항","nextMessage":"기타 선택사항"})
\ No newline at end of file diff --git a/includes/js/dijit/form/nls/ko/Textarea.js b/includes/js/dijit/form/nls/ko/Textarea.js new file mode 100644 index 0000000..5c4e916 --- /dev/null +++ b/includes/js/dijit/form/nls/ko/Textarea.js @@ -0,0 +1 @@ +({"iframeEditTitle":"편집 영역","iframeFocusTitle":"편집 영역 프레임"})
\ No newline at end of file diff --git a/includes/js/dijit/form/nls/ko/validate.js b/includes/js/dijit/form/nls/ko/validate.js new file mode 100644 index 0000000..c76c676 --- /dev/null +++ b/includes/js/dijit/form/nls/ko/validate.js @@ -0,0 +1 @@ +({"rangeMessage":"이 값은 범위를 벗어납니다.","invalidMessage":"입력된 값이 올바르지 않습니다.","missingMessage":"이 값은 필수입니다."})
\ No newline at end of file diff --git a/includes/js/dijit/form/nls/nb/ComboBox.js b/includes/js/dijit/form/nls/nb/ComboBox.js new file mode 100644 index 0000000..de14554 --- /dev/null +++ b/includes/js/dijit/form/nls/nb/ComboBox.js @@ -0,0 +1 @@ +({"previousMessage":"Tidligere valg","nextMessage":"Flere valg"})
\ No newline at end of file diff --git a/includes/js/dijit/form/nls/nb/Textarea.js b/includes/js/dijit/form/nls/nb/Textarea.js new file mode 100644 index 0000000..16fadf5 --- /dev/null +++ b/includes/js/dijit/form/nls/nb/Textarea.js @@ -0,0 +1 @@ +({"iframeEditTitle":"redigeringsområde","iframeFocusTitle":"ramme for redigeringsområde"})
\ No newline at end of file diff --git a/includes/js/dijit/form/nls/nb/validate.js b/includes/js/dijit/form/nls/nb/validate.js new file mode 100644 index 0000000..2fe96f2 --- /dev/null +++ b/includes/js/dijit/form/nls/nb/validate.js @@ -0,0 +1 @@ +({"rangeMessage":"Denne verdien er utenfor gyldig område.","invalidMessage":"Den angitte verdien er ikke gyldig.","missingMessage":"Denne verdien er obligatorisk."})
\ No newline at end of file diff --git a/includes/js/dijit/form/nls/nl/ComboBox.js b/includes/js/dijit/form/nls/nl/ComboBox.js new file mode 100644 index 0000000..b5885d7 --- /dev/null +++ b/includes/js/dijit/form/nls/nl/ComboBox.js @@ -0,0 +1 @@ +({"previousMessage":"Eerdere opties","nextMessage":"Meer opties"})
\ No newline at end of file diff --git a/includes/js/dijit/form/nls/nl/Textarea.js b/includes/js/dijit/form/nls/nl/Textarea.js new file mode 100644 index 0000000..d13c3a6 --- /dev/null +++ b/includes/js/dijit/form/nls/nl/Textarea.js @@ -0,0 +1 @@ +({"iframeEditTitle":"veld bewerken","iframeFocusTitle":"veldkader bewerken"})
\ No newline at end of file diff --git a/includes/js/dijit/form/nls/nl/validate.js b/includes/js/dijit/form/nls/nl/validate.js new file mode 100644 index 0000000..b3062c1 --- /dev/null +++ b/includes/js/dijit/form/nls/nl/validate.js @@ -0,0 +1 @@ +({"rangeMessage":"Deze waarde is niet toegestaan.","invalidMessage":"De opgegeven waarde is ongeldig.","missingMessage":"Deze waarde is verplicht."})
\ No newline at end of file diff --git a/includes/js/dijit/form/nls/pl/ComboBox.js b/includes/js/dijit/form/nls/pl/ComboBox.js new file mode 100644 index 0000000..f2b4b08 --- /dev/null +++ b/includes/js/dijit/form/nls/pl/ComboBox.js @@ -0,0 +1 @@ +({"previousMessage":"Poprzednie wybory","nextMessage":"Więcej wyborów"})
\ No newline at end of file diff --git a/includes/js/dijit/form/nls/pl/Textarea.js b/includes/js/dijit/form/nls/pl/Textarea.js new file mode 100644 index 0000000..8948800 --- /dev/null +++ b/includes/js/dijit/form/nls/pl/Textarea.js @@ -0,0 +1 @@ +({"iframeEditTitle":"obszar edycji","iframeFocusTitle":"ramka obszaru edycji"})
\ No newline at end of file diff --git a/includes/js/dijit/form/nls/pl/validate.js b/includes/js/dijit/form/nls/pl/validate.js new file mode 100644 index 0000000..cf05d2f --- /dev/null +++ b/includes/js/dijit/form/nls/pl/validate.js @@ -0,0 +1 @@ +({"rangeMessage":"Ta wartość jest spoza zakresu.","invalidMessage":"Wprowadzona wartość jest niepoprawna.","missingMessage":"Ta wartość jest wymagana."})
\ No newline at end of file diff --git a/includes/js/dijit/form/nls/pt-pt/ComboBox.js b/includes/js/dijit/form/nls/pt-pt/ComboBox.js new file mode 100644 index 0000000..2540542 --- /dev/null +++ b/includes/js/dijit/form/nls/pt-pt/ComboBox.js @@ -0,0 +1 @@ +({"previousMessage":"Opções anteriores","nextMessage":"Mais opções"})
\ No newline at end of file diff --git a/includes/js/dijit/form/nls/pt-pt/Textarea.js b/includes/js/dijit/form/nls/pt-pt/Textarea.js new file mode 100644 index 0000000..bcd75e7 --- /dev/null +++ b/includes/js/dijit/form/nls/pt-pt/Textarea.js @@ -0,0 +1 @@ +({"iframeEditTitle":"área de edição","iframeFocusTitle":"painel da área de edição"})
\ No newline at end of file diff --git a/includes/js/dijit/form/nls/pt-pt/validate.js b/includes/js/dijit/form/nls/pt-pt/validate.js new file mode 100644 index 0000000..c9312e2 --- /dev/null +++ b/includes/js/dijit/form/nls/pt-pt/validate.js @@ -0,0 +1 @@ +({"rangeMessage":"Este valor encontra-se fora do intervalo.","invalidMessage":"O valor introduzido não é válido.","missingMessage":"O valor é requerido."})
\ No newline at end of file diff --git a/includes/js/dijit/form/nls/pt/ComboBox.js b/includes/js/dijit/form/nls/pt/ComboBox.js new file mode 100644 index 0000000..2540542 --- /dev/null +++ b/includes/js/dijit/form/nls/pt/ComboBox.js @@ -0,0 +1 @@ +({"previousMessage":"Opções anteriores","nextMessage":"Mais opções"})
\ No newline at end of file diff --git a/includes/js/dijit/form/nls/pt/Textarea.js b/includes/js/dijit/form/nls/pt/Textarea.js new file mode 100644 index 0000000..7fc20ab --- /dev/null +++ b/includes/js/dijit/form/nls/pt/Textarea.js @@ -0,0 +1 @@ +({"iframeEditTitle":"área de edição","iframeFocusTitle":"quadro da área de edição"})
\ No newline at end of file diff --git a/includes/js/dijit/form/nls/pt/validate.js b/includes/js/dijit/form/nls/pt/validate.js new file mode 100644 index 0000000..fab945e --- /dev/null +++ b/includes/js/dijit/form/nls/pt/validate.js @@ -0,0 +1 @@ +({"rangeMessage":"Este valor está fora dos limites.","invalidMessage":"O valor inserido não é válido.","missingMessage":"Este valor é necessário."})
\ No newline at end of file diff --git a/includes/js/dijit/form/nls/ru/ComboBox.js b/includes/js/dijit/form/nls/ru/ComboBox.js new file mode 100644 index 0000000..193f4ee --- /dev/null +++ b/includes/js/dijit/form/nls/ru/ComboBox.js @@ -0,0 +1 @@ +({"previousMessage":"Предыдущие варианты","nextMessage":"Следующие варианты"})
\ No newline at end of file diff --git a/includes/js/dijit/form/nls/ru/Textarea.js b/includes/js/dijit/form/nls/ru/Textarea.js new file mode 100644 index 0000000..ad7ad22 --- /dev/null +++ b/includes/js/dijit/form/nls/ru/Textarea.js @@ -0,0 +1 @@ +({"iframeEditTitle":"область редактирования","iframeFocusTitle":"фрейм области редактирования"})
\ No newline at end of file diff --git a/includes/js/dijit/form/nls/ru/validate.js b/includes/js/dijit/form/nls/ru/validate.js new file mode 100644 index 0000000..35fb5ca --- /dev/null +++ b/includes/js/dijit/form/nls/ru/validate.js @@ -0,0 +1 @@ +({"rangeMessage":"Это значение вне диапазона.","invalidMessage":"Указано недопустимое значение.","missingMessage":"Это обязательное значение."})
\ No newline at end of file diff --git a/includes/js/dijit/form/nls/sv/ComboBox.js b/includes/js/dijit/form/nls/sv/ComboBox.js new file mode 100644 index 0000000..860bf75 --- /dev/null +++ b/includes/js/dijit/form/nls/sv/ComboBox.js @@ -0,0 +1 @@ +({"previousMessage":"Föregående alternativ","nextMessage":"Fler alternativ"})
\ No newline at end of file diff --git a/includes/js/dijit/form/nls/sv/Textarea.js b/includes/js/dijit/form/nls/sv/Textarea.js new file mode 100644 index 0000000..9e508ac --- /dev/null +++ b/includes/js/dijit/form/nls/sv/Textarea.js @@ -0,0 +1 @@ +({"iframeEditTitle":"redigeringsområde","iframeFocusTitle":"redigeringsområdesram"})
\ No newline at end of file diff --git a/includes/js/dijit/form/nls/sv/validate.js b/includes/js/dijit/form/nls/sv/validate.js new file mode 100644 index 0000000..8c1b537 --- /dev/null +++ b/includes/js/dijit/form/nls/sv/validate.js @@ -0,0 +1 @@ +({"rangeMessage":"Värdet är utanför intervallet.","invalidMessage":"Det angivna värdet är ogiltigt.","missingMessage":"Värdet är obligatoriskt."})
\ No newline at end of file diff --git a/includes/js/dijit/form/nls/tr/ComboBox.js b/includes/js/dijit/form/nls/tr/ComboBox.js new file mode 100644 index 0000000..46f71dc --- /dev/null +++ b/includes/js/dijit/form/nls/tr/ComboBox.js @@ -0,0 +1 @@ +({"previousMessage":"Önceki seçenekler","nextMessage":"Diğer seçenekler"})
\ No newline at end of file diff --git a/includes/js/dijit/form/nls/tr/Textarea.js b/includes/js/dijit/form/nls/tr/Textarea.js new file mode 100644 index 0000000..3f2b5e7 --- /dev/null +++ b/includes/js/dijit/form/nls/tr/Textarea.js @@ -0,0 +1 @@ +({"iframeEditTitle":"düzenleme alanı","iframeFocusTitle":"düzenleme alanı çerçevesi"})
\ No newline at end of file diff --git a/includes/js/dijit/form/nls/tr/validate.js b/includes/js/dijit/form/nls/tr/validate.js new file mode 100644 index 0000000..838dbda --- /dev/null +++ b/includes/js/dijit/form/nls/tr/validate.js @@ -0,0 +1 @@ +({"rangeMessage":"Bu değer aralık dışında.","invalidMessage":"Girilen değer geçersiz.","missingMessage":"Bu değer gerekli."})
\ No newline at end of file diff --git a/includes/js/dijit/form/nls/validate.js b/includes/js/dijit/form/nls/validate.js new file mode 100644 index 0000000..29a1a47 --- /dev/null +++ b/includes/js/dijit/form/nls/validate.js @@ -0,0 +1 @@ +({"rangeMessage":"This value is out of range.","invalidMessage":"The value entered is not valid.","missingMessage":"This value is required."})
\ No newline at end of file diff --git a/includes/js/dijit/form/nls/zh-tw/ComboBox.js b/includes/js/dijit/form/nls/zh-tw/ComboBox.js new file mode 100644 index 0000000..ead5fa6 --- /dev/null +++ b/includes/js/dijit/form/nls/zh-tw/ComboBox.js @@ -0,0 +1 @@ +({"previousMessage":"前一個選擇項","nextMessage":"其他選擇項"})
\ No newline at end of file diff --git a/includes/js/dijit/form/nls/zh-tw/Textarea.js b/includes/js/dijit/form/nls/zh-tw/Textarea.js new file mode 100644 index 0000000..cb7abda --- /dev/null +++ b/includes/js/dijit/form/nls/zh-tw/Textarea.js @@ -0,0 +1 @@ +({"iframeEditTitle":"編輯區","iframeFocusTitle":"編輯區框"})
\ No newline at end of file diff --git a/includes/js/dijit/form/nls/zh-tw/validate.js b/includes/js/dijit/form/nls/zh-tw/validate.js new file mode 100644 index 0000000..b398a31 --- /dev/null +++ b/includes/js/dijit/form/nls/zh-tw/validate.js @@ -0,0 +1 @@ +({"rangeMessage":"此值超出範圍。","invalidMessage":"輸入的值無效。","missingMessage":"必須提供此值。"})
\ No newline at end of file diff --git a/includes/js/dijit/form/nls/zh/ComboBox.js b/includes/js/dijit/form/nls/zh/ComboBox.js new file mode 100644 index 0000000..7cc92cf --- /dev/null +++ b/includes/js/dijit/form/nls/zh/ComboBox.js @@ -0,0 +1 @@ +({"previousMessage":"先前选项","nextMessage":"更多选项"})
\ No newline at end of file diff --git a/includes/js/dijit/form/nls/zh/Textarea.js b/includes/js/dijit/form/nls/zh/Textarea.js new file mode 100644 index 0000000..e1cf172 --- /dev/null +++ b/includes/js/dijit/form/nls/zh/Textarea.js @@ -0,0 +1 @@ +({"iframeEditTitle":"编辑区","iframeFocusTitle":"编辑区框架"})
\ No newline at end of file diff --git a/includes/js/dijit/form/nls/zh/validate.js b/includes/js/dijit/form/nls/zh/validate.js new file mode 100644 index 0000000..e2c01f5 --- /dev/null +++ b/includes/js/dijit/form/nls/zh/validate.js @@ -0,0 +1 @@ +({"rangeMessage":"此值超出范围。","invalidMessage":"输入的值无效。","missingMessage":"此值是必需值。"})
\ No newline at end of file diff --git a/includes/js/dijit/form/templates/Button.html b/includes/js/dijit/form/templates/Button.html new file mode 100644 index 0000000..09dbad8 --- /dev/null +++ b/includes/js/dijit/form/templates/Button.html @@ -0,0 +1,11 @@ +<div class="dijit dijitReset dijitLeft dijitInline" +	dojoAttachEvent="onclick:_onButtonClick,onmouseenter:_onMouse,onmouseleave:_onMouse,onmousedown:_onMouse" +	waiRole="presentation" +	><button class="dijitReset dijitStretch dijitButtonNode dijitButtonContents" dojoAttachPoint="focusNode,titleNode" +		type="${type}" waiRole="button" waiState="labelledby-${id}_label" +		><span class="dijitReset dijitInline ${iconClass}" dojoAttachPoint="iconNode"  + 			><span class="dijitReset dijitToggleButtonIconChar">✓</span  +		></span +		><div class="dijitReset dijitInline"><center class="dijitReset dijitButtonText" id="${id}_label" dojoAttachPoint="containerNode">${label}</center></div +	></button +></div> diff --git a/includes/js/dijit/form/templates/CheckBox.html b/includes/js/dijit/form/templates/CheckBox.html new file mode 100644 index 0000000..580b820 --- /dev/null +++ b/includes/js/dijit/form/templates/CheckBox.html @@ -0,0 +1,7 @@ +<div class="dijitReset dijitInline" waiRole="presentation" +	><input +	 	type="${type}" name="${name}" +		class="dijitReset dijitCheckBoxInput" +		dojoAttachPoint="focusNode" +	 	dojoAttachEvent="onmouseover:_onMouse,onmouseout:_onMouse,onclick:_onClick" +/></div> diff --git a/includes/js/dijit/form/templates/ComboBox.html b/includes/js/dijit/form/templates/ComboBox.html new file mode 100644 index 0000000..b957b54 --- /dev/null +++ b/includes/js/dijit/form/templates/ComboBox.html @@ -0,0 +1,19 @@ +<div class="dijit dijitReset dijitInlineTable dijitLeft" +	id="widget_${id}" +	dojoAttachEvent="onmouseenter:_onMouse,onmouseleave:_onMouse,onmousedown:_onMouse" dojoAttachPoint="comboNode" waiRole="combobox" tabIndex="-1" +	><div style="overflow:hidden;" +		><div class='dijitReset dijitRight dijitButtonNode dijitArrowButton dijitDownArrowButton' +			dojoAttachPoint="downArrowNode" waiRole="presentation" +			dojoAttachEvent="onmousedown:_onArrowMouseDown,onmouseup:_onMouse,onmouseenter:_onMouse,onmouseleave:_onMouse" +			><div class="dijitArrowButtonInner"> </div +			><div class="dijitArrowButtonChar">▼</div +		></div +		><div class="dijitReset dijitValidationIcon"><br></div +		><div class="dijitReset dijitValidationIconText">Χ</div +		><div class="dijitReset dijitInputField" +			><input type="text" autocomplete="off" name="${name}" class='dijitReset' +			dojoAttachEvent="onkeypress:_onKeyPress, onfocus:_update, compositionend,onkeyup" +			dojoAttachPoint="textbox,focusNode" waiRole="textbox" waiState="haspopup-true,autocomplete-list" +		/></div +	></div +></div> diff --git a/includes/js/dijit/form/templates/ComboButton.html b/includes/js/dijit/form/templates/ComboButton.html new file mode 100644 index 0000000..6b46ea0 --- /dev/null +++ b/includes/js/dijit/form/templates/ComboButton.html @@ -0,0 +1,21 @@ +<table class='dijit dijitReset dijitInline dijitLeft' +	cellspacing='0' cellpadding='0' waiRole="presentation" +	><tbody waiRole="presentation"><tr waiRole="presentation" +		><td	class="dijitReset dijitStretch dijitButtonContents dijitButtonNode" +			tabIndex="${tabIndex}" +			dojoAttachEvent="ondijitclick:_onButtonClick,onmouseenter:_onMouse,onmouseleave:_onMouse,onmousedown:_onMouse"  dojoAttachPoint="titleNode" +			waiRole="button" waiState="labelledby-${id}_label" +			><div class="dijitReset dijitInline ${iconClass}" dojoAttachPoint="iconNode" waiRole="presentation"></div +			><div class="dijitReset dijitInline dijitButtonText" id="${id}_label" dojoAttachPoint="containerNode" waiRole="presentation">${label}</div +		></td +		><td class='dijitReset dijitStretch dijitButtonNode dijitArrowButton dijitDownArrowButton' +			dojoAttachPoint="popupStateNode,focusNode" +			dojoAttachEvent="ondijitclick:_onArrowClick, onkeypress:_onKey,onmouseenter:_onMouse,onmouseleave:_onMouse" +			stateModifier="DownArrow" +			title="${optionsTitle}" name="${name}" +			waiRole="button" waiState="haspopup-true" +			><div class="dijitReset dijitArrowButtonInner" waiRole="presentation"> </div +			><div class="dijitReset dijitArrowButtonChar" waiRole="presentation">▼</div +		></td +	></tr></tbody +></table> diff --git a/includes/js/dijit/form/templates/DropDownButton.html b/includes/js/dijit/form/templates/DropDownButton.html new file mode 100644 index 0000000..2e62f55 --- /dev/null +++ b/includes/js/dijit/form/templates/DropDownButton.html @@ -0,0 +1,13 @@ +<div class="dijit dijitReset dijitLeft dijitInline" +	dojoAttachEvent="onmouseenter:_onMouse,onmouseleave:_onMouse,onmousedown:_onMouse,onclick:_onDropDownClick,onkeydown:_onDropDownKeydown,onblur:_onDropDownBlur,onkeypress:_onKey" +	waiRole="presentation" +	><div class='dijitReset dijitRight' waiRole="presentation" +	><button class="dijitReset dijitStretch dijitButtonNode dijitButtonContents" type="${type}" +		dojoAttachPoint="focusNode,titleNode" waiRole="button" waiState="haspopup-true,labelledby-${id}_label" +		><div class="dijitReset dijitInline ${iconClass}" dojoAttachPoint="iconNode" waiRole="presentation"></div +		><div class="dijitReset dijitInline dijitButtonText"  dojoAttachPoint="containerNode,popupStateNode" waiRole="presentation" +			id="${id}_label">${label}</div +		><div class="dijitReset dijitInline dijitArrowButtonInner" waiRole="presentation"> </div +		><div class="dijitReset dijitInline dijitArrowButtonChar" waiRole="presentation">▼</div +	></button +></div></div> diff --git a/includes/js/dijit/form/templates/HorizontalSlider.html b/includes/js/dijit/form/templates/HorizontalSlider.html new file mode 100644 index 0000000..4dac451 --- /dev/null +++ b/includes/js/dijit/form/templates/HorizontalSlider.html @@ -0,0 +1,37 @@ +<table class="dijit dijitReset dijitSlider" cellspacing="0" cellpadding="0" border="0" rules="none" +	><tr class="dijitReset" +		><td class="dijitReset" colspan="2"></td +		><td dojoAttachPoint="containerNode,topDecoration" class="dijitReset" style="text-align:center;width:100%;"></td +		><td class="dijitReset" colspan="2"></td +	></tr +	><tr class="dijitReset" +		><td class="dijitReset dijitSliderButtonContainer dijitSliderButtonContainerH" +			><div class="dijitSliderDecrementIconH" tabIndex="-1" style="display:none" dojoAttachPoint="decrementButton" dojoAttachEvent="onclick: decrement"><span class="dijitSliderButtonInner">-</span></div +		></td +		><td class="dijitReset" +			><div class="dijitSliderBar dijitSliderBumper dijitSliderBumperH dijitSliderLeftBumper dijitSliderLeftBumper" dojoAttachEvent="onclick:_onClkDecBumper"></div +		></td +		><td class="dijitReset" +			><input dojoAttachPoint="valueNode" type="hidden" name="${name}" +			/><div waiRole="presentation" style="position:relative;" dojoAttachPoint="sliderBarContainer" +				><div waiRole="presentation" dojoAttachPoint="progressBar" class="dijitSliderBar dijitSliderBarH dijitSliderProgressBar dijitSliderProgressBarH" dojoAttachEvent="onclick:_onBarClick" +					><div dojoAttachPoint="sliderHandle,focusNode" class="dijitSliderMoveable dijitSliderMoveableH" dojoAttachEvent="onkeypress:_onKeyPress,onmousedown:_onHandleClick" waiRole="slider" valuemin="${minimum}" valuemax="${maximum}" +						><div class="dijitSliderImageHandle dijitSliderImageHandleH"></div +					></div +				></div +				><div waiRole="presentation" dojoAttachPoint="remainingBar" class="dijitSliderBar dijitSliderBarH dijitSliderRemainingBar dijitSliderRemainingBarH" dojoAttachEvent="onclick:_onBarClick"></div +			></div +		></td +		><td class="dijitReset" +			><div class="dijitSliderBar dijitSliderBumper dijitSliderBumperH dijitSliderRightBumper dijitSliderRightBumper" dojoAttachEvent="onclick:_onClkIncBumper"></div +		></td +		><td class="dijitReset dijitSliderButtonContainer dijitSliderButtonContainerH" style="right:0px;" +			><div class="dijitSliderIncrementIconH" tabIndex="-1" style="display:none" dojoAttachPoint="incrementButton" dojoAttachEvent="onclick: increment"><span class="dijitSliderButtonInner">+</span></div +		></td +	></tr +	><tr class="dijitReset" +		><td class="dijitReset" colspan="2"></td +		><td dojoAttachPoint="containerNode,bottomDecoration" class="dijitReset" style="text-align:center;"></td +		><td class="dijitReset" colspan="2"></td +	></tr +></table> diff --git a/includes/js/dijit/form/templates/InlineEditBox.html b/includes/js/dijit/form/templates/InlineEditBox.html new file mode 100644 index 0000000..6db3496 --- /dev/null +++ b/includes/js/dijit/form/templates/InlineEditBox.html @@ -0,0 +1,12 @@ +<span +	><fieldset dojoAttachPoint="editNode" style="display:none;" waiRole="presentation" +		><div dojoAttachPoint="containerNode" dojoAttachEvent="onkeypress:_onEditWidgetKeyPress"></div +		><div dojoAttachPoint="buttonContainer" +			><button class='saveButton' dojoAttachPoint="saveButton" dojoType="dijit.form.Button" dojoAttachEvent="onClick:save">${buttonSave}</button +			><button class='cancelButton' dojoAttachPoint="cancelButton" dojoType="dijit.form.Button" dojoAttachEvent="onClick:cancel">${buttonCancel}</button +		></div +	></fieldset +	><span tabIndex="0" dojoAttachPoint="textNode,focusNode" waiRole="button" style="display:none;" +		dojoAttachEvent="onkeypress:_onKeyPress,onclick:_onClick,onmouseout:_onMouseOut,onmouseover:_onMouseOver,onfocus:_onMouseOver,onblur:_onMouseOut" +	></span +></span> diff --git a/includes/js/dijit/form/templates/Spinner.html b/includes/js/dijit/form/templates/Spinner.html new file mode 100644 index 0000000..981c698 --- /dev/null +++ b/includes/js/dijit/form/templates/Spinner.html @@ -0,0 +1,28 @@ +<div class="dijit dijitReset dijitInlineTable dijitLeft" +	id="widget_${id}" +	dojoAttachEvent="onmouseenter:_onMouse,onmouseleave:_onMouse,onmousedown:_onMouse" waiRole="presentation" +	><div class="dijitInputLayoutContainer" +		><div class="dijitReset dijitSpinnerButtonContainer" +			> <div class="dijitReset dijitLeft dijitButtonNode dijitArrowButton dijitUpArrowButton" +				dojoAttachPoint="upArrowNode" +				dojoAttachEvent="onmouseenter:_onMouse,onmouseleave:_onMouse" +				stateModifier="UpArrow" +				><div class="dijitArrowButtonInner"> </div +				><div class="dijitArrowButtonChar">▲</div +			></div +			><div class="dijitReset dijitLeft dijitButtonNode dijitArrowButton dijitDownArrowButton" +				dojoAttachPoint="downArrowNode" +				dojoAttachEvent="onmouseenter:_onMouse,onmouseleave:_onMouse" +				stateModifier="DownArrow" +				><div class="dijitArrowButtonInner"> </div +				><div class="dijitArrowButtonChar">▼</div +			></div +		></div +		><div class="dijitReset dijitValidationIcon"><br></div +		><div class="dijitReset dijitValidationIconText">Χ</div +		><div class="dijitReset dijitInputField" +			><input class='dijitReset' dojoAttachPoint="textbox,focusNode" type="${type}" dojoAttachEvent="onfocus:_update,onkeyup:_onkeyup,onkeypress:_onKeyPress" +				waiRole="spinbutton" autocomplete="off" name="${name}" +		/></div +	></div +></div> diff --git a/includes/js/dijit/form/templates/TextBox.html b/includes/js/dijit/form/templates/TextBox.html new file mode 100644 index 0000000..804fe1e --- /dev/null +++ b/includes/js/dijit/form/templates/TextBox.html @@ -0,0 +1,4 @@ +<input class="dijit dijitReset dijitLeft" dojoAttachPoint='textbox,focusNode' name="${name}" +	dojoAttachEvent='onmouseenter:_onMouse,onmouseleave:_onMouse,onfocus:_onMouse,onblur:_onMouse,onkeypress:_onKeyPress,onkeyup' +	autocomplete="off" type="${type}" +	/>
\ No newline at end of file diff --git a/includes/js/dijit/form/templates/TimePicker.html b/includes/js/dijit/form/templates/TimePicker.html new file mode 100644 index 0000000..0bf3c40 --- /dev/null +++ b/includes/js/dijit/form/templates/TimePicker.html @@ -0,0 +1,5 @@ +<div id="widget_${id}" class="dijitMenu" +    ><div dojoAttachPoint="upArrow" class="dijitButtonNode"><span class="dijitTimePickerA11yText">▲</span></div +    ><div dojoAttachPoint="timeMenu,focusNode" dojoAttachEvent="onclick:_onOptionSelected,onmouseover,onmouseout"></div +    ><div dojoAttachPoint="downArrow" class="dijitButtonNode"><span class="dijitTimePickerA11yText">▼</span></div +></div> diff --git a/includes/js/dijit/form/templates/ValidationTextBox.html b/includes/js/dijit/form/templates/ValidationTextBox.html new file mode 100644 index 0000000..2bdb674 --- /dev/null +++ b/includes/js/dijit/form/templates/ValidationTextBox.html @@ -0,0 +1,12 @@ +<div class="dijit dijitReset dijitInlineTable dijitLeft" +	id="widget_${id}" +	dojoAttachEvent="onmouseenter:_onMouse,onmouseleave:_onMouse,onmousedown:_onMouse" waiRole="presentation" +	><div style="overflow:hidden;" +		><div class="dijitReset dijitValidationIcon"><br></div +		><div class="dijitReset dijitValidationIconText">Χ</div +		><div class="dijitReset dijitInputField" +			><input class="dijitReset" dojoAttachPoint='textbox,focusNode' dojoAttachEvent='onfocus:_update,onkeyup:_onkeyup,onblur:_onMouse,onkeypress:_onKeyPress' autocomplete="off" +			type='${type}' name='${name}' +		/></div +	></div +></div> diff --git a/includes/js/dijit/form/templates/VerticalSlider.html b/includes/js/dijit/form/templates/VerticalSlider.html new file mode 100644 index 0000000..88b2951 --- /dev/null +++ b/includes/js/dijit/form/templates/VerticalSlider.html @@ -0,0 +1,46 @@ +<table class="dijitReset dijitSlider" cellspacing="0" cellpadding="0" border="0" rules="none" +><tbody class="dijitReset" +	><tr class="dijitReset" +		><td class="dijitReset"></td +		><td class="dijitReset dijitSliderButtonContainer dijitSliderButtonContainerV" +			><div class="dijitSliderIncrementIconV" tabIndex="-1" style="display:none" dojoAttachPoint="incrementButton" dojoAttachEvent="onclick:_topButtonClicked"><span class="dijitSliderButtonInner">+</span></div +		></td +		><td class="dijitReset"></td +	></tr +	><tr class="dijitReset" +		><td class="dijitReset"></td +		><td class="dijitReset" +			><center><div class="dijitSliderBar dijitSliderBumper dijitSliderBumperV dijitSliderTopBumper dijitSliderTopBumper" dojoAttachEvent="onclick:_onClkIncBumper"></div></center +		></td +		><td class="dijitReset"></td +	></tr +	><tr class="dijitReset" +		><td dojoAttachPoint="leftDecoration" class="dijitReset" style="text-align:center;height:100%;"></td +		><td class="dijitReset" style="height:100%;" +			><input dojoAttachPoint="valueNode" type="hidden" name="${name}" +			/><center waiRole="presentation" style="position:relative;height:100%;" dojoAttachPoint="sliderBarContainer" +				><div waiRole="presentation" dojoAttachPoint="remainingBar" class="dijitSliderBar dijitSliderBarV dijitSliderRemainingBar dijitSliderRemainingBarV" dojoAttachEvent="onclick:_onBarClick"><!--#5629--></div +				><div waiRole="presentation" dojoAttachPoint="progressBar" class="dijitSliderBar dijitSliderBarV dijitSliderProgressBar dijitSliderProgressBarV" dojoAttachEvent="onclick:_onBarClick" +					><div dojoAttachPoint="sliderHandle,focusNode" class="dijitSliderMoveable" dojoAttachEvent="onkeypress:_onKeyPress,onmousedown:_onHandleClick" style="vertical-align:top;" waiRole="slider" valuemin="${minimum}" valuemax="${maximum}" +						><div class="dijitSliderImageHandle dijitSliderImageHandleV"></div +					></div +				></div +			></center +		></td +		><td dojoAttachPoint="containerNode,rightDecoration" class="dijitReset" style="text-align:center;height:100%;"></td +	></tr +	><tr class="dijitReset" +		><td class="dijitReset"></td +		><td class="dijitReset" +			><center><div class="dijitSliderBar dijitSliderBumper dijitSliderBumperV dijitSliderBottomBumper dijitSliderBottomBumper" dojoAttachEvent="onclick:_onClkDecBumper"></div></center +		></td +		><td class="dijitReset"></td +	></tr +	><tr class="dijitReset" +		><td class="dijitReset"></td +		><td class="dijitReset dijitSliderButtonContainer dijitSliderButtonContainerV" +			><div class="dijitSliderDecrementIconV" tabIndex="-1" style="display:none" dojoAttachPoint="decrementButton" dojoAttachEvent="onclick:_bottomButtonClicked"><span class="dijitSliderButtonInner">-</span></div +		></td +		><td class="dijitReset"></td +	></tr +></tbody></table> | 
