diff options
Diffstat (limited to 'includes/js/dojox/form')
-rw-r--r-- | includes/js/dojox/form/CheckedMultiSelect.js | 223 | ||||
-rw-r--r-- | includes/js/dojox/form/DropDownSelect.js | 267 | ||||
-rw-r--r-- | includes/js/dojox/form/PasswordValidator.js | 280 | ||||
-rw-r--r-- | includes/js/dojox/form/README | 39 | ||||
-rw-r--r-- | includes/js/dojox/form/nls/PasswordValidator.js | 1 | ||||
-rw-r--r-- | includes/js/dojox/form/resources/CheckedMultiSelect.css | 65 | ||||
-rw-r--r-- | includes/js/dojox/form/resources/CheckedMultiSelect.css.commented.css | 99 | ||||
-rw-r--r-- | includes/js/dojox/form/resources/CheckedMultiSelect.html | 4 | ||||
-rw-r--r-- | includes/js/dojox/form/resources/DropDownSelect.css | 137 | ||||
-rw-r--r-- | includes/js/dojox/form/resources/DropDownSelect.css.commented.css | 209 | ||||
-rw-r--r-- | includes/js/dojox/form/resources/PasswordValidator.html | 3 | ||||
-rw-r--r-- | includes/js/dojox/form/resources/_CheckedMultiSelectItem.html | 4 | ||||
-rw-r--r-- | includes/js/dojox/form/tests/test_CheckedMultiSelect.html | 91 | ||||
-rw-r--r-- | includes/js/dojox/form/tests/test_DropDownSelect.html | 128 | ||||
-rw-r--r-- | includes/js/dojox/form/tests/test_PasswordValidator.html | 216 |
15 files changed, 1766 insertions, 0 deletions
diff --git a/includes/js/dojox/form/CheckedMultiSelect.js b/includes/js/dojox/form/CheckedMultiSelect.js new file mode 100644 index 0000000..eb80c72 --- /dev/null +++ b/includes/js/dojox/form/CheckedMultiSelect.js @@ -0,0 +1,223 @@ +if(!dojo._hasResource["dojox.form.CheckedMultiSelect"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. +dojo._hasResource["dojox.form.CheckedMultiSelect"] = true; +dojo.provide("dojox.form.CheckedMultiSelect"); + +dojo.require("dijit.form.MultiSelect"); +dojo.require("dijit.form.CheckBox"); + +dojo.declare("dojox.form._CheckedMultiSelectItem", + [dijit._Widget, dijit._Templated], + { + // summary: + // The individual items for a CheckedMultiSelect + + widgetsInTemplate: true, + templateString:"<div class=\"dijitReset ${baseClass}\"\n\t><input class=\"${baseClass}Box\" dojoType=\"dijit.form.CheckBox\" dojoAttachPoint=\"checkBox\" dojoAttachEvent=\"_onClick:_changeBox\" type=\"checkbox\" \n\t><div class=\"dijitInline ${baseClass}Label\" dojoAttachPoint=\"labelNode\" dojoAttachEvent=\"onmousedown:_onMouse,onmouseover:_onMouse,onmouseout:_onMouse,onclick:_onClick\">${option.innerHTML}</div\n></div>\n", + + baseClass: "dojoxMultiSelectItem", + + // option: Element + // The option that is associated with this item + option: null, + parent: null, + + // disabled: boolean + // Whether or not this widget is disabled + disabled: false, + + _changeBox: function(){ + // summary: + // Called to force the select to match the state of the check box + // (only on click of the checkbox) + this.option.selected = this.checkBox.getValue() && true; + + // fire the parent's change + this.parent._onChange(); + + // refocus the parent + this.parent.focus(); + }, + + _labelClick: function(){ + // summary: + // Called when the label portion is clicked + dojo.stopEvent(e); + if(this.disabled){ + return; + } + var cb = this.checkBox; + cb.setValue(!cb.getValue()); + this._changeBox(); + }, + + _onMouse: function(e){ + // summary: + // Sets the hover state depending on mouse state (passes through + // to the check box) + this.checkBox._onMouse(e); + }, + + _onClick: function(e){ + // summary: + // Sets the click state (passes through to the check box) + this.checkBox._onClick(e); + }, + + _updateBox: function(){ + // summary: + // Called to force the box to match the state of the select + this.checkBox.setValue(this.option.selected); + }, + + setAttribute: function(attr, value){ + // summary: + // Disables (or enables) all the children as well + this.inherited(arguments); + switch(attr){ + case "disabled": + this.checkBox.setAttribute(attr, value); + break; + default: + break; + } + } +}); + +dojo.declare("dojox.form.CheckedMultiSelect", dijit.form.MultiSelect, { + // summary: + // Extends the core dijit MultiSelect to provide a "checkbox" selector + + templateString: "", + templateString:"<div class=\"dijit dijitReset dijitInline\" dojoAttachEvent=\"onmousedown:_mouseDown,onclick:focus\"\n\t><select class=\"${baseClass}Select\" multiple=\"true\" dojoAttachPoint=\"containerNode,focusNode\" dojoAttachEvent=\"onchange: _onChange\"></select\n\t><div dojoAttachPoint=\"wrapperDiv\"></div\n></div>\n", + + baseClass: "dojoxMultiSelect", + + // children: dojox.form._CheckedMultiSelectItem[] + // Array of all our children (for updating them) + children: [], + + /*===== + dojox.form.__SelectOption = function(){ + // value: String + // The value of the option. Setting to empty (or missing) will + // place a separator at that location + // label: String + // The label for our option. It can contain html tags. + this.value = value; + this.label = label; + } + =====*/ + + // options: dojox.form.__SelectOption[] + // our set of options + options: null, + + _mouseDown: function(e){ + // summary: + // Cancels the mousedown event to prevent others from stealing + // focus + dojo.stopEvent(e); + }, + + _updateChildren: function(){ + // summary: + // Called to update the checked states of my children to match me + dojo.forEach(this.children,function(child){ + child._updateBox(); + }); + }, + + _addChild: function(/*Element*/ option){ + // summary: + // Adds and returns a child for the given option. + var item = new dojox.form._CheckedMultiSelectItem({ + option: option, + parent: this + }); + this.wrapperDiv.appendChild(item.domNode); + return item; + }, + + _loadChildren: function(){ + // summary: + // Reloads the children to match our box. + + // Destroy any existing children before loading them again + dojo.forEach(this.children, function(child){ + child.destroyRecursive(); + }); + this.children = dojo.query("option", this.domNode).map(function(child){ + return this._addChild(child); + }, this); + this.options = dojo.map(this.children, function(child){ + var opt = child.option; + return { value:opt.value, label: opt.text }; + }); + // Update the statuses of the children + this._updateChildren(); + }, + + addOption: function(/* dojox.form.__SelectOption or string, optional */ value, /* string? */ label){ + // summary: Adds the given option to the select + + var o = new Option("",""); + o.value = value.value || value; + o.innerHTML = value.label || label; + this.containerNode.appendChild(o); + }, + + removeOption: function(/*String*/ optionId){ + dojo.query("option[value=" + optionId + "]", this.domNode).forEach(function(node){ + node.parentNode.removeChild(node); + }, this); + }, + + setOptionLabel: function(/*string*/ optionId, /*string*/ label){ + dojo.query("option[value=" + optionId + "]", this.domNode).forEach(function(node){ + node.innerHTML = label; + }); + }, + + addSelected: function(select){ + this.inherited(arguments); + + // Reload my children and the children of the guy pointing to me + if(select._loadChildren){ + select._loadChildren(); + } + this._loadChildren(); + }, + + setAttribute: function(attr, value){ + // summary: + // Disable (or enable) all the children as well + this.inherited(arguments); + switch(attr){ + case "disabled": + dojo.forEach(this.children, function(node){ + if(node && node.setAttribute){ + node.setAttribute(attr, value); + } + }); + break; + default: + break; + } + }, + + startup: function(){ + if(this._started){ return; } + this.inherited(arguments); + + // Load children and make connections + this._loadChildren(); + this.connect(this, "setValue", "_updateChildren"); + this.connect(this, "invertSelection", "_updateChildren"); + this.connect(this, "addOption", "_loadChildren"); + this.connect(this, "removeOption", "_loadChildren"); + this.connect(this, "setOptionLabel", "_loadChildren"); + this._started = true; + } +}); + +} diff --git a/includes/js/dojox/form/DropDownSelect.js b/includes/js/dojox/form/DropDownSelect.js new file mode 100644 index 0000000..94d26d1 --- /dev/null +++ b/includes/js/dojox/form/DropDownSelect.js @@ -0,0 +1,267 @@ +if(!dojo._hasResource["dojox.form.DropDownSelect"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. +dojo._hasResource["dojox.form.DropDownSelect"] = true; +dojo.provide("dojox.form.DropDownSelect"); + +dojo.require("dijit.form.Button"); +dojo.require("dijit.Menu"); + +dojo.require("dojo.data.ItemFileWriteStore"); + +dojo.declare("dojox.form.DropDownSelect", dijit.form.DropDownButton, { + // summary: + // This is a "Styleable" select box - it is basically a DropDownButton which + // can take as its input a <select>. + + baseClass: "dojoxDropDownSelect", + + /*===== + dojox.form.__SelectOption = function(){ + // value: String + // The value of the option. Setting to empty (or missing) will + // place a separator at that location + // label: String + // The label for our option. It can contain html tags. + this.value = value; + this.label = label; + } + =====*/ + + // options: dojox.form.__SelectOption[] + // our set of options + options: null, + + // emptyLabel: string + // What to display in an "empty" dropdown + emptyLabel: "", + + // _isPopulated: boolean + // Whether or not we have been populated + _isPopulated: false, + + _addMenuItem: function(/* dojox.form.__SelectOption */ option){ + // summary: + // For the given option, add a menu item to our dropdown + // If the option doesn't have a value, then a separator is added + // in that place. + var menu = this.dropDown; + + if(!option.value){ + // We are a separator (no label set for it) + menu.addChild(new dijit.MenuSeparator()); + }else{ + // Just a regular menu option + var click = dojo.hitch(this, "setAttribute","value",option); + var mi = new dijit.MenuItem({ + id: this.id + "_item_" + option.value, + label: option.label, + onClick: click + }); + menu.addChild(mi); + + } + }, + + _resetButtonState: function(){ + // summary: + // Resets the menu and the length attribute of the button - and + // ensures that the label is appropriately set. + var len = this.options.length; + + // reset the menu to make it "populatable on the next click + var dropDown = this.dropDown; + dojo.forEach(dropDown.getChildren(), function(child){ + child.destroyRecursive(); + }); + this._isPopulated = false; + + // Set our length attribute and our value + this.setAttribute("readOnly", (len === 1)); + this.setAttribute("disabled", (len === 0)); + this.setAttribute("value", this.value); + }, + + _updateSelectedState: function(){ + // summary: + // Sets the "selected" class on the item for styling purposes + var val = this.value; + if(val){ + var testId = this.id + "_item_" + val; + dojo.forEach(this.dropDown.getChildren(), function(child){ + dojo[child.id === testId ? "addClass" : "removeClass"](child.domNode, + this.baseClass + "SelectedOption"); + }, this); + } + }, + + addOption: function(/* dojox.form.__SelectOption or string, optional */ value, /* string? */ label){ + // summary: + // Adds an option to the end of the select. If value is empty or + // missing, a separator is created instead. + + this.options.push(value.value ? value : { value:value, label:label }); + }, + + removeOption: function(/* string, dojox.form.__SelectOption or number */ valueOrIdx){ + // summary: + // Removes the given option + this.options = dojo.filter(this.options, function(node, idx){ + return !((typeof valueOrIdx === "number" && idx === valueOrIdx) || + (typeof valueOrIdx === "string" && node.value === valueOrIdx) || + (valueOrIdx.value && node.value === valueOrIdx.value)); + }); + }, + + setOptionLabel: function(/*string*/ value, /*string*/ label){ + dojo.forEach(this.options, function(node){ + if(node.value === value){ + node.label = label; + } + }); + }, + + destroy: function(){ + // summary: + // Clear out an outstanding hack handle + if(this._labelHackHandle){ + clearTimeout(this._labelHackHandle); + } + this.inherited(arguments); + }, + + setLabel: function(/* string */ content){ + // summary: + // Wraps our label in a div - that way, our rich text can work + // correctly. + + content = '<div class=" ' + this.baseClass + 'Label">' + + content + + '</div>'; + // Because FF2 has a problem with layout, we need to delay this + // call for it. + if(this._labelHackHandle){ + clearTimeout(this._labelHackHandle); + } + if(dojo.isFF === 2){ + this._labelHackHandle = setTimeout(dojo.hitch(this, function(){ + this._labelHackHandle = null; + dijit.form.DropDownButton.prototype.setLabel.call(this, content); + }), 0); + }else{ + this.inherited(arguments); + } + }, + + setAttribute: function(/*string*/ attr, /* anything */ value){ + // summary: sometime we get called to set our value - we need to + // make sure and route those requests through _setValue() + // instead. + if(attr === "value"){ + // If a string is passed, then we set our value from looking it up. + if(typeof value === "string"){ + value = dojo.filter(this.options, function(node){ + return node.value === value; + })[0]; + } + + // If we don't have a value, try to show the first item + if(!value){ + value = this.options[0] || { value: "", label: "" }; + } + this.value = value.value; + if(this._started){ + this.setLabel(value.label || this.emptyLabel || " "); + } + this._handleOnChange(value.value); + value = this.value; + }else{ + this.inherited(arguments); + } + }, + + _fillContent: function(){ + // summary: + // Loads our options and sets up our dropdown correctly. We + // don't want any content, so we don't call any inherit chain + // function. + var opts = this.options; + if(!opts){ + opts = this.options = this.srcNodeRef ? dojo.query(">", + this.srcNodeRef).map(function(node){ + if(node.getAttribute("type") === "separator"){ + return { value: "", label: "" }; + } + return { value: node.getAttribute("value"), + label: String(node.innerHTML) }; + }, this) : []; + } + + // Set the value to be the first, or the selected index + if(opts.length && !this.value){ + var si = this.srcNodeRef.selectedIndex; + this.value = opts[si != -1 ? si : 0].value; + } + + // Create the dropDown widget + this.dropDown = new dijit.Menu(); + }, + + postCreate: function(){ + // summary: sets up our event handling that we need for functioning + // as a select + + this.inherited(arguments); + + // Make our event connections for updating state + var fx = function(){ + dojo[this._opened ? "addClass" : "removeClass"](this.focusNode, + this.baseClass + "ButtonOpened"); + }; + this.connect(this, "_openDropDown", fx); + this.connect(this, "_closeDropDown", fx); + this.connect(this, "onChange", "_updateSelectedState"); + this.connect(this, "addOption", "_resetButtonState"); + this.connect(this, "removeOption", "_resetButtonState"); + this.connect(this, "setOptionLabel", "_resetButtonState"); + }, + + startup: function(){ + // summary: + // FF2 has layout problems if the reset call isn't done on a + // slight delay + this.inherited(arguments); + if(dojo.isFF === 2){ + setTimeout(dojo.hitch(this, this._resetButtonState), 0); + }else{ + this._resetButtonState(); + } + }, + + _populate: function(/* function */ callback){ + // summary: + // populates the menu (and does the callback, if passed) + + var dropDown = this.dropDown; + + // Add each menu item + dojo.forEach(this.options, this._addMenuItem, this); + + // Update states + this._updateSelectedState(); + dojo.addClass(this.dropDown.domNode, this.baseClass + "Menu"); + this._isPopulated = true; + if(callback){ callback.call(this); } + }, + + _toggleDropDown: function(){ + // summary: Overrides DropDownButton's toggle function to make sure + // that the values are correctly populated. + var dropDown = this.dropDown; + if(dropDown && !dropDown.isShowingNow && !this._isPopulated){ + this._populate(dojox.form.DropDownSelect.superclass._toggleDropDown); + }else{ + this.inherited(arguments); + } + } +}); + +} diff --git a/includes/js/dojox/form/PasswordValidator.js b/includes/js/dojox/form/PasswordValidator.js new file mode 100644 index 0000000..e147ddf --- /dev/null +++ b/includes/js/dojox/form/PasswordValidator.js @@ -0,0 +1,280 @@ +if(!dojo._hasResource["dojox.form.PasswordValidator"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. +dojo._hasResource["dojox.form.PasswordValidator"] = true; +dojo.provide("dojox.form.PasswordValidator"); + +dojo.require("dijit.form._FormWidget"); +dojo.require("dijit.form.ValidationTextBox"); + +dojo.requireLocalization("dojox.form", "PasswordValidator", null, "ROOT"); + +dojo.declare("dojox.form._ChildTextBox", dijit.form.ValidationTextBox, { + // summary: + // A class that is shared between all our children - extends + // ValidationTextBox and provides some shared functionality + // + // containerWidget: widget + // Our parent (the PasswordValidator) + containerWidget: null, + + // type: string + // Don't override this - we are all "password" types + type: "password", + + reset: function(){ + // summary: + // Force-set to empty string (we don't save passwords EVER)...and + // since _OldPWBox overrides setValue to check for empty string, + // call our parent class directly (not this.inherited()) + dijit.form.ValidationTextBox.prototype.setValue.call(this, "", true); + this._hasBeenBlurred = false; + } +}); + + + +dojo.declare("dojox.form._OldPWBox", dojox.form._ChildTextBox, { + // summary: + // A class representing our "old password" box. + // + // _isPWValid: boolean + // Whether or not the password is valid + _isPWValid: false, + + setValue: function(/* anything */ newVal, /* boolean? */ priority){ + // summary: + // Updates _isPWValid if this isn't our initial update by calling + // our PasswordValidator's pwCheck function + if(newVal === ""){ + newVal = dojox.form._OldPWBox.superclass.getValue.call(this); + } + if(priority !== null){ + // Priority is passed in as null, explicitly when this is an + // update (not initially set). We want to check our password now. + this._isPWValid = this.containerWidget.pwCheck(newVal); + } + this.inherited("setValue", arguments); + }, + + isValid: function(/* boolean */ isFocused){ + // Take into account the isPWValid setting + return this.inherited("isValid", arguments) && this._isPWValid; + }, + + _update: function(/* event */ e){ + // Only call validate() if we've been blurred or else we get popups + // too early. + if(this._hasBeenBlurred){ this.validate(true); } + this._onMouse(e); + }, + + getValue: function(){ + // summary: + // Only returns a value if our container widget is valid. This + // is to prevent exposure of "oldPW" too early. + if(this.containerWidget.isValid()){ + return this.inherited("getValue", arguments); + }else{ + return ""; + } + } +}); + + +dojo.declare("dojox.form._NewPWBox", dojox.form._ChildTextBox, { + // summary: + // A class representing our new password textbox + + // required: boolean + // Whether or not this widget is required (default: true) + required: true, + + onChange: function(){ + // summary: + // Validates our verify box - to make sure that a change to me is + // reflected there + this.containerWidget._inputWidgets[2].validate(false); + this.inherited(arguments); + } +}); + +dojo.declare("dojox.form._VerifyPWBox", dojox.form._ChildTextBox, { + // summary: + // A class representing our verify textbox + + isValid: function(isFocused){ + // summary: + // Validates that we match the "real" password + return this.inherited("isValid", arguments) && + (this.getValue() == this.containerWidget._inputWidgets[1].getValue()); + } +}); + +dojo.declare("dojox.form.PasswordValidator", dijit.form._FormValueWidget, { + // summary: + // A password validation widget that simplifies the "old/new/verify" + // style of requesting passwords. You will probably want to override + // this class and implement your own pwCheck function. + // + // required: boolean + // Whether or not it is required for form submission + required: true, + + // inputWidgets: TextBox[] + // An array of text boxes that are our components + _inputWidgets: null, + + // oldName: string? + // The name to send our old password as (when form is posted) + oldName: "", + + templateString:"<div dojoAttachPoint=\"containerNode\">\n\t<input type=\"hidden\" name=\"${name}\" value=\"\" dojoAttachPoint=\"focusNode\" />\n</div>\n", + + _hasBeenBlurred: false, + + isValid: function(/* boolean */ isFocused){ + // summary: we are valid if ALL our children are valid + return dojo.every(this._inputWidgets, function(i){ + if(i && i._setStateClass){ i._setStateClass(); } + return (!i || i.isValid()); + }); + }, + + validate: function(/* boolean */ isFocused){ + // summary: Validating this widget validates all our children + return dojo.every(dojo.map(this._inputWidgets, function(i){ + if(i && i.validate){ + i._hasBeenBlurred = (i._hasBeenBlurred || this._hasBeenBlurred); + return i.validate(); + } + return true; + }, this), "return item;"); + }, + + reset: function(){ + // summary: Resetting this widget resets all our children + this._hasBeenBlurred = false; + dojo.forEach(this._inputWidgets, function(i){ + if(i && i.reset){ i.reset(); } + }, this); + }, + + _createSubWidgets: function(){ + // summary: + // Turns the inputs inside this widget into "real" validation + // widgets - and sets up the needed connections. + var widgets = this._inputWidgets, + msg = dojo.i18n.getLocalization("dojox.form", "PasswordValidator", + this.lang); + dojo.forEach(widgets, function(i, idx){ + if(i){ + var p = {containerWidget: this}, c; + if(idx === 0){ + p.name = this.oldName; + p.invalidMessage = msg.badPasswordMessage; + c = dojox.form._OldPWBox; + }else if(idx === 1){ + p.required = this.required; + c = dojox.form._NewPWBox; + }else if(idx === 2){ + p.invalidMessage = msg.nomatchMessage; + c = dojox.form._VerifyPWBox; + } + widgets[idx] = new c(p, i); + } + }, this); + }, + + pwCheck: function(/* string */ password){ + // summary: + // Overridable function for validation of the old password box. + // + // This function is called and passed the old password. Return + // true if it's OK to continue, and false if it is not. + // + // IMPORTANT SECURITY NOTE: Do NOT EVER EVER EVER check this in + // HTML or JavaScript!!! + // + // You will probably want to override this function to callback + // to a server to verify the password (the callback will need to + // be syncronous) - and it's probably a good idea to validate + // it again on form submission before actually doing + // anything destructive - that's why the "oldName" value + // is available. + // + // And don't just fetch the password from the server + // either :) Send the test password (probably hashed, for + // security) and return from the server a status instead. + // + // Again - DON'T BE INSECURE!!! Security is left as an exercise + // for the reader :) + return false; + }, + + postCreate: function(){ + // summary: + // Sets up the correct widgets. You *MUST* specify one child + // text box (a simple HTML <input> element) with pwType="new" + // *and* one child text box with pwType="verify". You *MAY* + // specify a third child text box with pwType="old" in order to + // prompt the user to enter in their old password before the + // widget returns that it is valid. + + this.inherited(arguments); + + // Turn my inputs into the correct stuff.... + var widgets = this._inputWidgets = []; + dojo.forEach(["old","new","verify"], function(i){ + widgets.push(dojo.query("input[pwType=" + i + "]", + this.containerNode)[0]); + }, this); + if (!widgets[1] || !widgets[2]){ + throw new Error("Need at least pwType=\"new\" and pwType=\"verify\""); + } + if (this.oldName && !widgets[0]){ + throw new Error("Need to specify pwType=\"old\" if using oldName"); + } + this._createSubWidgets(); + }, + + setAttribute: function(/* string */ attr, /* anything */ value){ + this.inherited(arguments); + + // Disabling (or enabling) the container disables (or enables) all + // the subwidgets as well - same for requiring + switch(attr){ + case "disabled": + case "required": + dojo.forEach(this._inputWidgets, function(i){ + if(i && i.setAttribute){ i.setAttribute(attr, value);} + }); + break; + default: + break; + } + }, + + getValue: function(){ + // summary: overridden to return an empty string if we aren't valid. + if (this.isValid()){ + return this._inputWidgets[1].getValue(); + }else{ + return ""; + } + }, + + focus: function(){ + // summary: + // places focus on the first invalid input widget - if all + // input widgets are valid, the first widget is focused. + var f = false; + dojo.forEach(this._inputWidgets, function(i){ + if(i && !i.isValid() && !f){ + i.focus(); + f = true; + } + }); + if(!f){ this._inputWidgets[1].focus(); } + } +}); + +} diff --git a/includes/js/dojox/form/README b/includes/js/dojox/form/README new file mode 100644 index 0000000..3fc4f7c --- /dev/null +++ b/includes/js/dojox/form/README @@ -0,0 +1,39 @@ +-------------------------------------------------------------------------------
+dojox.form Collection
+-------------------------------------------------------------------------------
+Version 1.0
+Release date: 02/26/2008
+-------------------------------------------------------------------------------
+Project state:
+experimental
+-------------------------------------------------------------------------------
+Credits
+ Nathan Toone (nathan)
+
+-------------------------------------------------------------------------------
+Project description
+
+ This is a collection of additional widgets that can be used in forms.
+-------------------------------------------------------------------------------
+Dependencies:
+
+ Depends on dojo core and dijit
+-------------------------------------------------------------------------------
+Documentation
+
+-------------------------------------------------------------------------------
+Installation instructions
+
+ Install into /dojox/form
+-------------------------------------------------------------------------------
+Additional Notes (Brief widget list):
+
+ * CheckedMultiSelect - an extension to dijit.form.MultiSelect which
+ uses check boxes instead of ctrl-click
+
+ * PasswordValidator - a widget which simplifies the common "old/new/verify"
+ mechanism of specifying passwords
+
+ * DropDownSelect - an extension to dijit.form.DropDownButton which is
+ meant to mirror the html <select> drop down
+
diff --git a/includes/js/dojox/form/nls/PasswordValidator.js b/includes/js/dojox/form/nls/PasswordValidator.js new file mode 100644 index 0000000..4887d27 --- /dev/null +++ b/includes/js/dojox/form/nls/PasswordValidator.js @@ -0,0 +1 @@ +({"badPasswordMessage":"Invalid Password.","nomatchMessage":"Passwords do not match."})
\ No newline at end of file diff --git a/includes/js/dojox/form/resources/CheckedMultiSelect.css b/includes/js/dojox/form/resources/CheckedMultiSelect.css new file mode 100644 index 0000000..1953b1e --- /dev/null +++ b/includes/js/dojox/form/resources/CheckedMultiSelect.css @@ -0,0 +1,65 @@ + +.dojoxMultiSelectSelect { display: none; } +.dojoxMultiSelect { + border: solid black 1px; + margin: 1px 0; + overflow: scroll; + overflow-y: scroll; + overflow-x: hidden; + height: 100px; +} +.dj_ie .dojoxMultiSelect, +.dj_safari .dojoxMultiSelect { + + padding-right: 15px; +} +.dojoxMultiSelectItem { + white-space: nowrap; + padding:.1em .2em; + cursor:default; +} +.dojoxMultiSelectDisabled * { + color:gray !important; +} +.dojoxMultiSelectItemLabel { + margin-left: .2em; +} +.tundra .dojoxMultiSelect { + margin: 0em 0.1em; +} +.tundra .dojoxMultiSelect { + background:#fff url("../../../dijit/themes/tundra/images/validationInputBg.png") repeat-x top left; + #background:#fff url('../../../dijit/themes/tundra/images/validationInputBg.gif') repeat-x top left; + border:1px solid #b3b3b3; + line-height: normal; +} +.tundra .dojoxMultiSelectFocused { + + border-color:#406b9b; +} +.soria .dojoxMultiSelect { + margin: 0em 0.1em; +} +.soria .dojoxMultiSelect { + background:#fff url("../../../dijit/themes/soria/images/validationInputBg.png") repeat-x top left; + #background:#fff url('../../../dijit/themes/soria/images/validationInputBg.gif') repeat-x top left; + border:1px solid #8ba0bd; + line-height: normal; +} +.soria .dojoxMultiSelectFocused { + + border-color:#406b9b; +} +.nihilo .dojoxMultiSelect { + margin: 0em 0.1em; +} +.nihilo .dojoxMultiSelect { + background:#fff url("../../../dijit/themes/nihilo/images/validationInputBg.png") repeat-x top left; + #background:#fff url('../../../dijit/themes/nihilo/images/validationInputBg.gif') repeat-x top left; + border:1px solid #d3d3d3; + line-height: normal; +} +.nihilo .dojoxMultiSelectFocused { + + border-color:#b3b3b3; +} diff --git a/includes/js/dojox/form/resources/CheckedMultiSelect.css.commented.css b/includes/js/dojox/form/resources/CheckedMultiSelect.css.commented.css new file mode 100644 index 0000000..32cd0b5 --- /dev/null +++ b/includes/js/dojox/form/resources/CheckedMultiSelect.css.commented.css @@ -0,0 +1,99 @@ +/* +**---------------------------------------------------------------------------- +** CheckedMultiSelect +**---------------------------------------------------------------------------- +*/ +.dojoxMultiSelectSelect { display: none; } + +.dojoxMultiSelect { + border: solid black 1px; + margin: 1px 0; + overflow: scroll; + overflow-y: scroll; + overflow-x: hidden; + height: 100px; +} + +.dj_ie .dojoxMultiSelect, +.dj_safari .dojoxMultiSelect { + /* So that the scroll bar doesn't cover stuff up */ + padding-right: 15px; +} + +.dojoxMultiSelectItem { + white-space: nowrap; + padding:.1em .2em; + cursor:default; +} + +.dojoxMultiSelectDisabled * { + color:gray !important; +} + +.dojoxMultiSelectItemLabel { + margin-left: .2em; +} + +/* +**---------------------------------------------------------------------------- +** Tundra theme (make look similar to text box) +**---------------------------------------------------------------------------- +*/ +.tundra .dojoxMultiSelect { + margin: 0em 0.1em; +} + +.tundra .dojoxMultiSelect { + background:#fff url("../../../dijit/themes/tundra/images/validationInputBg.png") repeat-x top left; + #background:#fff url('../../../dijit/themes/tundra/images/validationInputBg.gif') repeat-x top left; + border:1px solid #b3b3b3; + line-height: normal; +} + +.tundra .dojoxMultiSelectFocused { + /* input field when focused (ie: typing affects it) */ + border-color:#406b9b; +} + +/* +**---------------------------------------------------------------------------- +** Soria theme (make look similar to text box) +**---------------------------------------------------------------------------- +*/ +.soria .dojoxMultiSelect { + margin: 0em 0.1em; +} + +.soria .dojoxMultiSelect { + background:#fff url("../../../dijit/themes/soria/images/validationInputBg.png") repeat-x top left; + #background:#fff url('../../../dijit/themes/soria/images/validationInputBg.gif') repeat-x top left; + border:1px solid #8ba0bd; + line-height: normal; +} + +.soria .dojoxMultiSelectFocused { + /* input field when focused (ie: typing affects it) */ + border-color:#406b9b; +} + +/* +**---------------------------------------------------------------------------- +** Nihilo theme (make look similar to text box) +**---------------------------------------------------------------------------- +*/ +.nihilo .dojoxMultiSelect { + margin: 0em 0.1em; +} + +.nihilo .dojoxMultiSelect { + background:#fff url("../../../dijit/themes/nihilo/images/validationInputBg.png") repeat-x top left; + #background:#fff url('../../../dijit/themes/nihilo/images/validationInputBg.gif') repeat-x top left; + border:1px solid #d3d3d3; + line-height: normal; +} + +.nihilo .dojoxMultiSelectFocused { + /* input field when focused (ie: typing affects it) */ + border-color:#b3b3b3; +} + diff --git a/includes/js/dojox/form/resources/CheckedMultiSelect.html b/includes/js/dojox/form/resources/CheckedMultiSelect.html new file mode 100644 index 0000000..256aad7 --- /dev/null +++ b/includes/js/dojox/form/resources/CheckedMultiSelect.html @@ -0,0 +1,4 @@ +<div class="dijit dijitReset dijitInline" dojoAttachEvent="onmousedown:_mouseDown,onclick:focus" + ><select class="${baseClass}Select" multiple="true" dojoAttachPoint="containerNode,focusNode" dojoAttachEvent="onchange: _onChange"></select + ><div dojoAttachPoint="wrapperDiv"></div +></div>
\ No newline at end of file diff --git a/includes/js/dojox/form/resources/DropDownSelect.css b/includes/js/dojox/form/resources/DropDownSelect.css new file mode 100644 index 0000000..cbd1971 --- /dev/null +++ b/includes/js/dojox/form/resources/DropDownSelect.css @@ -0,0 +1,137 @@ + +.dojoxDropDownSelect { + margin: 0.2em; +} +.dijit_a11y .dojoxDropDownSelectDisabled .dijitButtonNode { + border-style: dotted !important; + border-color: #999 !important; + color:#999 !important; +} +.dojoxDropDownSelect .dijitButtonNode { + padding: 0px; +} +.dijitButtonNode .dojoxDropDownSelectLabel * +{ + vertical-align: baseline; +} +.dojoxDropDownSelectSelectedOption * { + font-weight: bold; +} +.dojoxDropDownSelectDisabled .dijitArrowButtonInner, +.dojoxDropDownSelectReadOnly .dijitArrowButtonInner { + display: none; +} +.dojoxDropDownSelectMenu .dijitMenuItemIcon { + width: 1px; +} +.tundra .dojoxDropDownSelectDisabled * { + cursor: not-allowed !important; +} +.tundra .dojoxDropDownSelectReadOnly * { + cursor: default !important; +} +.tundra .dojoxDropDownSelectDisabled * { + cursor: not-allowed !important; +} +.tundra .dojoxDropDownSelectReadOnly * { + cursor: default !important; +} +.tundra .dojoxDropDownSelect .dijitButtonNode { + background:#fff url("../../../dijit/themes/tundra/images/validationInputBg.png") repeat-x top left; + #background:#fff url('../../../dijit/themes/tundra/images/validationInputBg.gif') repeat-x top left; + border:1px solid #b3b3b3; + line-height: normal; +} +.tundra .dojoxDropDownSelectDisabled .dijitButtonNode { + + border-color: #d5d5d5 #bdbdbd #bdbdbd #d5d5d5; + + background:#e4e4e4 url("../../../dijit/themes/tundra/images/buttonDisabled.png") top repeat-x; + opacity: 0.60; +} +.dj_ie .tundra .dojoxDropDownSelectDisabled .dijitButtonNode * { + filter: gray() alpha(opacity=50); +} +.tundra .dojoxDropDownSelectHover .dijitButtonNode, +.tundra .dojoxDropDownSelect .dojoxDropDownSelectButtonOpened { + + + border-color:#a5beda; + border-bottom-color:#5c7590; + border-right-color:#5c7590; + color:#000; + background:#fcfdff url("../../../dijit/themes/tundra/images/buttonHover.png") repeat-x bottom; +} +.tundra .dojoxDropDownSelectActive .dijitButtonNode { + + border-color:#366dba; + background: #ededed url("../../../dijit/themes/tundra/images/buttonActive.png") bottom repeat-x; +} +.soria .dojoxDropDownSelectDisabled * { + cursor: not-allowed !important; +} +.soria .dojoxDropDownSelectReadOnly * { + cursor: default !important; +} +.soria .dojoxDropDownSelect .dijitButtonNode { + background:#fff url("../../../dijit/themes/soria/images/validationInputBg.png") repeat-x top left; + #background:#fff url('../../../dijit/themes/soria/images/validationInputBg.gif') repeat-x top left; + border:1px solid #8ba0bd; + line-height: normal; +} +.soria .dojoxDropDownSelectDisabled .dijitButtonNode { + + border-color: #b9bbdd #b9bbdd #b9bbdd #b9bbdd; + + background:#c3d3e5 url("../../../dijit/themes/soria/images/buttonDisabled.png") top repeat-x; + opacity: 0.60; +} +.dj_ie .soria .dojoxDropDownSelectDisabled .dijitButtonNode * { + filter: gray() alpha(opacity=50); +} +.soria .dojoxDropDownSelectHover .dijitButtonNode, +.soria .dojoxDropDownSelect .dojoxDropDownSelectButtonOpened { + + + color:#000; + background:#acc5e2 url("../../../dijit/themes/soria/images/buttonHover.png") repeat-x top left; +} +.soria .dojoxDropDownSelectActive .dijitButtonNode { + + border-color:#657c9c; + background: #91b4e5 url("../../../dijit/themes/soria/images/buttonActive.png") top left repeat-x; +} +.nihilo .dojoxDropDownSelectDisabled * { + cursor: not-allowed !important; +} +.nihilo .dojoxDropDownSelectReadOnly * { + cursor: default !important; +} +.nihilo .dojoxDropDownSelect .dijitButtonNode { + background:#fff url("../../../dijit/themes/nihilo/images/validationInputBg.png") repeat-x top left; + #background:#fff url('../../../dijit/themes/nihilo/images/validationInputBg.gif') repeat-x top left; + border:1px solid #d3d3d3; + line-height: normal; +} +.nihilo .dojoxDropDownSelectDisabled .dijitButtonNode { + + border-color: #dedede; + + background:#fafafa url("../../../dijit/themes/nihilo/images/buttonDisabled.png") top repeat-x; + opacity: 0.60; +} +.dj_ie .nihilo .dojoxDropDownSelectDisabled .dijitButtonNode * { + filter: gray() alpha(opacity=50); +} +.nihilo .dojoxDropDownSelectHover .dijitButtonNode, +.nihilo .dojoxDropDownSelect .dojoxDropDownSelectButtonOpened { + + + color:#000; + background:#fcfcfc url("../../../dijit/themes/nihilo/images/buttonHover.png") repeat-x top left; +} +.nihilo .dojoxDropDownSelectActive .dijitButtonNode { + + border-color:#dedede; + background: #f5f5f5 url("../../../dijit/themes/nihilo/images/buttonActive.png") top left repeat-x; +} diff --git a/includes/js/dojox/form/resources/DropDownSelect.css.commented.css b/includes/js/dojox/form/resources/DropDownSelect.css.commented.css new file mode 100644 index 0000000..a0a0636 --- /dev/null +++ b/includes/js/dojox/form/resources/DropDownSelect.css.commented.css @@ -0,0 +1,209 @@ +/* +**---------------------------------------------------------------------------- +** DropDownSelect +**---------------------------------------------------------------------------- +*/ +/* Mirror dijitDropDownButton a bit */ +.dojoxDropDownSelect { + margin: 0.2em; +} +.dijit_a11y .dojoxDropDownSelectDisabled .dijitButtonNode { + border-style: dotted !important; + border-color: #999 !important; + color:#999 !important; +} + +/* And remove the padding - so it looks a "bit" more like a text box */ +.dojoxDropDownSelect .dijitButtonNode { + padding: 0px; +} + +/* Fix the baseline of our label (for multi-size font elements) */ +.dijitButtonNode .dojoxDropDownSelectLabel * +{ + vertical-align: baseline; +} + +/* Styling for the currently-selected option (rich text can mess this up) */ +.dojoxDropDownSelectSelectedOption * { + font-weight: bold; +} + +/* And remove the arrow when we are read-only or disabled (1 or 0 options) */ +.dojoxDropDownSelectDisabled .dijitArrowButtonInner, +.dojoxDropDownSelectReadOnly .dijitArrowButtonInner { + display: none; +} + +/* And hide (at least, mostly) the menuItemIcon column */ +.dojoxDropDownSelectMenu .dijitMenuItemIcon { + width: 1px; +} + +/* +**---------------------------------------------------------------------------- +** Common stylings +**---------------------------------------------------------------------------- +*/ +/* Cursor States */ +.tundra .dojoxDropDownSelectDisabled * { + cursor: not-allowed !important; +} +.tundra .dojoxDropDownSelectReadOnly * { + cursor: default !important; +} + + +/* +**---------------------------------------------------------------------------- +** Tundra stylings +**---------------------------------------------------------------------------- +*/ +/* Cursor States */ +.tundra .dojoxDropDownSelectDisabled * { + cursor: not-allowed !important; +} +.tundra .dojoxDropDownSelectReadOnly * { + cursor: default !important; +} + +/* Make unselected "look" more like a text box and less like a button */ +.tundra .dojoxDropDownSelect .dijitButtonNode { + background:#fff url("../../../dijit/themes/tundra/images/validationInputBg.png") repeat-x top left; + #background:#fff url('../../../dijit/themes/tundra/images/validationInputBg.gif') repeat-x top left; + border:1px solid #b3b3b3; + line-height: normal; +} + +/* Mirror DropDownButton */ +.tundra .dojoxDropDownSelectDisabled .dijitButtonNode { + /* disabled state - inner */ + border-color: #d5d5d5 #bdbdbd #bdbdbd #d5d5d5; + /*color:#b4b4b4;*/ + background:#e4e4e4 url("../../../dijit/themes/tundra/images/buttonDisabled.png") top repeat-x; + opacity: 0.60; /* Safari, Opera and Mozilla */ +} + +.dj_ie .tundra .dojoxDropDownSelectDisabled .dijitButtonNode * { + filter: gray() alpha(opacity=50); /* IE */ +} + +.tundra .dojoxDropDownSelectHover .dijitButtonNode, +.tundra .dojoxDropDownSelect .dojoxDropDownSelectButtonOpened { + /* hover and opened state - inner */ + /* TODO: change from Hover to Selected so that button is still highlighted while drop down is being used */ + border-color:#a5beda; + border-bottom-color:#5c7590; + border-right-color:#5c7590; + color:#000; + background:#fcfdff url("../../../dijit/themes/tundra/images/buttonHover.png") repeat-x bottom; +} + +.tundra .dojoxDropDownSelectActive .dijitButtonNode { + /* active state - inner (for when you are pressing a normal button, or + * when a toggle button is in a depressed state + */ + border-color:#366dba; + background: #ededed url("../../../dijit/themes/tundra/images/buttonActive.png") bottom repeat-x; +} + + +/* +**---------------------------------------------------------------------------- +** Soria stylings +**---------------------------------------------------------------------------- +*/ +/* Cursor States */ +.soria .dojoxDropDownSelectDisabled * { + cursor: not-allowed !important; +} +.soria .dojoxDropDownSelectReadOnly * { + cursor: default !important; +} + +/* Make unselected "look" more like a text box and less like a button */ +.soria .dojoxDropDownSelect .dijitButtonNode { + background:#fff url("../../../dijit/themes/soria/images/validationInputBg.png") repeat-x top left; + #background:#fff url('../../../dijit/themes/soria/images/validationInputBg.gif') repeat-x top left; + border:1px solid #8ba0bd; + line-height: normal; +} + +/* Mirror DropDownButton */ +.soria .dojoxDropDownSelectDisabled .dijitButtonNode { + /* disabled state - inner */ + border-color: #b9bbdd #b9bbdd #b9bbdd #b9bbdd; + /*color:#b4b4b4;*/ + background:#c3d3e5 url("../../../dijit/themes/soria/images/buttonDisabled.png") top repeat-x; + opacity: 0.60; /* Safari, Opera and Mozilla */ +} + +.dj_ie .soria .dojoxDropDownSelectDisabled .dijitButtonNode * { + filter: gray() alpha(opacity=50); /* IE */ +} + +.soria .dojoxDropDownSelectHover .dijitButtonNode, +.soria .dojoxDropDownSelect .dojoxDropDownSelectButtonOpened { + /* hover state - inner */ + /* TODO: change from Hover to Selected so that button is still highlighted while drop down is being used */ + color:#000; + background:#acc5e2 url("../../../dijit/themes/soria/images/buttonHover.png") repeat-x top left; +} + +.soria .dojoxDropDownSelectActive .dijitButtonNode { + /* active state - inner (for when you are pressing a normal button, or + * when a toggle button is in a depressed state + */ + border-color:#657c9c; + background: #91b4e5 url("../../../dijit/themes/soria/images/buttonActive.png") top left repeat-x; +} + +/* +**---------------------------------------------------------------------------- +** Nihilo stylings +**---------------------------------------------------------------------------- +*/ +/* Cursor States */ +.nihilo .dojoxDropDownSelectDisabled * { + cursor: not-allowed !important; +} +.nihilo .dojoxDropDownSelectReadOnly * { + cursor: default !important; +} + +/* Make unselected "look" more like a text box and less like a button */ +.nihilo .dojoxDropDownSelect .dijitButtonNode { + background:#fff url("../../../dijit/themes/nihilo/images/validationInputBg.png") repeat-x top left; + #background:#fff url('../../../dijit/themes/nihilo/images/validationInputBg.gif') repeat-x top left; + border:1px solid #d3d3d3; + line-height: normal; +} + +/* Mirror DropDownButton */ +.nihilo .dojoxDropDownSelectDisabled .dijitButtonNode { + /* disabled state - inner */ + border-color: #dedede; + /*color:#b4b4b4;*/ + background:#fafafa url("../../../dijit/themes/nihilo/images/buttonDisabled.png") top repeat-x; + opacity: 0.60; /* Safari, Opera and Mozilla */ +} + +.dj_ie .nihilo .dojoxDropDownSelectDisabled .dijitButtonNode * { + filter: gray() alpha(opacity=50); /* IE */ +} + +.nihilo .dojoxDropDownSelectHover .dijitButtonNode, +.nihilo .dojoxDropDownSelect .dojoxDropDownSelectButtonOpened { + /* hover state - inner */ + /* TODO: change from Hover to Selected so that button is still highlighted while drop down is being used */ + color:#000; + background:#fcfcfc url("../../../dijit/themes/nihilo/images/buttonHover.png") repeat-x top left; +} + +.nihilo .dojoxDropDownSelectActive .dijitButtonNode { + /* active state - inner (for when you are pressing a normal button, or + * when a toggle button is in a depressed state + */ + border-color:#dedede; + background: #f5f5f5 url("../../../dijit/themes/nihilo/images/buttonActive.png") top left repeat-x; +} diff --git a/includes/js/dojox/form/resources/PasswordValidator.html b/includes/js/dojox/form/resources/PasswordValidator.html new file mode 100644 index 0000000..80a55ae --- /dev/null +++ b/includes/js/dojox/form/resources/PasswordValidator.html @@ -0,0 +1,3 @@ +<div dojoAttachPoint="containerNode"> + <input type="hidden" name="${name}" value="" dojoAttachPoint="focusNode" /> +</div>
\ No newline at end of file diff --git a/includes/js/dojox/form/resources/_CheckedMultiSelectItem.html b/includes/js/dojox/form/resources/_CheckedMultiSelectItem.html new file mode 100644 index 0000000..d9ec863 --- /dev/null +++ b/includes/js/dojox/form/resources/_CheckedMultiSelectItem.html @@ -0,0 +1,4 @@ +<div class="dijitReset ${baseClass}" + ><input class="${baseClass}Box" dojoType="dijit.form.CheckBox" dojoAttachPoint="checkBox" dojoAttachEvent="_onClick:_changeBox" type="checkbox" + ><div class="dijitInline ${baseClass}Label" dojoAttachPoint="labelNode" dojoAttachEvent="onmousedown:_onMouse,onmouseover:_onMouse,onmouseout:_onMouse,onclick:_onClick">${option.innerHTML}</div +></div> diff --git a/includes/js/dojox/form/tests/test_CheckedMultiSelect.html b/includes/js/dojox/form/tests/test_CheckedMultiSelect.html new file mode 100644 index 0000000..b8729d2 --- /dev/null +++ b/includes/js/dojox/form/tests/test_CheckedMultiSelect.html @@ -0,0 +1,91 @@ +<html> + <head> + <script type="text/javascript" + src="../../../dojo/dojo.js" + djConfig="isDebug: true, parseOnLoad: true"> + </script> + <script type="text/javascript"> + dojo.require("doh.runner"); + dojo.require("dojo.parser"); + dojo.require("dojox.form.CheckedMultiSelect"); + dojo.require("dijit.form.Button"); + dojo.require("dijit.form.Form"); + + dojo.addOnLoad(function(){ + doh.register("tests", + [ + function test_setValue(t){ + t.is(["VA","WA"], form.getValues().ms1); + form.setValues({ms1: ["TN","CA"]}); + t.is(["TN","CA"], form.getValues().ms1); + ms1.invertSelection(); + t.is(["VA","WA","FL"], form.getValues().ms1); + }, + function test_addSelected(t){ + ms1.addSelected(ms2); + t.is([], form.getValues().ms2); + ms1.invertSelection(); + t.is(["TN","CA"], form.getValues().ms1); + }, + ] + ); + doh.run(); + dojo.connect(ms1, "onChange", function(val){ + console.log("First Select Changed to " + val); + }); + }); + </script> + <style> + @import url(../../../dojo/resources/dojo.css); + @import url(../../../dijit/themes/tundra/tundra.css); + @import url(../resources/CheckedMultiSelect.css); + @import url(../../../dijit/tests/css/dijitTests.css); + </style> + </head> + <body class="tundra"> + <h1 class="testTitle">Test: dojox.form.CheckedMultiSelect</h1> + <h2>Automated test</h2> + <form dojoType="dijit.form.Form" jsId="form"> + <select jsId="ms1" multiple="true" name="ms1" dojoType="dojox.form.CheckedMultiSelect"> + <option value="TN">Tennessee</option> + <option value="VA" selected="selected">Virginia</option> + <option value="WA" selected="selected">Washington</option> + <option value="FL">Florida</option> + <option value="CA">California</option> + </select> + <hr> + <select jsId="ms2" multiple="true" name="ms2" dojoType="dojox.form.CheckedMultiSelect"> + <option value="UT">Utah</option> + <option value="TX" selected="selected">Texas</option> + <option value="GA" selected="selected">Georgia</option> + <option value="ID">Idaho</option> + <option value="WY">Wyoming</option> + <option value="OR">Oregon</option> + <option value="PA">Pennsylvania</option> + </select> + <hr> + <select jsId="ms3" multiple="true" name="ms3" dojoType="dojox.form.CheckedMultiSelect"> + </select> + <hr> + <button dojoType="dijit.form.Button"> + <script type="dojo/method" event="onClick"> + console.dir(form.getValues()); + </script> + Get Values + </button> + <button dojoType="dijit.form.Button"> + <script type="dojo/method" event="onClick"> + var idx = dojo.query("option", ms3.domNode).length; + ms3.addOption(idx + "", "Option " + (idx + 1)); + </script> + Add Option + </button> + <button dojoType="dijit.form.Button"> + <script type="dojo/method" event="onClick"> + ms3.setAttribute("disabled", !ms3.disabled); + </script> + Toggle Disabled + </button> + </form> + </body> +</html> diff --git a/includes/js/dojox/form/tests/test_DropDownSelect.html b/includes/js/dojox/form/tests/test_DropDownSelect.html new file mode 100644 index 0000000..4487e54 --- /dev/null +++ b/includes/js/dojox/form/tests/test_DropDownSelect.html @@ -0,0 +1,128 @@ +<html> + <head> + <script type="text/javascript" + src="../../../dojo/dojo.js" + djConfig="isDebug: true, parseOnLoad: true"> + </script> + <script type="text/javascript"> + dojo.require("doh.runner"); + dojo.require("dojo.parser"); + dojo.require("dojox.form.DropDownSelect"); + dojo.require("dijit.form.Button"); + dojo.require("dijit.form.Form"); + + var numOptions = 0; + var numChanges = 0; + + dojo.addOnLoad(function(){ + dojo.connect(s1, "onChange", function(val){ + console.log("First Select Changed to " + val); + numChanges++; + }); + doh.register("tests", + [ + function test_setValue(t){ + t.is({s1:"VA", s2:"CA", s3:"AL", s4: "AK", s5: "move", s6:"", s7:"NY"}, form.getValues()); + s1.setAttribute("value", "WA"); + t.is("WA", s1.value); + s1.setAttribute("value", "UT"); + t.is("TN", s1.value); + t.is(2, numChanges); + } + ] + ); + doh.run(); + }); + </script> + <style> + @import url(../../../dojo/resources/dojo.css); + @import url(../../../dijit/themes/tundra/tundra.css); + @import url(../resources/DropDownSelect.css); + @import url(../../../dijit/tests/css/dijitTests.css); + </style> + <style> + .ark { text-decoration: underline; } + </style> + </head> + <body class="tundra"> + <h1 class="testTitle">Test: dojox.form.DropDownSelect</h1> + <h2>Automated test</h2> + <form dojoType="dijit.form.Form" jsId="form"> + <h4 class="testSubtitle">Setting Defaults</h4> + <select jsId="s1" name="s1" dojoType="dojox.form.DropDownSelect"> + <option value="TN">Tennessee</option> + <option value="VA" selected="selected">Virginia</option> + <option value="WA">Washington</option> + <option value="FL">Florida</option> + <option value="CA">California</option> + </select> + <select jsId="s2" name="s2" value="CA" dojoType="dojox.form.DropDownSelect"> + <option value="AL">Alabama</option> + <option value="AK">Alaska</option> + <option value="AZ">Arizona</option> + <option value="AR">Arkansas</option> + <option value="CA">California</option> + </select> + <select jsId="s3" name="s3" dojoType="dojox.form.DropDownSelect"> + <option value="AL">Alabama</option> + <option value="AK">Alaska</option> + <option type="separator"></option> + <option value="AZ">Arizona</option> + <option value="AR">Arkansas</option> + <option type="separator"></option> + <option value="CA">California</option> + </select> + <hr> + <h4 class="testSubtitle">Rich Text (Need to use divs and spans - since browsers hack selects to pieces)</h4> + <div jsId="s4" name="s4" value="AK" dojoType="dojox.form.DropDownSelect"> + <span value="AL"><b>Alabama</b></span> + <span value="AK"><font color="red">A</font><font color="orange">l</font><font color="yellow">a</font><font color="green">s</font><font color="blue">k</font><font color="purple">a</font></span> + <span value="AZ"><i>Arizona</i></span> + <span value="AR"><span class="ark">Arkansas</span></span> + <span value="CA"><span style="font-size:25%">C</span><span style="font-size:50%">a</span><span style="font-size:75%">l</span><span style="font-size:90%">i</span><span style="font-size:100%">f</span><span style="font-size:125%">o</span><span style="font-size:133%">r</span><span style="font-size:150%">n</span><span style="font-size:175%">i</span><span style="font-size:200%">a</span></span> + <span value="NM">New<br> Mexico</span> + </div> + <div jsId="s5" name="s5" value="move" dojoType="dojox.form.DropDownSelect"> + <span value="copy"><img style="vertical-align: middle;margin-top: 1px;margin-bottom:1px;" src="../../../dijit/themes/tundra/images/dndCopy.png" /> Copy</span> + <span value="move"><img style="vertical-align: middle;margin-top: 1px;margin-bottom:1px;" src="../../../dijit/themes/tundra/images/dndMove.png" /> Move</span> + <span value="nocopy"><img style="vertical-align: middle;margin-top: 1px;margin-bottom:1px;" src="../../../dijit/themes/tundra/images/dndNoCopy.png" /> No Copy</span> + <span value="nomove"><img style="vertical-align: middle;margin-top: 1px;margin-bottom:1px;" src="../../../dijit/themes/tundra/images/dndNoMove.png" /> No Move</span> + </div> + <hr> + <h4 class="testSubtitle">Empty</h4> + <select jsId="s6" name="s6" dojoType="dojox.form.DropDownSelect"> + </select> + <hr> + <h4 class="testSubtitle">Single Item</h4> + <select jsId="s7" name="s7" dojoType="dojox.form.DropDownSelect"> + <option value="NY">New York</option> + </select> + <hr> + <button dojoType="dijit.form.Button"> + <script type="dojo/method" event="onClick"> + console.dir(form.getValues()); + </script> + Get Values + </button> + <button dojoType="dijit.form.Button"> + <script type="dojo/method" event="onClick"> + numOptions++; + s6.addOption(numOptions + "", "Option " + numOptions); + </script> + Add Option + </button> + <button dojoType="dijit.form.Button"> + <script type="dojo/method" event="onClick"> + s6.removeOption(0); + </script> + Remove Top Option + </button> + <button dojoType="dijit.form.Button"> + <script type="dojo/method" event="onClick"> + s4.setAttribute("disabled", !s4.disabled); + </script> + Toggle Disabled + </button> + </form> + </body> +</html> diff --git a/includes/js/dojox/form/tests/test_PasswordValidator.html b/includes/js/dojox/form/tests/test_PasswordValidator.html new file mode 100644 index 0000000..e3b1e63 --- /dev/null +++ b/includes/js/dojox/form/tests/test_PasswordValidator.html @@ -0,0 +1,216 @@ +<html> + <head> + <script type="text/javascript" + src="../../../dojo/dojo.js" + djConfig="isDebug: true, parseOnLoad: true"> + </script> + <script type="text/javascript"> + dojo.require("doh.runner"); + dojo.require("dojo.parser"); + dojo.require("dojox.form.PasswordValidator"); + dojo.require("dijit.form.Button"); + dojo.require("dijit.form.Form"); + + dojo.addOnLoad(function(){ + doh.register("tests", + [ + function test_setDisabled(t){ + valid1.setAttribute("disabled", true); + t.t(dojo.every(dojo.query("[widgetId]", + valid1.domNode).map(function(i){ + return dijit.byNode(i); + }), function(i){return i.disabled;})); + valid1.setAttribute("disabled", false); + t.t(dojo.every(dojo.query("[widgetId]", + valid1.domNode).map(function(i){ + return dijit.byNode(i); + }), function(i){return !i.disabled;})); + }, + function test_isValid(t){ + t.f(form1.isValid()); + dijit.byId("nv1").setValue("test"); + dijit.byId("vv1").setValue("Test"); + t.f(form1.isValid()); + dijit.byId("vv1").setValue("test"); + t.t(form1.isValid()); + t.t(form6.isValid()); + t.is({password: ""}, form6.getValues()); + dijit.byId("nv6").setValue("test"); + t.f(form6.isValid()); + t.is({password: ""}, form6.getValues()); + dijit.byId("vv6").setValue("test"); + t.t(form6.isValid()); + t.is({password: "test"}, form6.getValues()); + }, + function test_getValue(t){ + dijit.byId("nv1").setValue("test"); + dijit.byId("vv1").setValue("Test"); + t.is({password: ""}, form1.getValues()); + dijit.byId("vv1").setValue("test123"); + dijit.byId("nv1").setValue("test123"); + t.is({password: "test123"}, form1.getValues()); + }, + function test_oldPW(t){ + dijit.byId("nv2").setValue("test"); + dijit.byId("vv2").setValue("test"); + t.f(form2.isValid()); + dijit.byId("ov2").setValue("oldpw4"); + t.f(form2.isValid()); + dijit.byId("ov2").setValue("oldpw2"); + t.t(form2.isValid()); + }, + function test_getOldValue(t){ + t.is({password: "test"}, form2.getValues()); + dijit.byId("nv3").setValue("test"); + dijit.byId("vv3").setValue("test"); + dijit.byId("ov3").setValue("oldpw4"); + t.is({password: "", oldPassword: ""}, form3.getValues()); + dijit.byId("ov3").setValue("oldpw3"); + dijit.byId("vv3").setValue("Test"); + t.is({password: "", oldPassword: ""}, form3.getValues()); + dijit.byId("vv3").setValue("test"); + t.is({password: "test", oldPassword: "oldpw3"}, form3.getValues()); + }, + function test_getValuesInTable(t){ + dijit.byId("nv4").setValue("test"); + dijit.byId("vv4").setValue("test"); + dijit.byId("ov4").setValue("oldpw4"); + t.is({password: "test"}, form4.getValues()); + dijit.byId("nv5").setValue("test"); + dijit.byId("vv5").setValue("test"); + dijit.byId("ov5").setValue("oldpw5"); + t.is({password: "test", oldPassword: "oldpw5"}, form5.getValues()); + } + ] + ); + doh.run(); + }); + </script> + <link rel="stylesheet" type="text/css" href="../../../dijit/themes/tundra/tundra.css"> + <link rel="stylesheet" type="text/css" href="../../../dijit/tests/css/dijitTests.css"> + </head> + <body class="tundra"> + <h1 class="testTitle">Test: dojox.form.PasswordValidator</h1> + <h2>Automated test</h2> + <h4 class="testSubtitle">No old password</h4> + <form dojoType="dijit.form.Form" jsId="form1"> + <div dojoType="dojox.form.PasswordValidator" jsId="valid1" name="password"> + <label>Password: <input type="password" id="nv1" pwType="new" /></label><br> + <label>Validate: <input type="password" id="vv1" pwType="verify" /></label><br> + </div> + </form> + <hr> + <h4 class="testSubtitle">Old password (hard-coded to "oldpw2") - not passed to getValues</h4> + <form dojoType="dijit.form.Form" jsId="form2"> + <div dojoType="dojox.form.PasswordValidator" jsId="valid2" name="password"> + <script type="dojo/method" event="pwCheck" args="password"> + /* + NOTE: Do NOT EVER EVER EVER do this sort of a check!!! + + This is only as an example. You will probably want to + override the pwCheck function to callback to a server to + verify the password (the callback will need to be + syncronous) - and it's probably a good idea to validate + it again on form submission before actually doing + anything destructive - that's why the "oldName" value + is there. + + And don't just fetch the password from the server + either :) Send the test password (probably hashed, for + security) and return from the server a status instead. + + Again - DON'T DO THIS - it is HORRIBLY INSECURE!!!! + + Security is left as an exercise to the reader :) + */ + return password === "oldpw2"; + </script> + <label>Old Password: <input type="password" id="ov2" pwType="old" /></label><br> + <label>Password: <input type="password" id="nv2" pwType="new" /></label><br> + <label>Validate: <input type="password" id="vv2" pwType="verify" /></label><br> + </div> + </form> + <hr> + <h4 class="testSubtitle">Old password (hard-coded to "oldpw3") - passed to getValues</h4> + <form dojoType="dijit.form.Form" jsId="form3"> + <div dojoType="dojox.form.PasswordValidator" jsId="valid3" name="password" oldName="oldPassword"> + <script type="dojo/method" event="pwCheck" args="password"> + console.log("Checking " + password); + return password === "oldpw3"; + </script> + <label>Old Password: <input type="password" id="ov3" pwType="old" /></label><br> + <label>Password: <input type="password" id="nv3" pwType="new" /></label><br> + <label>Validate: <input type="password" id="vv3" pwType="verify" /></label><br> + </div> + </form> + <hr> + <h4 class="testSubtitle">In Table, Old password (hard-coded to "oldpw4") - not passed to getValues</h4> + <form dojoType="dijit.form.Form" jsId="form4"> + <div dojoType="dojox.form.PasswordValidator" jsId="valid4" name="password"> + <script type="dojo/method" event="pwCheck" args="password"> + return password === "oldpw4"; + </script> + <table> + <tr> + <td><label for="ov4">Old Password:</label></td> + <td><input type="password" id="ov4" pwType="old" /></td> + </tr> + <tr> + <td><label for="nv4">Password:</label></td> + <td><input type="password" id="nv4" pwType="new" /></td> + </tr> + <tr> + <td><label for="vv4">Validate:</label></td> + <td><input type="password" id="vv4" pwType="verify" /></td> + </tr> + </table> + </div> + </form> + <hr> + <h4 class="testSubtitle">In Table, Old password (hard-coded to "oldpw5") - passed to getValues</h4> + <form dojoType="dijit.form.Form" jsId="form5"> + <div dojoType="dojox.form.PasswordValidator" jsId="valid5" name="password" oldName="oldPassword"> + <script type="dojo/method" event="pwCheck" args="password"> + return password === "oldpw5"; + </script> + <table> + <tr> + <td><label for="ov5">Old Password:</label></td> + <td><input type="password" id="ov5" pwType="old" /></td> + </tr> + <tr> + <td><label for="nv5">Password:</label></td> + <td><input type="password" id="nv5" pwType="new" /></td> + </tr> + <tr> + <td><label for="vv5">Validate:</label></td> + <td><input type="password" id="vv5" pwType="verify" /></td> + </tr> + </table> + </div> + </form> + <hr> + <h4 class="testSubtitle">No old password, not required</h4> + <form dojoType="dijit.form.Form" jsId="form6"> + <div dojoType="dojox.form.PasswordValidator" required="false" jsId="valid6" name="password"> + <label>Password: <input type="password" id="nv6" pwType="new" /></label><br> + <label>Validate: <input type="password" id="vv6" pwType="verify" /></label><br> + </div> + </form> + <hr> + <button dojoType="dijit.form.Button"> + <script type="dojo/method" event="onClick"> + dojo.forEach([form1, form2, form3, form4, form5, form6], function(i){ + console.dir(i.getValues()); + }); + </script> + Get Values + </button> + <button dojoType="dijit.form.Button"> + <script type="dojo/method" event="onClick"> + valid5.setAttribute("disabled", !valid5.disabled); + </script> + Toggle Disabled + </button> + </body> +</html> |