/* * ***** BEGIN LICENSE BLOCK ***** * Version: ZAPL 1.1 * * The contents of this file are subject to the Zimbra AJAX Public * License Version 1.1 ("License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at * http://www.zimbra.com/license * * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See * the License for the specific language governing rights and limitations * under the License. * * The Original Code is: Zimbra AJAX Toolkit. * * The Initial Developer of the Original Code is Zimbra, Inc. * Portions created by Zimbra are Copyright (C) 2005 Zimbra, Inc. * All Rights Reserved. * * Contributor(s): * * ***** END LICENSE BLOCK ***** */ // // Factory to create XFormItems from simple attributes (eg: from JS object literals or XML) // /** This object is never instantiated. */ function XFormItemFactory() {} /** * Creates a form item. * * @param attributes An object whose properties map to component attribute * name/value pairs. * @param parentItem The parent item of this item. * @param xform The form to which this item is being created. */ XFormItemFactory.createItem = function (attributes, parentItem, xform) { // assign a modelItem to the item var refPath = this.getRefPath(attributes, parentItem); var modelItem; if (refPath != null) { // assign a modelItem to the item modelItem = this.getModelItem(xform.xmodel, attributes, refPath); } // get the class for that type and create one var type = this.getItemType(attributes, modelItem); var constructor = this.getItemTypeConstructor(type, xform); var item = new constructor(); item._setAttributes(attributes); // get a unique id for the item var idPrefix = ( attributes.id ? xform.getId() + "_" + attributes.id : refPath ? xform.getId() + "_" + refPath : item.__parentItem ? item.__parentItem.getId() : xform.getId() + "_" + item.type ); // assign a unique id to each item // (if the item specifies an id, we use a variant of that, just in case there's more than one) item.id = xform.getUniqueId(idPrefix); item.refPath = refPath; item.__modelItem = modelItem; item.__xform = xform; item.__parentItem = parentItem; // assign the item into our form's index so we can be found later xform.indexItem(item, item.id); // tell the item to initialize any special properties it needs to on construction item.initFormItem(); return item; } XFormItemFactory.getRefPath = function (attributes, parentItem) { if (attributes.refPath) return attributes.refPath; var ref = attributes.ref; if (ref == null) return null; if (parentItem) { var parentPath = parentItem.getRefPath(); if (parentPath == null) parentPath = ""; } else { var parentPath = ""; } var path = ref; if (ref == ".") { path = parentPath; } else if (ref == "..") { parentPath = parentPath.split("/"); path = parentPath.slice(0, parentPath.length - 1).join("/"); } else if (parentPath == "") { path = ref; } else { path = parentPath + "/" + ref; } return path; } XFormItemFactory.getModelItem = function (xmodel, attributes, refPath) { if (refPath == null || refPath == "") return null; return xmodel.getItem(refPath, true); } XFormItemFactory.getItemType = function (attributes, modelItem) { var type = attributes.type; if (type == null) { type = attributes.type = _OUTPUT_; } var modelType = (modelItem && modelItem.type ? modelItem.type : _STRING_); if (type == _INPUT_) { if (attributes.value !== _UNDEFINED_) { type = _CHECKBOX_; } else { switch (modelType) { case _STRING_: case _NUMBER_: type = _INPUT_; break; case _DATE_: case _DATETIME_: case _TIME_: type = modelType; break; default: type = _INPUT_; } } } else if (type == _SELECT_) { var appearance = attributes.appearance; if (appearance == _RADIO_) { type = _RADIO_; } else { type = _SELECT_; } } return type; } XFormItemFactory.typeConstructorMap = {}; XFormItemFactory.createItemType = function (typeConstant, typeName, constructor, superClassConstructor) { if (constructor == null) constructor = new Function(); if (typeof superClassConstructor == "string") superClassConstructor = this.getItemTypeConstructor(superClassConstructor); if (superClassConstructor == null) superClassConstructor = XFormItem; // initialize the constructor constructor.prototype = new superClassConstructor(); constructor.prototype.type = typeName; constructor.prototype.constructor = constructor; constructor.prototype.toString = new Function("return '[XFormItem:" + typeName + " ' + this.getId() + ']'"); constructor.toString = new Function("return '[Class XFormItem:" + typeName + "]'"); // put the item type into the typemap this.registerItemType(typeConstant, typeName, constructor); // return the prototype return constructor; } XFormItemFactory.registerItemType = function(typeConstant, typeName, constructor) { // assign the type constant to the window so everyone else can use it window[typeConstant] = typeName; this.typeConstructorMap[typeName] = constructor; } XFormItemFactory.defaultItemType = "output"; XFormItemFactory.getItemTypeConstructor = function (typeName, form) { var typeConstructorMap = (form && form.typeConstructorMap ? form.typeConstructorMap : this.typeConstructorMap); var typeConstructor = typeConstructorMap[typeName]; if (typeConstructor == null) { var defaultItemType = (form ? form.defaultItemType : this.defaultItemType); typeConstructorMap[defaultItemType]; } return typeConstructor; } XFormItemFactory.quickClone = function(object) { this.cloner.prototype = object; return new this.cloner(); } XFormItemFactory.cloner = function(){} XFormItemFactory.initItemDefaults = function(form, itemDefaults) { // create a clone of the XFormItemFactory typeConstructorMap for the form form.typeConstructorMap = this.quickClone(this.typeConstructorMap); if (itemDefaults == null) itemDefaults = form.itemDefaults; if (itemDefaults != null) { // for each type in itemDefaults for (var type in itemDefaults) { var originalConstructor = this.typeConstructorMap[type]; var defaults = itemDefaults[type]; if (originalConstructor == null) { type = window[type]; originalConstructor = this.typeConstructorMap[type]; } if (originalConstructor == null) { continue; } var newConstructor = form.typeConstructorMap[type] = new Function(); newConstructor.prototype = new originalConstructor(); // NOTE: reassigning the constructor here is technically correct, // but will result in (item.constructor == originalClass.constructor) not working... newConstructor.prototype.constructor = newConstructor; for (var prop in defaults) { newConstructor.prototype[prop] = defaults[prop]; } } } } // // Abstract Class XFormItem // // All other form item classes inherit from this. // function XFormItem() {} XFormItem.prototype.constructor = XFormItem; XFormItemFactory.registerItemType("_FORM_ITEM_", "form_item", XFormItem); XFormItem.ERROR_STATE_ERROR = 0; XFormItem.ERROR_STATE_VALID = 1; // // set base class defaults // XFormItem.prototype._isXFormItem = true; // outputting and inserting XFormItem.prototype.writeElementDiv = false; // appearance XFormItem.prototype.labelLocation = _LEFT_; XFormItem.prototype.tableCssClass = "xform_table"; // table that encloses one or more cells XFormItem.prototype.tableCssStyle = null; // table that encloses one or more cells XFormItem.prototype.containerCssClass = "xform_container"; // td that contains the element XFormItem.prototype.containerCssStyle = null; // td that contains the element XFormItem.prototype.cssClass = null; // element itself (or element div) XFormItem.prototype.labelCssClass = "xform_label"; // label td XFormItem.prototype.errorCssClass = "xform_error"; // error DIV XFormItem.prototype.nowrap = false; XFormItem.prototype.labelWrap = false; XFormItem.prototype.align = _UNDEFINED_; // _UNDEFINED_ because it's a bit faster to draw XFormItem.prototype.valign = _UNDEFINED_; // _UNDEFINED_ because it's a bit faster to draw XFormItem.prototype.focusable = false; // updating XFormItem.prototype.forceUpdate = false; // SET TO true TO FORCE AN ITEM TO UPDATE, EVEN IF VALUE HAS NOT CHANGED XFormItem.prototype.relevant; XFormItem.prototype.relevantIfEmpty = true; XFormItem.prototype.relevantBehavior = _HIDE_; // _HIDE_, _DISABLE_ // changing/saving XFormItem.prototype.elementChangeHandler = "onchange"; // choices map XFormItem.prototype.selection = _CLOSED_; XFormItem.prototype.openSelectionLabel = ""; // error handling XFormItem.prototype.errorLocation = _SELF_; // // Methods // // set the initializing attributes of this firm XFormItem.prototype._setAttributes = function (attributes) { this.__attributes = attributes; } // override this to do any item initialization you need to do // NOTE: this is called AFTER the formItem is initiaized with its modelItem, set in its form, etc XFormItem.prototype.initFormItem = function() { window.status = ''; } // DEFAULT IMPLEMENTATION calls this.getForm().initItemList() on our items array // SOME CLASSES MAY NOT WANT TO DO THIS (eg: _REPEAT_, which does this dynamically later) XFormItem.prototype.initializeItems = function () { var items = this.getItems(); if (items != null) { this.items = this.getForm().initItemList(items, this); } } // error handling /** * Sets the error message for this form item. * This will set the error for this item, or * useing the errorLocation, follow the chain up, * to set the error on the related item. * * @param message The message to display. This message should already * be localized. */ XFormItem.prototype.setError = function(message, childError) { var errLoc = this.getErrorLocation(); if (errLoc == _PARENT_ || errLoc == _INHERIT_){ this.getParentItem().setError(message, true); return; } this.getForm().addErrorItem(this); this.__errorState = XFormItem.ERROR_STATE_ERROR; var container = this.getErrorContainer(true); if (container) container.innerHTML = message; }; /** * Clears the error message for this form item. * This will clear the error for this item, or * useing the errorLocation, follow the chain up, * to clear the error on the related item. */ XFormItem.prototype.clearError = function() { var errLoc = this.getErrorLocation(); if (errLoc == _PARENT_ || errLoc == _INHERIT_){ this.getParentItem().clearError(); return; } this.getForm().removeErrorItem(this); this.__errorState = XFormItem.ERROR_STATE_VALID; this.removeErrorContainer(); }; XFormItem.prototype.hasError = function () { return (this.__errorState == XFormItem.ERROR_STATE_ERROR); }; XFormItem.prototype.getErrorContainer = function(createIfNecessary) { var container = this.getElement(this.getId() + "___error_container"); if (container != null) return container; if (createIfNecessary == true && this.getContainer()) { return this.createErrorContainer(); } return null; } XFormItem.prototype.createErrorContainer = function () { // output an error container var errorContainer = document.createElement("div"); errorContainer.id = this.getId() + "___error_container"; errorContainer.className = this.getErrorCssClass(); var container = this.getContainer(); if (container.hasChildNodes()) { container.insertBefore(errorContainer, container.firstChild); } else { container.appendChild(errorContainer); } return errorContainer; } XFormItem.prototype.removeErrorContainer = function () { var errorContainer = this.getErrorContainer(); if (errorContainer != null) { errorContainer.parentNode.removeChild(errorContainer); } } // // PROPERTIES OF INDIVIDUAL ITEMS // XFormItem.prototype.getType = function () { return this.type; } //XXX XFormItem.prototype.getParentItem = function () { return this.__parentItem; } XFormItem.prototype.getForm = function () { return this.__xform; } XFormItem.prototype.getGlobalRef = function() { return this.getForm().getGlobalRefString() + ".getItemById('" + this.getId() + "')"; } XFormItem.prototype.getFormGlobalRef = function() { return this.getForm().getGlobalRefString(); } XFormItem.prototype.getInstance = function() { return this.getForm().instance; } XFormItem.prototype.getModel = function () { return this.getForm().getModel(); } XFormItem.prototype.getFormController = function () { return this.getForm().getController(); } XFormItem.prototype.getModelItem = function() { return this.__modelItem; } //XXX NON-STANDARD XFormItem.prototype.getRef = function () { if (this.ref !== _UNDEFINED_) return this.ref; return this.__attributes.ref; } XFormItem.prototype.getRefPath = function () { return this.refPath; } XFormItem.prototype.getId = function () { return this.id; } XFormItem.prototype.getExternalId = function () { var ret = null; if (this.__attributes.id !== _UNDEFINED_) { ret = this.__attributes.id; } else if ( (ret = this.getRef()) !== _UNDEFINED_) { // nothing } else { ret = null; } return ret; }; // // GENERIC HTML WRITING ROUTINES // XFormItem.prototype.getOnChangeMethod = function() { return this.cacheInheritedMethod("onChange","$onChange","value,event,form"); } XFormItem.prototype.getOnActivateMethod = function() { return this.cacheInheritedMethod("onActivate","$onActivate","event"); } XFormItem.prototype.getExternalChangeHandler = function() { return "var item = " + this.getGlobalRef() + "; item.$elementChanged(value, item.getInstanceValue(), event||window.event);"; } XFormItem.prototype.getElementValueGetterHTML = function () { return "var value = this.value;"; } /** * returns the HTML part of an element that is used to set "onchange" * (or whatever is defined by elementChangehandler) property of the element * Greg Solovyev 07/19/05: moved JS creation part into XFormItem.prototype.getChangehandlerJSCode **/ XFormItem.prototype.getChangeHandlerHTML = function() { var elementChangeHandler = this.getElementChangeHandler(); if (elementChangeHandler != "onkeypress") { return AjxBuffer.concat(" ", elementChangeHandler, "=\"", this.getChangehandlerJSCode() + "\"",this.getKeyPressHandlerHTML()); } else { return this.getKeyPressHandlerHTML(); } } /** * returns JavaScript code that should be executed when an element is changed by a user * @author Greg Solovyev **/ XFormItem.prototype.getChangehandlerJSCode = function () { return AjxBuffer.concat(this.getElementValueGetterHTML(),this.getExternalChangeHandler()); } XFormItem.prototype.getFocusHandlerHTML = function () { var formId = this.getFormGlobalRef(), itemId = this.getId() ; return AjxBuffer.concat( " onfocus=\"", formId, ".onFocus('", itemId, "')\"", " onblur=\"", formId, ".onBlur('", itemId, "')\"" ); } XFormItem.prototype.getOnActivateHandlerHTML = function() { var method = this.getOnActivateMethod(); if (method == null) return ""; return AjxBuffer.concat( " ", this.getElementChangeHandler(), "=\"", this.getGlobalRef(),".$onActivate(event||window.event)\"" ); } /** * Schedules this.handleKeyPressDelay to fire later when the user finishes typing * @param ev - "onkeypress" event * @param domItem - HTML form element * @author Greg Solovyev **/ XFormItem.prototype.handleKeyUp = function (ev, domItem) { // don't fire off another if we've already set one up. if (this.keyPressDelayHdlr != null) { AjxTimedAction.cancelAction(this.keyPressDelayHdlr); XForm.keyPressDelayHdlr = null; } var form = this.getForm(); ev = ev ? ev : window.event; var key = DwtKeyEvent.getCharCode(ev); if (key == DwtKeyEvent.KEY_TAB) { DwtUiEvent.setBehaviour(ev, true, false); return false; } var action = new AjxTimedAction(); action.obj = this; action.method = this.handleKeyPressDelay; action.params.add(ev); action.params.add(domItem); //XForm.keyPressDelayHdlr = setTimeout(XForm.handleKeyPressDelay, 250, item, ev, formItem); this.keyPressDelayHdlr = AjxTimedAction.scheduleAction(action, 500); }; XFormItem.prototype.handleKeyDown = function (ev, domItem) { ev = (ev != null)? ev: window.event; var key = DwtKeyEvent.getCharCode(ev); if (key == DwtKeyEvent.KEY_ENTER) { // By telling the browser just to let this do the default, and // not let the event bubble, our keyup handler // wil see the enter key. DwtUiEvent.setBehaviour(ev, true, true); return false; } else if (key == DwtKeyEvent.KEY_TAB) { DwtUiEvent.setBehaviour(ev, true, false); this.getForm().focusNext(this.getId()); return false; } return true; }; /** * Implements delayed handling of "keypress" event. * Calls change handler script on the item. * See @link XFormItem.prototype.getChangehandlerJSCode for change handler script. * @author Greg Solovyev **/ XFormItem.prototype.handleKeyPressDelay = function(ev, domItem) { this.keyPressDelayHdlr = null; if (this.$changeHandlerFunc == null) { var JSCode = this.getChangehandlerJSCode(); this.$changeHandlerFunc = new Function("event", JSCode); } if(this.$changeHandlerFunc) { this.$changeHandlerFunc.call(domItem, ev); } }; XFormItem.prototype.getKeyPressHandlerHTML = function () { /** * Greg Solovyev 07/19/05 * added handler for onkeypress event in order to be able to update the form before the field looses focus **/ var keydownEv = "onkeydown"; if (AjxEnv.isNav) { keydownEv = "onkeypress"; } return AjxBuffer.concat(" ", keydownEv,"=\"",this.getGlobalRef(), ".handleKeyDown(event, this)\"", " onkeyup=\"", this.getGlobalRef(), ".handleKeyUp(event, this)\""); }; // // container // XFormItem.prototype.outputContainerTDStartHTML = function (html, updateScript, indent, colSpan, rowSpan) { html.append(indent, " 1 ? " colspan=" + colSpan : ""), (rowSpan > 1 ? " rowspan=" + rowSpan : ""), this.getContainerCssString(), ">\r" ); } XFormItem.prototype.outputContainerTDEndHTML = function (html, updateScript, indent) { html.append("\r", indent, " \r"); } // // element div // // for items that are effectively elements (or are drawn by something other than this form) // NOTE: you can pass in any random CSS properties you want in cssStyle XFormItem.prototype.outputElementDivStart = function (html, updateScript, indent) { html.append(indent, "
\r"); } XFormItem.prototype.outputElementDivEnd = function (html, updateScript, indent) { html.append("\r", indent, "
"); } // // label td // XFormItem.prototype.outputLabelCellHTML = function (html, updateScript, indent, rowSpan) { var label = this.getLabel(); if (label == null) return; if (label == "") label = " "; html.append(indent, " 1 ? " rowspan=" + rowSpan : ""), ">", "", label, ""); if(this.getInheritedProperty("required")) { html.append("*"); } html.append("\r"); } // // update script // XFormItem.prototype.outputUpdateScriptStart = function (html, updateScript, indent) { //TODO: take the script they want to place, do a regex look for the variables below and only include the ones they care about! var forceUpdate = this.getForceUpdate(); var relevant = this.getRelevant(); var relevantIfEmpty = this.getRelevantIfEmpty(); var parentRequiresRelevantCheck = (this.__parentItem ? (this.__parentItem._childRelevantCheckRequired == true) : false); if ( forceUpdate == false && this.refPath == null && relevant == null && relevantIfEmpty == true && parentRequiresRelevantCheck == false && typeof this.insertElement != "function" ) return; var updateElementMethod = this.getUpdateElementMethod(); var elementChangedMethod = this.getElementChangedMethod(); var getDisplayValueMethod = this.getDisplayValueMethod(); updateScript.append( // first line is to separate out each item "_____________________________________________________++;\r", "item = form.getItemById('", this.getId(),"', '", this.getRefPath(), "');\r" ); // if there is a relevant attribute, // get whether or not this item is relevant, and // write a script that will show or hide the container element // // NOTE: we leave the script dangling in the "if relevant" clause, // and close the if clause in writeUpdateScriptEnd(). // It is the job of each individual outputter to write script that will // update the value of the element (or subelements, etc) during the updateScript. // The can be assured that it will only be called when it is relevant, and // can access the following variables: // value = new value to show // element = DOM element of the 'control' itself (INPUT, SELECT, whatever a custom outputter gave us) // itemId = (often internally generated) ID for the control // ref = ref for the control (in the XForm, not the model) // container = DOM element of the DIV container of the control // if (relevant != null || relevantIfEmpty == false || parentRequiresRelevantCheck) { if (relevantIfEmpty == false) { if (relevant == null) { relevant = "get(item) != null"; } else { relevant = "get(item) != null && (" + relevant + ")"; } } if (parentRequiresRelevantCheck) { if (relevant == null) { relevant = "item.__parentItem.__isRelevant"; } else { relevant = "item.__parentItem.__isRelevant && (" + relevant + ")"; } } updateScript.append( "relevant = (", relevant, ");\r", "item.__isRelevant = (relevant == true);\r" ); var relevantBehavior = this.getRelevantBehavior(); if (relevantBehavior == _HIDE_) { this._endRelevantClause = true; updateScript.append( "if (!item.__isRelevant) {\r", "item.hide();\r", "} else {\r "); if(this.focusable) { updateScript.append( "DBG.println(AjxDebug.DBG1, \"Adding item ", this.getId(), " to the tabIdOrder \");\r", "item.getForm().tabIdOrder.push(item.getId());\r" ); } updateScript.append("item.show();\r"); } else if (relevantBehavior == _DISABLE_) { this._endRelevantClause = false; this._childRelevantCheckRequired = true; updateScript.append( "if (!item.__isRelevant) {\r", "item.disableElement();\r", "} else {\r "); if(this.focusable) { updateScript.append( "DBG.println(AjxDebug.DBG1, \"Adding item ", this.getId(), " to the tabIdOrder \");\r", "item.getForm().tabIdOrder.push(item.getId());\r" ); } updateScript.append( "item.enableElement();\r", "}\r"//, ); } } else { if(this.focusable) { updateScript.append( "DBG.println(AjxDebug.DBG1, \"Adding item ", this.getId(), " to the tabIdOrder \");\r", "item.getForm().tabIdOrder.push(item.getId());\r" ); } } // if the item should be inserted after drawing, do that now // (note: this means that hidden elements won't be inserted until they're relevant) if (typeof this.insertElement == "function") { updateScript.append("item.insertElement();\r"); } // if we should update the element, call that now. // NOTE: by default, we only update values that have changed since the last time // the form items was updated. To turn this off, set "forceUpdate:true" in a particular item. // if ((this.refPath || forceUpdate) && (updateElementMethod)) { updateScript.append( "if(!item.hasError()){\r", "value = ", (this.refPath ? "model.getInstanceValue(instance, item.refPath)" : "null" ), ";\r", (getDisplayValueMethod != null? "value = item.$getDisplayValue(value);\r" : "") ); if (forceUpdate != true) { updateScript.append( "var valueStr = ''+value;\r", "if (item.$lastDisplayValue != valueStr) {\r ", "item.$updateElement(value);\r", "item.$lastDisplayValue = valueStr;\r", "}\r" ); } else { updateScript.append( "item.$updateElement(value);\r" ); } updateScript.append("}\r"); } } XFormItem.prototype.outputUpdateScriptEnd = function (html, updateScript, indent) { if (this._endRelevantClause) { updateScript.append("\r}\r"); delete this._endRelevantClause; } } // // change handling // XFormItem.prototype.elementChanged = function(elementValue, instanceValue, event) { this.getForm().itemChanged(this.getId(), elementValue, event); } // // get and set instance values! // XFormItem.prototype.getInstanceValue = function (path) { if (path == null) path = this.getRefPath(); if (path == null) return null; return this.getModel().getInstanceValue(this.getInstance(), path); } //NOTE: model.getInstance() gets count of PARENT XFormItem.prototype.getInstanceCount = function () { if (this.getRefPath() == null) return 0; return this.getModel().getInstanceCount(this.getInstance(), this.getRefPath()); } XFormItem.prototype.setInstanceValue = function (value, path) { if (path == null) path = this.getRefPath(); if (path == null) return null; return this.getModel().setInstanceValue(this.getInstance(), path, value); } XFormItem.prototype.set = XFormItem.prototype.setInstancevalue; XFormItem.getValueFromHTMLSelect = function (element) { var values = []; for (var i = 0; i < element.options.length; i++) { if (element.options[i].selected) { values[values.length] = element.options[i].value; } } return values.join(","); } XFormItem.prototype.getValueFromHTMLSelect = function(element) { if (element == null) element = this.getElement(); return XFormItem.getValueFromHTMLSelect(element); } XFormItem.updateValueInHTMLSelect1 = function (newValue, element, selectionIsOpen) { if (element == null) return null; if (selectionIsOpen == null) selectionIsOpen = false; var options = element.options; for (i = 0; i < options.length; i++) { var choice = options[i]; if (choice.value == newValue) { element.selectedIndex = i; return element.value; } } // default to the first element if nothing was selected (?) if (options.length > 0) { element.selectedIndex = 0; return options[0].value; } return null; } XFormItem.prototype.updateValueInHTMLSelect1 = function (newValue, element, selectionIsOpen) { if (element == null) element = this.getElement(); if (selectionIsOpen == null) selectionIsOpen = this.getSelectionIsOpen(); return XFormItem.updateValueInHTMLSelect1(newValue, element, selectionIsOpen); } XFormItem.updateValueInHTMLSelect = function (newValue, element, selectionIsOpen) { if (element == null) return null; if (newValue == null) newValue = ""; if (selectionIsOpen == null) selectionIsOpen = false; // assumes newValue is a comma-delimited string or an array if (typeof newValue == "string") newValue = newValue.split(","); // hack up newValue to make searching for a particular option newValue easier var uniqueStartStr = "{|[", uniqueEndStr = "]|}" ; newValue = uniqueStartStr + newValue.join(uniqueEndStr + uniqueStartStr) + uniqueEndStr; var options = element.options; var anySelected = false; for (var i = 0; i < options.length; i++) { var isPresent = (newValue.indexOf(uniqueStartStr + options[i].value + uniqueEndStr) > -1); options[i].selected = isPresent; anySelected = anySelected || isPresent; } if (!anySelected && !selectionIsOpen) { // select the first value??? options[0].selected = true; } } XFormItem.prototype.updateValueInHTMLSelect = function (newValue, element, selectionIsOpen) { if (newValue == null) newValue = ""; if (element == null) element = this.getElement(); if (selectionIsOpen == null) selectionIsOpen = this.getSelectionIsOpen(); return XFormItem.updateValueInHTMLSelect(newValue, element, selectionIsOpen); } XFormItem.prototype.getChoicesHTML = function(indent) { var choices = this.getNormalizedChoices(); if (choices == null) return ""; //throw an error? var html = new AjxBuffer(); if (indent == null) indent = ""; this.outputChoicesHTMLStart(html, indent); var values = choices.values; var labels = choices.labels; var choiceCssClass = this.getChoiceCssClass(); for (var i = 0; i < values.length; i++) { html.append(indent, this.getChoiceHTML(i, values[i], labels[i], choiceCssClass, indent)); } this.outputChoicesHTMLEnd(html, indent); return html.toString(); } XFormItem.prototype.outputChoicesHTMLStart = function(html, indent) { return; } XFormItem.prototype.outputChoicesHTMLEnd = function(html, indent) { return; } XFormItem.prototype.getChoiceCssClass = function() { return ""; } XFormItem.prototype.getChoiceHTML = function (itemNum, value, label, cssClass, indent) { return AjxBuffer.concat(indent,""); } XFormItem.prototype.updateChoicesHTML = function () { this.cleanChoiceDisplay(); // NOTE: setting the innerHTML of the options doesn't work // for now, just set the outer HTML of the entire widget // TODO: do this by frobbing the options manually for speed and so things don't flash var html = new AjxBuffer(); var updateScript = new AjxBuffer(); // NOTE: we won't be using this... this.outputHTML(html, new AjxBuffer(), ""); this.getContainer().innerHTML = html.toString(); return; /* var element = this.getElement(); if (element != null) { var options = element.options; element.options.innerHTML = this.getChoicesHTML(); } */ } XFormItem.prototype.getInheritedProperty = function(prop) { // first look in the instance attributes if (this.__attributes[prop] !== _UNDEFINED_) return this.__attributes[prop]; // look up the inheritance chain for this type if (this[prop] !== _UNDEFINED_) return this[prop]; // if not found there, look in the xmodel var modelItem = this.__modelItem; if (modelItem && modelItem[prop]) return modelItem[prop]; return null; } // NOTE: cacheProp MUST be different than prop! XFormItem.prototype.cacheInheritedProperty = function (prop, cacheProp) { if (this[cacheProp] !== _UNDEFINED_) return this[cacheProp]; return (this[cacheProp] = this.getInheritedProperty(prop)); } XFormItem.prototype.cacheInheritedMethod = function (methodName, cacheProp, arguments) { if (this[cacheProp] !== _UNDEFINED_) return this[cacheProp]; var func = this.getInheritedProperty(methodName); if (func != null) func = this.convertToFunction(func, arguments); this[cacheProp] = func; return func; } // // properties of the element after its' been drawn // XFormItem.prototype.getElement = XForm.prototype.getElement; XFormItem.prototype.showElement = XForm.prototype.showElement; XFormItem.prototype.hideElement = XForm.prototype.hideElement; XFormItem.prototype.createElement = XForm.prototype.createElement; XFormItem.prototype.getWidget = function() { return this.widget; } XFormItem.prototype.setWidget = function(widget) { this.widget = widget; } XFormItem.prototype.getContainer = function() { return this.getElement(this.getId() + "___container"); } XFormItem.prototype.getLabelContainer = function() { return this.getElement(this.getId() + "___label"); } XFormItem.prototype.show = function() { var container = this.getLabelContainer(); if (container) this.showElement(container); container = this.getContainer(); if (container != null) { this.showElement(container); } else { var items = this.getItems(); if (items != null) { for (var i = 0; i < items.length; i++) { var item = items[i]; item.show(); } } } } XFormItem.prototype.hide = function() { var container = this.getLabelContainer() if (container) this.hideElement(container); container = this.getContainer(); if (container != null) { this.hideElement(container); } else { var items = this.getItems(); if (items != null) { for (var i = 0; i < items.length; i++) { items[i].hide(); } } } } XFormItem.prototype.focus = function () { this.getForm().focusElement(this.getId()); }; // // SIMPLE ATTRIBUTE ACCESSORS // // NOTE: this is effectively the public API for the properties you can define // for a FormItem // XFormItem.prototype.getValue = function() { return this.getInheritedProperty("value"); } // SPECIAL CASE: don't take ITEMS from the model... //XXX NON-STANDARD XFormItem.prototype.getItems = function () { if (this.items) return this.items; return this.__attributes.items; } XFormItem.prototype.getRelevant = function () { return this.cacheInheritedProperty("relevant","_relevant"); } XFormItem.prototype.getRelevantIfEmpty = function () { return this.getInheritedProperty("relevantIfEmpty"); } XFormItem.prototype.evalRelevant = function () { var relevant = this.getRelevant(); if (relevant == null) return true; var item = this; var form = this.getForm(); var model = this.getModel(); var instance = this.getForm().getInstance(); with (form) { return eval(relevant); } } XFormItem.prototype.getRelevantBehavior = function () { var behavior = this.getInheritedProperty("relevantBehavior"); if (behavior == _PARENT_) { if (this.__parentItem) { return this.__parentItem.getRelevantBehavior(); } else { return _HIDE_; } } return behavior; } XFormItem.prototype.getChoices = function () { return this.getInheritedProperty("choices"); } // normalized choices look like: {values:[v1, v2, v3...], labels:[l1, l2, l3...]} XFormItem.prototype.getNormalizedChoices = function () { if (this.$normalizedChoices) return this.$normalizedChoices; var choices = this.getChoices(); if (choices == null) return null; var normalizedChoices; if (typeof choices.getChoices == "function") { normalizedChoices = choices.getChoices(); } else if (AjxUtil.isArray(choices)) { // it's either an array of objects or an array of strings if (typeof choices[0] == "object") { // list of objects normalizedChoices = XFormChoices.normalizeChoices(choices, XFormChoices.OBJECT_LIST); } else { // list of simple values normalizedChoices = XFormChoices.normalizeChoices(choices, XFormChoices.SIMPLE_LIST); } } else { // assume it's a hash normalizedChoices = XFormChoices.normalizeChoices(choices, XFormChoices.HASH); } this.$normalizedChoices = normalizedChoices; return this.$normalizedChoices; } XFormItem.prototype.getNormalizedValues = function () { var choices = this.getNormalizedChoices(); if (choices) return choices.values; return null; } XFormItem.prototype.getNormalizedLabels = function () { var choices = this.getNormalizedChoices(); if (choices) return choices.labels; return null; } // // appearance methods // XFormItem.prototype.getAppearance = function () { return this.getInheritedProperty("appearance"); } XFormItem.prototype.getCssClass = function () { return this.getInheritedProperty("cssClass"); } XFormItem.prototype.getCssStyle = function () { return this.getInheritedProperty("cssStyle"); } XFormItem.prototype.getLabel = function (value) { return this.getInheritedProperty("label"); } XFormItem.prototype.getErrorCssClass = function () { return this.getInheritedProperty("errorCssClass"); } XFormItem.prototype.getLabelCssClass = function () { return this.getInheritedProperty("labelCssClass"); } XFormItem.prototype.getLabelCssStyle = function () { return this.getInheritedProperty("labelCssStyle"); } XFormItem.prototype.getLabelWrap = function () { return this.getInheritedProperty("labelWrap"); } XFormItem.prototype.getLabelLocation = function () { return this.getInheritedProperty("labelLocation"); } XFormItem.prototype.getContainerCssClass = function () { return this.getInheritedProperty("containerCssClass"); } XFormItem.prototype.getContainerCssStyle = function () { return this.getInheritedProperty("containerCssStyle"); } XFormItem.prototype.getTableCssClass = function () { return this.getInheritedProperty("tableCssClass"); } XFormItem.prototype.getTableCssStyle = function () { return this.getInheritedProperty("tableCssStyle"); } XFormItem.prototype.getNowrap = function () { return this.getInheritedProperty("nowrap"); } XFormItem.prototype.getWidth = function () { return this.cacheInheritedProperty("width","_width"); } XFormItem.prototype.getHeight = function () { return this.getInheritedProperty("height"); } XFormItem.prototype.getOverflow = function () { return this.getInheritedProperty("overflow"); } XFormItem.prototype.getNumCols = function () { return this.getInheritedProperty("numCols"); } XFormItem.prototype.getAlign = function () { return this.getInheritedProperty("align"); } XFormItem.prototype.getValign = function() { return this.getInheritedProperty("valign"); } // NEW TABLE LAYOUT STUFF XFormItem.prototype.useParentTable = true; XFormItem.prototype.getUseParentTable = function () { return this.getInheritedProperty("useParentTable"); } XFormItem.prototype.colSizes = _UNDEFINED_; XFormItem.prototype.getColSizes = function () { return this.getInheritedProperty("colSizes"); } XFormItem.prototype.colSpan = 1; XFormItem.prototype.getColSpan = function () { return this.getInheritedProperty("colSpan"); } XFormItem.prototype.rowSpan = 1; XFormItem.prototype.getRowSpan = function () { return this.getInheritedProperty("rowSpan"); } // END NEW TABLE LAYOUT STUFF // error handling XFormItem.prototype.getErrorLocation = function () { return this.getInheritedProperty("errorLocation"); }; // // convenience methods to figure out drawing types for you // // return the "label" in the choices array for this item // (allows us to do lookup of displayed values easily) XFormItem.prototype.getChoiceLabel = function (value) { var choices = this.getNormalizedChoices(); if (choices == null) return value; // choices will look like: {values:[v1, v2, v3...], labels:[l1, l2, l3...]} var values = choices.values; for (var i = 0; i < values.length; i++) { if (values[i] == value) { return choices.labels[i]; } } // if we didn't find it, simply return the original value return value; } // return the number of the choice for a particular value // returns -1 if not found XFormItem.prototype.getChoiceNum = function (value) { var choices = this.getNormalizedChoices(); if (choices == null) return -1; // choices will look like: {values:[v1, v2, v3...], labels:[l1, l2, l3...]} var values = choices.values; for (var i = 0; i < values.length; i++) { if (values[i] == value) { return i; } } return -1 } XFormItem.prototype.getCssString = function () { var css = (this.getCssClass() || ''); if (css != '' && css != null) css = " class=\"" + css + "\""; var style = (this.getCssStyle() || ''); var width = this.getWidth(); if (width != null && width != "auto") style += ";width:" + width; var height = this.getHeight(); if (height != null) style += ";height:" + height; var overflow = this.getOverflow(); if (overflow != null) style += ";overflow:" + overflow; if (this.getNowrap()) style += ";white-space:nowrap;"; var valign = this.getValign(); if (valign) style += "vertical-align:"+valign; if (style != '') css += " style=\"" + style + ";\""; return css; } XFormItem.prototype.getLabelCssString = function () { var css = (this.getLabelCssClass() || ''); if (css != '' && css != null) css = " class=\"" + css + "\""; var style = (this.getLabelCssStyle() || ''); if (this.getLabelWrap() == false) { style += ";white-space:nowrap"; } if (style != '') css += " style=\"" + style + ";\""; return css; } XFormItem.prototype.getTableCssString = function () { var css = (this.getTableCssClass() || ''); if (css != '' && css != null) css = " class=\"" + css + "\""; var style = this.getTableCssStyle(); if (style == null) style = ''; var colSizes = this.getColSizes(); if (colSizes != null) { style += ";table-layout:fixed"; } var width = this.getWidth(); if (width != null) style += ";width:"+ width; // var height = this.getHeight(); // if (height != null) style += ";height:"+ height; var overflow = this.getOverflow(); if (overflow != null) style += ";overflow:" + overflow; return css + (style != null ? " style=\"" + style + ";\"" : ""); } XFormItem.prototype.getContainerCssString = function () { var css = (this.getContainerCssClass() || ''); if (css != '' && css != null) css = " class=\"" + css + "\""; var style = this.getContainerCssStyle(); if (style == null) style = ''; var align = this.getAlign(); if (align != _LEFT_) { if (align == _CENTER_ || align == _MIDDLE_) { style += ";text-align:center"; } else if (align == _RIGHT_) { style += ";text-align:right"; } } var valign = this.getValign(); if (valign == _TOP_) { style += ";vertical-align:top"; } else if (valign == _BOTTOM_) { style += ";vertical-align:bottom"; } else if (valign == _CENTER_ || valign == _MIDDLE_) { style += ";vertical-align:middle"; } var relevant = this.getRelevant(); if (relevant) { var relevantBehavior = this.getRelevantBehavior(); if (relevantBehavior == _HIDE_) { style += ";display:none"; } } if (style != "") css += " style=\"" + style + ";\""; return css; } // // handling changes to items // XFormItem.prototype.getElementChangeHandler = function () { return this.getInheritedProperty("elementChangeHandler"); } // // outputting, inserting and updating items // XFormItem.prototype.getForceUpdate = function() { return this.getInheritedProperty("forceUpdate"); } XFormItem.prototype.getOutputHTMLMethod = function() { return this.convertToFunction( this.getInheritedProperty("outputHTML"), "html,updateScript,indent,currentCol" ); } XFormItem.prototype.getElementChangedMethod = function () { return this.cacheInheritedMethod("elementChanged","$elementChanged","elementValue, instanceValue, event"); } XFormItem.prototype.getUpdateElementMethod = function() { return this.cacheInheritedMethod("updateElement","$updateElement","newValue"); } XFormItem.prototype.getDisplayValueMethod = function() { return this.cacheInheritedMethod("getDisplayValue","$getDisplayValue","newValue"); } XFormItem.prototype.convertToFunction = function (script, arguments) { if ((script == null) || (typeof(script) == "function")) return script; if (typeof(this[script]) == "function") return this[script]; // CLOSURE??? return new Function(arguments, script); } // note that this form item's display needs to be updated XFormItem.prototype.dirtyDisplay = function () { delete this.$lastDisplayValue; } // override the next method in your subclass to enable/disable element XFormItem.prototype.setElementEnabled = function(enable) {} // convenience methods that call the above routine XFormItem.prototype.disableElement = function () { this.setElementEnabled(false); } XFormItem.prototype.enableElement = function () { this.setElementEnabled(true); } // you can use these to XFormItem.prototype.setElementDisabledProperty = function (enable) { this.getElement().disabled = (enable != true) } XFormItem.prototype.setElementEnabledCssClass = function (enable) { var el = this.getElement(); if (!el) return; if (enable) { el.className = this.getCssClass(); } else { el.className = this.getCssClass() + "_disabled"; } } // // _SELECT_ etc type properties // XFormItem.prototype.getSelection = function () { return this.getInheritedProperty("selection"); } XFormItem.prototype.getSelectionIsOpen = function () { return this.getInheritedProperty("selection"); } XFormItem.prototype.getOpenSelectionLabel = function () { return this.getInheritedProperty("openSelectionLabel"); } // // _REPEAT_ type properties // XFormItem.prototype.getNumberToShow = function () { return this.getInheritedProperty("number"); } XFormItem.prototype.getShowAddButton = function () { return this.getInheritedProperty("showAddButton"); } XFormItem.prototype.getShowRemoveButton = function () { return this.getInheritedProperty("showRemoveButton"); } XFormItem.prototype.getShowMoveUpButton = function () { return this.getInheritedProperty("showMoveUpButton"); } XFormItem.prototype.getShowMoveDownButton = function () { return this.getInheritedProperty("showMoveDownButton"); } XFormItem.prototype.getAddButton = function () { return this.getInheritedProperty("addButton"); } XFormItem.prototype.getRemoveButton = function () { return this.getInheritedProperty("removeButton"); } XFormItem.prototype.getMoveUpButton = function () { return this.getInheritedProperty("moveUpButton"); } XFormItem.prototype.getMoveDownButton = function () { return this.getInheritedProperty("moveDownButton"); } XFormItem.prototype.getAlwaysShowAddButton = function () { return this.getInheritedProperty("alwaysShowAddButton"); } XFormItem.prototype.getRepeatInstance = function () { return this.getInheritedProperty("repeatInstance"); } // // _IMAGE_ type properties // XFormItem.prototype.getSrc = function () { return this.getInheritedProperty("src"); } XFormItem.prototype.getSrcPath = function () { return this.getInheritedProperty("srcPath"); } // // _ANCHOR_, _URL_, etc // // type defaults XFormItem.prototype.getShowInNewWindow = function () { return this.getInheritedProperty("showInNewWindow"); } // // internal properties for creating various item types // XFormItem.prototype.getWriteElementDiv = function () { return this.getInheritedProperty("writeElementDiv"); } XFormItem.prototype.getMultiple = function () { return this.getInheritedProperty("multiple"); } XFormItem.prototype.getAlwaysUpdateChoices = function () { return this.getInheritedProperty("alwaysUpdateChoices"); } XFormItem.prototype.choicesAreDirty = function () { return (this._choiceDisplayIsDirty == true || this.getAlwaysUpdateChoices()); } // // XFormItem class: "output" // function Output_XFormItem() {} XFormItemFactory.createItemType("_OUTPUT_", "output", Output_XFormItem, XFormItem); // type defaults Output_XFormItem.prototype.writeElementDiv = true; Output_XFormItem.prototype.cssClass = "xform_output"; // element itself (or element div) // methods Output_XFormItem.prototype.outputHTML = function (html, updateScript, indent) { // by defaut, we output the "attributes.value" if set // (in case an item only wants to write out on the initial draw) // NOTE: dereferencing through the choice map happens in getDisplayValue() var value = this.getValue(); var method = this.getDisplayValueMethod(); if (method) { value = method.call(this, value); } html.append(value); } Output_XFormItem.prototype.getDisplayValue = function(newValue) { // dereference through the choices array, if provided newValue = this.getChoiceLabel(newValue); if (newValue == null) { newValue = ""; } else { newValue = "" + newValue; } return newValue; } Output_XFormItem.prototype.updateElement = function (newValue) { this.getElement().innerHTML = newValue; } // set up how disabling works for this item type Output_XFormItem.prototype.setElementEnabled = XFormItem.prototype.setElementEnabledCssClass; // // XFormItem class: "textfield" // function Textfield_XFormItem() {} XFormItemFactory.createItemType("_TEXTFIELD_", "textfield", Textfield_XFormItem, XFormItem); // aliases for _TEXTFIELD_: _INPUT_ XFormItemFactory.registerItemType("_INPUT_", "input", Textfield_XFormItem); // type defaults Textfield_XFormItem.prototype.width = 100; Textfield_XFormItem.prototype._inputType = "text"; Textfield_XFormItem.prototype.cssClass = "xform_field"; Textfield_XFormItem.prototype.elementChangeHandler="onkeypress"; Textfield_XFormItem.prototype.focusable = true; // methods Textfield_XFormItem.prototype.outputHTML = function (html, updateScript, indent, currentCol) { var inputType = this._inputType; var value = this.getValue(); var modelItem = this.getModelItem(); /*** //XXX this is probably not the best way to tell if we only want to enter numbers... if (modelItem && (modelItem.type == _NUMBER_)) {// || modelItem.type == _COS_NUMBER_)) { var keyStrokeHandler = " onkeypress=\"" // +"',45,46,48,49,50,51,52,53,54,55,56,57,69,101,'.indexOf(','+(event||window.event).keyCode+',') > -1\"" +"var code = ','+(event||window.event).which+',';" +"var isValidChar = (',45,46,48,49,50,51,52,53,54,55,56,57,69,101,'.indexOf(code) > -1);" +"DBG.println(code + ':'+isValidChar);" +"event.returnValue = isValidChar;" +"return isValidChar;" +"\"" } /***/ html.append(indent, ""); } Textfield_XFormItem.prototype.updateElement = function(newValue) { if (newValue == null) newValue = this.getValue(); if (newValue == null) newValue = ""; if (this.getElement().value != newValue) { this.getElement().value = newValue; } } // set up how disabling works for this item type Textfield_XFormItem.prototype.setElementEnabled = XFormItem.prototype.setElementDisabledProperty; // // XFormItem class: "secret" // function Secret_XFormItem() {} XFormItemFactory.createItemType("_SECRET_", "secret", Secret_XFormItem, Textfield_XFormItem); // alias for the SECRET class: PASSWORD XFormItemFactory.registerItemType("_PASSWORD_", "password", Secret_XFormItem); // type defaults Secret_XFormItem.prototype._inputType = "password"; Secret_XFormItem.prototype.focusable = true; // // XFormItem class: "file" // function File_XFormItem() {} XFormItemFactory.createItemType("_FILE_", "file", File_XFormItem, Textfield_XFormItem) // type defaults File_XFormItem.prototype._inputType = "file"; File_XFormItem.prototype.forceUpdate = false; File_XFormItem.prototype.focusable = true; // // XFormItem class: "textarea" // function Textarea_XFormItem() {} XFormItemFactory.createItemType("_TEXTAREA_", "textarea", Textarea_XFormItem, Textfield_XFormItem) Textarea_XFormItem.prototype.width = "100%"; Textarea_XFormItem.prototype.height = 100; Textarea_XFormItem.prototype.focusable = true; // methods Textarea_XFormItem.prototype.outputHTML = function (html, updateScript, indent, currentCol) { var wrap = this.getInheritedProperty("textWrapping"); if(!wrap) wrap = "off"; html.append(indent, ""); } // // XFormItem class: "checkbox" // function Checkbox_XFormItem() {} XFormItemFactory.createItemType("_CHECKBOX_", "checkbox", Checkbox_XFormItem, XFormItem) // type defaults Checkbox_XFormItem.prototype._inputType = "checkbox"; Checkbox_XFormItem.prototype.elementChangeHandler = "onclick"; Checkbox_XFormItem.prototype.labelLocation = _RIGHT_; Checkbox_XFormItem.prototype.cssClass = "xform_checkbox"; Checkbox_XFormItem.prototype.labelCssClass = "xform_checkbox"; Checkbox_XFormItem.prototype.align = _RIGHT_; Checkbox_XFormItem.prototype.trueValue = _UNDEFINED_; // Don't set in proto so model can override Checkbox_XFormItem.prototype.falseValue = _UNDEFINED_; Checkbox_XFormItem.prototype.focusable = true; // methods Checkbox_XFormItem.prototype.outputHTML = function (html, updateScript, indent, currentCol) { // figure out how to show the checkbox as checked or not var checked = ""; if (this.getInstanceValue() == this.getTrueValue()) { checked = " CHECKED"; } html.append(indent, ""); } Checkbox_XFormItem.prototype.getTrueValue = function () { var trueValue = this.getInheritedProperty("trueValue"); if (trueValue == null) trueValue = true; return trueValue; } Checkbox_XFormItem.prototype.getFalseValue = function () { var falseValue = this.getInheritedProperty("falseValue"); if (falseValue == null) falseValue = false; return falseValue; } Checkbox_XFormItem.prototype.updateElement = function(newValue) { newValue = (newValue == this.getTrueValue()); this.getElement().checked = newValue; } Checkbox_XFormItem.prototype.getElementValueGetterHTML = function () { var trueValue = this.getTrueValue(); if (trueValue !== _UNDEFINED_) { if (typeof trueValue == "string") trueValue = "'" + trueValue + "'"; var falseValue = this.getFalseValue(); if (typeof falseValue == "string") falseValue = "'" + falseValue + "'"; if (trueValue == null) trueValue = true; if (falseValue == null) falseValue = false; return AjxBuffer.concat( "var value = (this.checked ? ", trueValue, " : ", falseValue, ");" ); } else { return "var value = '"+this.getValue()+"';"; } } // set up how disabling works for this item type // XXXX eventually we want to disable our label as well... Checkbox_XFormItem.prototype.setElementEnabled = XFormItem.prototype.setElementDisabledProperty; // // XFormItem class: "radiobutton" // function Radio_XFormItem() {} XFormItemFactory.createItemType("_RADIO_", "radio", Radio_XFormItem, Checkbox_XFormItem) // type defaults Radio_XFormItem.prototype._inputType = "radio"; Radio_XFormItem.prototype.focusable = true; // methods Radio_XFormItem.prototype.updateElement = function(newValue) { this.getElement().checked = (this.getValue() == newValue); } Radio_XFormItem.prototype.getElementValueGetterHTML = function () { return "var value = '"+this.getValue()+"';"; } // // XFormItem class: "button" // function Button_XFormItem() {} XFormItemFactory.createItemType("_BUTTON_", "button", Button_XFormItem, XFormItem); XFormItemFactory.registerItemType("_TRIGGER_", "trigger", Button_XFormItem); // type defaults Button_XFormItem.prototype.forceUpdate = false; Button_XFormItem.prototype.elementChangeHandler = "onclick"; Button_XFormItem.prototype.labelLocation = _NONE_; Button_XFormItem.prototype.relevantBehavior = _DISABLE_; Button_XFormItem.prototype.cssClass = "xform_button"; Button_XFormItem.prototype.focusable = true; // methods Button_XFormItem.prototype.outputHTML = function (html, updateScript, indent, currentCol) { // write the div to hold the value (will be filled in on update) html.append(indent, ""); } // set up how disabling works for this item type Button_XFormItem.prototype.setElementEnabled = XFormItem.prototype.setElementDisabledProperty; // // XFormItem class: "submit" // function Submit_XFormItem() {} XFormItemFactory.createItemType("_SUBMIT_", "submit", Submit_XFormItem, Button_XFormItem) // methods Submit_XFormItem.prototype.outputHTML = function (html, updateScript, indent, currentCol) { // write the div to hold the value (will be filled in on update) html.append( "" ); } // // XFormItem class: "anchor" // function Anchor_XFormItem() {} XFormItemFactory.createItemType("_ANCHOR_", "anchor", Anchor_XFormItem, XFormItem) // type defaults Anchor_XFormItem.prototype.writeElementDiv = true; Anchor_XFormItem.prototype.forceUpdate = true; Anchor_XFormItem.prototype.cssClass = "xform_anchor"; Anchor_XFormItem.prototype.elementChangeHandler = "onclick"; Anchor_XFormItem.prototype.href = "javascript:;"; Anchor_XFormItem.prototype.showInNewWindow = true; Anchor_XFormItem.prototype.focusable = true; Anchor_XFormItem.prototype.getHref = function () { return this.getInheritedProperty("href"); } // type defaults Anchor_XFormItem.prototype.getAnchorTag = function(href, label) { if (href == null) href = this.getHref(); if (label == null) label = this.getLabel(); var inNewWindow = this.getShowInNewWindow(); return AjxBuffer.concat( '', label, ''); } // methods Anchor_XFormItem.prototype.outputHTML = function (html) { html.append(this.getAnchorTag()); } Anchor_XFormItem.prototype.updateElement = function (value) { this.getElement().innerHTML = this.getAnchorTag(value); } // set up how disabling works for this item type Anchor_XFormItem.prototype.setElementEnabled = XFormItem.prototype.setElementEnabledCssClass; // // Data anchor -- label is data driven // function Data_Anchor_XFormItem() {} XFormItemFactory.createItemType("_DATA_ANCHOR_", "data_anchor", Data_Anchor_XFormItem, Anchor_XFormItem) Data_Anchor_XFormItem.prototype.updateElement = function (value) { this.getElement().innerHTML = this.getAnchorTag(null, value); } // // XFormItem class: "url" // function Url_XFormItem() {} XFormItemFactory.createItemType("_URL_", "url", Url_XFormItem, Anchor_XFormItem) Url_XFormItem.prototype.updateElement = function (value) { this.getElement().innerHTML = this.getAnchorTag(value, value); } // // XFormItem class: "mailto" // function Mailto_XFormItem() {} XFormItemFactory.createItemType("_MAILTO_", "mailto", Mailto_XFormItem, Anchor_XFormItem) Mailto_XFormItem.prototype.updateElement = function (value) { this.getElement().innerHTML = this.getAnchorTag("mailto:"+value, value); } // // XFormItem class: "image" // function Image_XFormItem() {} XFormItemFactory.createItemType("_IMAGE_", "image", Image_XFormItem, XFormItem) // type defaults Image_XFormItem.prototype.forceUpdate = true; Image_XFormItem.prototype.src = _UNDEFINED_; Image_XFormItem.prototype.srcPath = _UNDEFINED_;; Image_XFormItem.prototype.writeElementDiv = true; // methods Image_XFormItem.prototype.updateElement = function (src) { if (src == null) src = this.getSrc(); // dereference through the choices array, if provided src = this.getChoiceLabel(src); // if we didn't get an image name, output nothing (?) if (src == null || src == "") { var output = ""; } else { // prepend the image path var path = this.getSrcPath(); if (path != null) src = path + src; var output = AjxBuffer.concat( "" ); } this.getElement().innerHTML = output; } // set up how disabling works for this item type Image_XFormItem.prototype.setElementEnabled = XFormItem.prototype.setElementEnabledCssClass; // Ajx_Image function Ajx_Image_XFormItem() {} XFormItemFactory.createItemType("_AJX_IMAGE_", "ajx_image", Ajx_Image_XFormItem, XFormItem); // type defaults Ajx_Image_XFormItem.prototype.forceUpdate = true; Ajx_Image_XFormItem.prototype.src = _UNDEFINED_; Ajx_Image_XFormItem.prototype.srcPath = _UNDEFINED_;; Ajx_Image_XFormItem.prototype.writeElementDiv = false; // // methods Ajx_Image_XFormItem.prototype.updateElement = function (src) { if (src == null) src = this.getSrc(); // dereference through the choices array, if provided src = this.getChoiceLabel(src); // if we didn't get an image name, output nothing (?) if (src == null || src == "") { var output = ""; } else { // prepend the image path var path = this.getSrcPath(); if (path != null) src = path + src; var output = AjxImg.getImageHtml(src, "position:relative;") } this.getContainer().innerHTML = output; }; // // XFormItem class: "select1" // function Select1_XFormItem() {} XFormItemFactory.createItemType("_SELECT1_", "select1", Select1_XFormItem, XFormItem) // type defaults Select1_XFormItem.prototype.multiple = false; Select1_XFormItem.prototype.alwaysUpdateChoices = false; Select1_XFormItem.prototype.focusable = true; // methods Select1_XFormItem.prototype.initFormItem = function () { // if we're dealing with an XFormChoices object... var choices = this.getChoices(); if (choices == null || choices.constructor != XFormChoices) return; // ...set up to receive notification when its choices change var listener = new AjxListener(this, this.dirtyDisplay); choices.addListener(DwtEvent.XFORMS_CHOICES_CHANGED, listener); } Select1_XFormItem.prototype.outputHTML = function (html, updateScript, indent, currentCol) { html.append(indent, "" ); this.cleanChoiceDisplay(); } Select1_XFormItem.prototype.getElementValueGetterHTML = function () { return "var value = XFormItem.getValueFromHTMLSelect(this);"; } Select1_XFormItem.prototype.setChoices = function(newChoices) { this.choices = newChoices; this.dirtyDisplay(); this.updateChoicesHTML(); } Select1_XFormItem.prototype.dirtyDisplay = function () { XFormItem.prototype.dirtyDisplay.call(this); this._choiceDisplayIsDirty = true; delete this.$normalizedChoices; } Select1_XFormItem.prototype.cleanChoiceDisplay = function () { this._choiceDisplayIsDirty = false; } Select1_XFormItem.prototype.updateElement = function (newValue) { if (this.choicesAreDirty()) this.updateChoicesHTML(); this.updateValueInHTMLSelect1(newValue, this.getElement(), this.getSelectionIsOpen()); } // set up how disabling works for this item type Select1_XFormItem.prototype.setElementEnabled = XFormItem.prototype.setElementDisabledProperty; // // XFormItem class: "select" // function Select_XFormItem() {} XFormItemFactory.createItemType("_SELECT_", "select", Select_XFormItem, Select1_XFormItem) // type defaults Select_XFormItem.prototype.multiple = true; Select_XFormItem.prototype.selection = _OPEN_; Select_XFormItem.prototype.focusable = true; // methods Select_XFormItem.prototype.updateElement = function (newValue) { if (this.choicesAreDirty()) this.updateChoicesHTML(); this.updateValueInHTMLSelect(newValue, this.getElement(), this.getSelectionIsOpen()); } // // XFormItem class: "spacer" // // Use to output an entire row spacer // function Spacer_XFormItem() {} XFormItemFactory.createItemType("_SPACER_", "spacer", Spacer_XFormItem, XFormItem) // type defaults Spacer_XFormItem.prototype.forceUpdate = false; Spacer_XFormItem.prototype.labelLocation = _NONE_; Spacer_XFormItem.prototype.width = 1; Spacer_XFormItem.prototype.height = 10; Spacer_XFormItem.prototype.cssStyle = "font-size:1px;overflow:hidden;"; Spacer_XFormItem.prototype.colSpan = "*"; Spacer_XFormItem.prototype.focusable = false; // methods Spacer_XFormItem.prototype.outputHTML = function (html, updateScript, indent, currentCol) { html.append(indent, "
"); } // set up how disabling works for this item type Spacer_XFormItem.prototype.setElementEnabled = XFormItem.prototype.setElementEnabledCssClass; // // XFormItem class: "cell_spacer" // // Use to output a single cell of space // function Cell_Spacer_XFormItem() {} XFormItemFactory.createItemType("_CELL_SPACER_", "cell_spacer", Cell_Spacer_XFormItem, Spacer_XFormItem) XFormItemFactory.registerItemType("_CELLSPACER_", "cell_spacer", Cell_Spacer_XFormItem); Cell_Spacer_XFormItem.prototype.width = 10; Cell_Spacer_XFormItem.prototype.height = 10; Cell_Spacer_XFormItem.prototype.colSpan = 1; Cell_Spacer_XFormItem.prototype.focusable = false; // // XFormItem class: "separator" // function Separator_XFormItem() {} XFormItemFactory.createItemType("_SEPARATOR_", "separator", Separator_XFormItem, XFormItem) // type defaults Separator_XFormItem.prototype.cssClass = "xform_separator"; Separator_XFormItem.prototype.colSpan = "*"; Separator_XFormItem.prototype.align = _CENTER_; Separator_XFormItem.prototype.valign = _CENTER_; Separator_XFormItem.prototype.height = 10; Separator_XFormItem.prototype.focusable = false; // methods Separator_XFormItem.prototype.outputHTML = function (html, updateScript, indent, currentCol) { var css = (this.getCssClass() || ''); if (css != '' && css != null) css = " class=\"" + css + "\""; html.append(indent, "", "
", "
", "
" ); } // set up how disabling works for this item type Separator_XFormItem.prototype.setElementEnabled = XFormItem.prototype.setElementEnabledCssClass; // // XFormItem class: "group" // function Group_XFormItem() {} XFormItemFactory.createItemType("_GROUP_", "group", Group_XFormItem, XFormItem) // type defaults Group_XFormItem.prototype.forceUpdate = false; Group_XFormItem.prototype.numCols = 2; Group_XFormItem.prototype.useParentTable = false; Group_XFormItem.prototype.focusable = false; Group_XFormItem.prototype.outputHTML = function (html, updateScript, indent, currentCol) { this.getForm().outputItemList(this.getItems(), this, html, updateScript, indent, this.getNumCols(), currentCol); } // nothing to do on group update -- each item will take care of it itself //group_XFormItem.prototype.updateElement = function (newValue) {} // // XFormItem class: "_BORDER_" // // NOTE: dependent on the file DwtBorder.js // function Border_XFormItem() {} XFormItemFactory.createItemType("_BORDER_", "border", Border_XFormItem, Group_XFormItem) // type defaults Border_XFormItem.prototype.forceUpdate = false; Border_XFormItem.prototype.colSpan = "*"; Border_XFormItem.prototype.numCols = 2; Border_XFormItem.prototype.useParentTable = false; Border_XFormItem.prototype.borderStyle = "card"; Border_XFormItem.prototype.focusable = false; Border_XFormItem.prototype.getBorderStyle = function () { return this.getInheritedProperty("borderStyle"); } Border_XFormItem.prototype.getSubstitutions = function () { return this.getInheritedProperty("substitutions"); } Border_XFormItem.prototype.getBorderWidth = function () { return DwtBorder.getBorderWidth(this.getBorderStyle()); } Border_XFormItem.prototype.getBorderHeight = function () { return DwtBorder.getBorderHeight(this.getBorderStyle()); } Border_XFormItem.prototype.outputHTMLStart = function (html, updateScript, indent, currentCol) { var style = this.getBorderStyle(); var substitutions = this.getSubstitutions(); html.append(DwtBorder.getBorderStartHtml(style, substitutions)); } Border_XFormItem.prototype.outputHTMLEnd = function (html, updateScript, indent, currentCol) { var style = this.getBorderStyle(); var substitutions = this.getSubstitutions(); html.append(DwtBorder.getBorderEndHtml(style, substitutions)); } // // XFormItem class: "case" // function Case_XFormItem() {} XFormItemFactory.createItemType("_CASE_", "case", Case_XFormItem, Group_XFormItem) // type defaults Case_XFormItem.prototype.labelLocation = _NONE_; Case_XFormItem.prototype.width = "100%"; Case_XFormItem.prototype.focusable = false; // // XFormItem class: "switch" // function Switch_XFormItem() {} XFormItemFactory.createItemType("_SWITCH_", "switch", Switch_XFormItem, Group_XFormItem) // type defaults Switch_XFormItem.prototype.labelLocation = _NONE_; Switch_XFormItem.prototype.colSpan = "*"; Switch_XFormItem.prototype.width = "100%"; Switch_XFormItem.prototype.numCols = 1; // // XFormItem class: "repeat" // function Repeat_XFormItem() {} XFormItemFactory.createItemType("_REPEAT_", "repeat", Repeat_XFormItem, Group_XFormItem) // type defaults Repeat_XFormItem.prototype.useParentTable = false; Repeat_XFormItem.prototype.writeElementDiv = true; Repeat_XFormItem.prototype.numCols = 1; Repeat_XFormItem.prototype.number = 1; Repeat_XFormItem.prototype.showRemoveButton = true; Repeat_XFormItem.prototype.showAddButton = true; Repeat_XFormItem.prototype.alwaysShowAddButton = false; Repeat_XFormItem.prototype.showMoveUpButton = false; Repeat_XFormItem.prototype.showMoveDownButton = false; Repeat_XFormItem.prototype.removeButton = { type:_BUTTON_, label: DwtMsg.xformRepeatRemove, //width:20, cssStyle:"margin-left:20px;", onActivate:function (event) { var repeatItem = this.getParentItem().getParentItem(); repeatItem.removeRowButtonClicked(this.getParentItem().instanceNum); }, relevantBehavior:_HIDE_, relevant: "item.__parentItem.getInstanceCount() != 0" }, Repeat_XFormItem.prototype.addButton = { ref:".", type:_BUTTON_, label: DwtMsg.xformRepeatAdd, //width:20, onActivate:function (event) { var repeatItem = this.getParentItem().getParentItem(); repeatItem.addRowButtonClicked(this.getParentItem().instanceNum); }, relevantBehavior:_HIDE_, forceUpdate:true } Repeat_XFormItem.prototype.moveUpButton = { type:_BUTTON_, label:"^", width:20, cssStyle:"margin-left:20px;", onActivate:function (event) { var repeatItem = this.getParentItem().getParentItem(); repeatItem.moveUpButtonClicked(this.getParentItem().instanceNum); } }, Repeat_XFormItem.prototype.moveDownButton = { ref:".", type:_BUTTON_, label:"v", width:20, onActivate:function (event) { var repeatItem = this.getParentItem().getParentItem(); repeatItem.moveDownButtonClicked(this.getParentItem().instanceNum); }, relevantBehavior:_HIDE_, relevant:"(item.getInstanceCount()-1) == item.__parentItem.instanceNum", forceUpdate:true } Repeat_XFormItem.prototype.initializeItems = function () { var items = this.getItems(); if (items.length == 1 && items[0].items) { var group = items[0]; } else { var group = { ref: this.getRef(), fromRepeat:true, // useParentTable:true, type:_GROUP_, numCols: items.length, items:[].concat(items) }; } // group.useParentTable = true; group.colSpan = 1; var relevant = "(item.instanceNum < " + this.getNumberToShow() + ") || "+ "(item.instanceNum < item.getInstanceCount())"; group.relevant = relevant; // add the add and remove buttons to the original items array, if appropriate if (this.getShowRemoveButton()) { group.items[group.items.length] = this.getRemoveButton(); group.numCols++; } if (this.getShowAddButton()) { var button = this.getAddButton(); if (!this.getAlwaysShowAddButton()) { button.relevant = "(item.getInstanceCount()-1) == item.__parentItem.instanceNum"; } group.items[group.items.length] = button; group.numCols++; } if (this.getShowMoveUpButton()) { group.items[group.items.length] = this.getMoveUpButton(); group.numCols++; } if (this.getShowMoveDownButton()) { group.items[group.items.length] = this.getMoveDownButton(); group.numCols++; } // save off the original items in the group this.__originalItems = group; // and reset the items array this.items = []; } Repeat_XFormItem.prototype.makeRepeatInstance = function() { // NOTE: We always append the new items to the end, which is OK, // since if a *data value* is inserted in the middle, // each row will show the proper thing when the update script is called // // NOTE: XFORMS SPEC REQUIRES REPEAT ITEMS TO START AT 1, this implementation starts at 0!!! // var originalGroup = this.__originalItems; var numCols = this.getNumCols(); var newItems = []; for (var i = 0; i < numCols; i++) { var instanceNum = this.items.length; originalGroup.refPath = this.getRefPath() + "[" + instanceNum + "]"; // initialize the originalGroup and its cloned items groupItem = this.getForm().initItem(originalGroup, this); groupItem.instanceNum = instanceNum; newItems.push(groupItem); this.items.push(groupItem); } return newItems; } Repeat_XFormItem.prototype.outputHTML = function (html, updateScript, indent, currentCol) { // output one item to start // all other items will be output dynamically this.makeRepeatInstance(); this.getForm().outputItemList(this.items, this, html, updateScript, indent + " ",this.getNumCols(), 0); } Repeat_XFormItem.prototype.updateElement = function (value) { var form = this.getForm(); var element = this.getElement(); if (value == null || value == "") value = []; var itemsToShow = Math.max(value.length, this.getNumberToShow()); var slotsPresent = this.items.length; var masterId = this.getId(); if (itemsToShow > slotsPresent) { var missingElementCount = (itemsToShow - slotsPresent); // create some more slots and show them var table = element.getElementsByTagName("table")[0]; var tbody = element.getElementsByTagName("tbody")[0]; if (AjxEnv.isIE) { var tempDiv = this.createElement("temp",null,"div",""); tempDiv.display = "none"; } var updateScript = new AjxBuffer(); while (this.items.length < itemsToShow) { var newItems = this.makeRepeatInstance(this); var html = new AjxBuffer(); form.outputItemList(newItems, this, html, updateScript, " ", this.getNumCols(), 0, true); if (AjxEnv.isIE) { tempDiv.innerHTML = "" + html + "
"; var rows = tempDiv.getElementsByTagName("table")[0].rows; for (var r = 0; r < rows.length; r++) { tbody.appendChild(rows[r]); } } else { var row = table.insertRow(-1); row.innerHTML = html; } } // update the insert and update scripts so they'll be called next time form.appendToUpdateScript(updateScript); // Since this is being called in the middle of update, // any items that need to be inserted won't have been, // and we won't have updated the items required. // Handle this now. //TODO: PUT this IN THE CORRECT PLACE BY PARSING THE STRING SOMEHOW??? form.tempScript = new Function(form.getUpdateScriptStart() + updateScript + form.getUpdateScriptEnd()); form.tempScript(); delete form.tempScript; } } Repeat_XFormItem.prototype.addRowButtonClicked = function (instanceNum) { var path = this.getRefPath(); this.getModel().addRowAfter(this.getInstance(), path, instanceNum); this.getForm().refresh(); } Repeat_XFormItem.prototype.removeRowButtonClicked = function (instanceNum) { if(this.getOnRemoveMethod() ) { this.getOnRemoveMethod().call(this, instanceNum, this.getForm()) } else { var path = this.getRefPath(); this.getModel().removeRow(this.getInstance(), path, instanceNum); } this.getForm().refresh(); } Repeat_XFormItem.prototype.getOnRemoveMethod = function() { return this.cacheInheritedMethod("onRemove","$onRemove","index,form"); } function Repeat_Grid_XFormItem() {} XFormItemFactory.createItemType("_REPEAT_GRID_", "repeat_grid", Repeat_Grid_XFormItem, Repeat_XFormItem) Repeat_Grid_XFormItem.prototype.showRemoveButton = false; Repeat_Grid_XFormItem.prototype.showAddButton = false; Repeat_Grid_XFormItem.numCols = 2; // // XFormItem class: "composite" // function Composite_XFormItem() {} XFormItemFactory.createItemType("_COMPOSITE_", "composite", Composite_XFormItem, Group_XFormItem) // type defaults Composite_XFormItem.prototype.useParentTable = false; Composite_XFormItem.prototype.tableCssClass = "xform_composite_table"; Composite_XFormItem.prototype.focusable = false; Composite_XFormItem.prototype.initializeItems = function () { var items = this.getItems(); if (items == null) return; // make sure the numCols is defined (default to the number of items in the composite) if (this.numCols == null) this.numCols = items.length; // actually instantiate them as formItems this.items = this.getForm().initItemList(items, this); } Composite_XFormItem.onFieldChange = function(value, event, form) { if(this.getParentItem() && this.getParentItem().getOnChangeMethod()) { return this.getParentItem().getOnChangeMethod().call(this, value, event, form); } else { return this.setInstanceValue(value); } } //Composite_XFormItem.prototype.getErrorContainer = function () { // //} // // XFormItem class: "date (composite item)" // function Date_XFormItem() {} XFormItemFactory.createItemType("_DATE_", "date", Date_XFormItem, Composite_XFormItem) // type defaults Date_XFormItem.prototype.DATE_MONTH_CHOICES = [ {value:1, label:AjxMsg.jan}, {value:2, label:AjxMsg.feb}, {value:3, label:AjxMsg.mar}, {value:4, label:AjxMsg.apr}, {value:5, label:AjxMsg.may}, {value:6, label:AjxMsg.jun}, {value:7, label:AjxMsg.jul}, {value:8, label:AjxMsg.aug}, {value:9, label:AjxMsg.sep}, {value:10, label:AjxMsg.oct}, {value:11, label:AjxMsg.nov}, {value:12, label:AjxMsg.dec} ]; Date_XFormItem.prototype.DATE_DAY_CHOICES = ["1","2","3","4","5","6","7","8","9","10","11","12", "13","14","15","16","17","18","19","20","21","22", "23","24","25","26","27","28","29","30","31"]; Date_XFormItem.prototype.numCols = 3; Date_XFormItem.prototype.items = [ { type:_SELECT1_, ref:".", width:50, valign:_MIDDLE_, relevantBehavior:_PARENT_, choices: Date_XFormItem.prototype.DATE_MONTH_CHOICES, labelLocation:_NONE_, getDisplayValue:function (newValue) { if (!(newValue instanceof Date)) newValue = new Date(); return "" + (newValue.getMonth() + 1); }, elementChanged:function (monthStr, currentDate, event) { if (currentDate == null) currentDate = new Date(); //??? should get values of other field??? var month = parseInt(monthStr); if (!isNaN(month)) { month -= 1; currentDate.setMonth(month); } this.getForm().itemChanged(this.getParentItem(), currentDate, event); } }, { type:_SELECT1_, ref:".", width:50, valign:_MIDDLE_, relevantBehavior:_PARENT_, labelLocation:_NONE_, choices: Date_XFormItem.prototype.DATE_DAY_CHOICES, getDisplayValue:function (newValue) { if (!(newValue instanceof Date)) newValue = new Date(); return "" + newValue.getDate(); }, elementChanged: function (dateStr, currentDate, event) { if (currentDate == null) currentDate = new Date(); //??? should get values of other field??? var date = parseInt(dateStr); if (!isNaN(date)) { currentDate.setDate(date); } this.getForm().itemChanged(this.getParentItem(), currentDate, event); } }, { type:_TEXTFIELD_, ref:".", relevantBehavior:_PARENT_, width:45, labelLocation:_NONE_, getDisplayValue:function (newValue) { if (!(newValue instanceof Date)) newValue = new Date(); return "" + newValue.getFullYear(); }, elementChanged: function (yearStr, currentDate, event) { if (currentDate == null) currentDate = new Date(); //??? should get values of other field??? var year = parseInt(yearStr); if (!isNaN(year)) { currentDate.setYear(year); } this.getForm().itemChanged(this.getParentItem(), currentDate, event); } } ]; // // XFormItem class: "time (composite item)" // function Time_XFormItem() {} XFormItemFactory.createItemType("_TIME_", "time", Time_XFormItem, Composite_XFormItem) // type defaults Time_XFormItem.prototype.numCols = 3; Time_XFormItem.prototype.TIME_HOUR_CHOICES = ["1","2","3","4","5", "6","7","8","9","10","11","12"]; Time_XFormItem.prototype.TIME_MINUTE_CHOICES = ["00","05","10","15","20","25", "30","35","40","45","50","55"]; Time_XFormItem.prototype.TIME_AMPM_CHOICES = [AjxMsg.am,AjxMsg.pm]; Time_XFormItem.prototype.items = [ { type:_SELECT1_, ref:".", width:50, valign:_MIDDLE_, choices: Time_XFormItem.prototype.TIME_HOUR_CHOICES, labelLocation:_NONE_, getDisplayValue:function (newValue) { if (!(newValue instanceof Date)) newValue = new Date(); var hours = "" + (newValue.getHours() % 12); if (hours == "0") hours = "12"; return hours; }, elementChanged:function (hoursStr, currentDate, event) { if (currentDate == null) currentDate = new Date(); //??? should get values of other fields??? if (this.__dummyDate == null) { this.__dummyDate = new Date(); } this.__dummyDate.setTime(currentDate.getTime()); var hours = parseInt(hoursStr); if (!isNaN(hours)) { if (hours == 12) hours = 0; var wasPM = (currentDate.getHours() > 11); if (wasPM) hours += 12; this.__dummyDate.setHours(hours); } var parentItem = this.getParentItem(); if (parentItem.$elementChanged != null) { this.getParentItem().$elementChanged(this.__dummyDate, currentDate, event); } else { this.getForm().itemChanged(this.getParentItem(), this.__dummyDate, event); } } }, { type:_SELECT1_, ref:".", width:50, valign:_MIDDLE_, choices: Time_XFormItem.prototype.TIME_MINUTE_CHOICES, labelLocation:_NONE_, getDisplayValue:function (newValue) { if (!(newValue instanceof Date)) newValue = new Date(); var minutes = newValue.getMinutes(); minutes = Math.round(minutes / 5) * 5; minutes = (minutes < 10 ? "0" + minutes : "" + minutes); return minutes; }, elementChanged:function (minutesStr, currentDate, event) { if (currentDate == null) currentDate = new Date(); //??? should get values of other fields??? if (this.__dummyDate == null) { this.__dummyDate = new Date(); } this.__dummyDate.setTime(currentDate.getTime()); var minutes = parseInt(minutesStr); if (!isNaN(minutes)) { this.__dummyDate.setMinutes(minutes); } var parentItem = this.getParentItem(); if (parentItem.$elementChanged != null) { this.getParentItem().$elementChanged(this.__dummyDate, currentDate, event); } else { this.getForm().itemChanged(this.getParentItem(), this.__dummyDate, event); } } }, { type:_SELECT1_, ref:".", choices: Time_XFormItem.prototype.TIME_AMPM_CHOICES, width:50, valign:_MIDDLE_, labelLocation:_NONE_, getDisplayValue:function (newValue) { if (!(newValue instanceof Date)) newValue = new Date(); var hours = newValue.getHours(); if (hours > 11) return AjxMsg.pm; return AjxMsg.am; }, elementChanged:function (ampmStr, currentDate, event) { if (currentDate == null) currentDate = new Date(); //??? should get values of other fields??? if (this.__dummyDate == null) { this.__dummyDate = new Date(); } this.__dummyDate.setTime(currentDate.getTime()); var isPM = (ampmStr == AjxMsg.pm); var hours = currentDate.getHours() % 12; this.__dummyDate.setHours(hours + (isPM ? 12 : 0)); var parentItem = this.getParentItem(); if (parentItem.$elementChanged != null) { this.getParentItem().$elementChanged(this.__dummyDate, currentDate, event); } else { this.getForm().itemChanged(this.getParentItem(), this.__dummyDate, event); } } } ]; // // XFormItem class: "datetime" (composite item) // function Datetime_XFormItem() {} XFormItemFactory.createItemType("_DATETIME_", "datetime", Datetime_XFormItem, Composite_XFormItem) Datetime_XFormItem._datetimeFormatToItems = function(format, dateItem, timeItem) { var items = []; var pattern = /{(\d+),\s*(date|time)}/; var index = 0; while ((index = format.search(pattern)) != -1) { if (index > 0) { var item = { type: _OUTPUT_, value: format.substring(0,index), valign: _CENTER_ }; items.push(item); format = format.substring(index); } var result = pattern.exec(format); items.push(result[2] == "date" ? dateItem : timeItem); format = format.substring(result[0].length); } if (format.length > 0) { var item = { type:_OUTPUT_, value: format }; items.push(item); } return items; } // type defaults Datetime_XFormItem.prototype.numCols = 3; Datetime_XFormItem.prototype.items = Datetime_XFormItem._datetimeFormatToItems( DwtMsg.xformDateTimeFormat, {type:_DATE_, ref:".", labelLocation:_NONE_}, {type:_TIME_, ref:".", labelLocation:_NONE_} ); // // XFormItem class: "widget_adaptor" // // An adaptor for using any random (non-DWT) widget in an xform // // NOTE: the generic implementation assumes: // 1) you'll create a method called "constructWidget()" which will construct the appropriate widget // 2) the widget has a function "insertIntoXForm(form, item, element)" // (overide "this.insertWidget" to change) // 3) the widget has a function "updateInXForm(form, item, value, element)" // (overide "this.updateWidget" to change) // function WidgetAdaptor_XFormItem() {} XFormItemFactory.createItemType("_WIDGET_ADAPTOR_", "widget_adaptor", WidgetAdaptor_XFormItem, XFormItem) // type defaults WidgetAdaptor_XFormItem.prototype.writeElementDiv = true; WidgetAdaptor_XFormItem.prototype.focusable = false; // methods // implement the following to actually construct the instance of your widget WidgetAdaptor_XFormItem.prototype.constructWidget = function () {} // // insertElement must guarantee that each element is only inserted ONCE // WidgetAdaptor_XFormItem.prototype.insertElement = function (newValue) { if (!this.__alreadyInserted) { this.__alreadyInserted = true; // try to construct a widget var widget = this.constructWidget(); // if we didn't get one, there's nothing to do here if (widget == null) return; // otherwise insert it into the form! this.widget = widget; this.insertWidget(this.getForm(), this.widget, this.getElement()); } } WidgetAdaptor_XFormItem.prototype.insertWidget = function (form, widget, element) { this.widget.insertIntoXForm(form, this, element); } WidgetAdaptor_XFormItem.prototype.updateElement = function(newValue) { this.updateWidget(newValue); } WidgetAdaptor_XFormItem.prototype.updateWidget = function (newValue) { this.widget.updateInXForm(this.getForm(), this, newValue, this.getElement()); } // // XFormItem class: "dwt_adaptor" // // An adaptor for using any random DWT widget in an xform // // NOTE: the generic implementation assumes: // 1) you'll create a method called "constructWidget()" which will construct the appropriate widget // 2) you'll adapt "insertWidget(form, widget, element)" to insert the widget properly // 3) you'll adapt "updateWidget(newValue)" to update the value properly // function Dwt_Adaptor_XFormItem() {} XFormItemFactory.createItemType("_DWT_ADAPTOR_", "dwt_adaptor", Dwt_Adaptor_XFormItem, WidgetAdaptor_XFormItem) // type defaults Dwt_Adaptor_XFormItem.prototype.focusable = false; // methods Dwt_Adaptor_XFormItem.prototype.setElementEnabled = function(enabled) { WidgetAdaptor_XFormItem.prototype.setElementEnabled.call(this, enabled); if (this.widget) { this.widget.setEnabled(enabled); } this._enabled = enabled; } // implement the following to actually construct the instance of your widget Dwt_Adaptor_XFormItem.prototype.constructWidget = function () {} Dwt_Adaptor_XFormItem.prototype.insertWidget = function (form, widget, element) { this.getForm()._reparentDwtObject(widget, element); } Dwt_Adaptor_XFormItem.prototype.updateWidget = function (newValue) {} Dwt_Adaptor_XFormItem.prototype.getDwtSelectItemChoices = function () { if (this.__selOption != null) return this.__selOptions; var selectOptions = null; var choices = this.getChoices(); if (choices != null) { var selectOptions = new Array(choices.length); for (var i = 0; i < choices.length; i++) { var choice = choices[i]; var choiceValue = (choice instanceof Object ? choice.value : choice); var choiceLabel = (choice instanceof Object ? choice.label : choice); selectOptions[i] = new DwtSelectOptionData(choiceValue, choiceLabel); } } this.__selOptions = selectOptions; return this.__selOptions; }; // // XFormItem class: "dwt_button" // // Adapts a DwtButton to work with the XForm // function Dwt_Button_XFormItem() {} XFormItemFactory.createItemType("_DWT_BUTTON_", "dwt_button", Dwt_Button_XFormItem, Dwt_Adaptor_XFormItem) // type defaults Dwt_Button_XFormItem.prototype.labelLocation = _NONE_; Dwt_Button_XFormItem.prototype.writeElementDiv = false; // methods Dwt_Button_XFormItem.prototype.insertWidget = function (form, widget, element) { this.getForm()._reparentDwtObject(widget, this.getContainer()); }; // implement the following to actually construct the instance of your widget Dwt_Button_XFormItem.prototype.constructWidget = function () { var widget = new DwtButton(this.getForm(), this.getCssClass()); var height = this.getHeight(); var width = this.getWidth(); var el = null; if (width != null || height != null){ el = widget.getHtmlElement(); if (width != null) el.style.width = width; if (height != null) el.style.height = height; } var style = this.getCssStyle(); if (style != null){ var styleArr = style.split(";"); el = (el != null)? el: widget.getHtmlElement(); var kp; for (var i = 0 ; i < styleArr.length ; ++i ){ kp = styleArr[i].split(":"); if (kp.length > 0){ if (kp[0] == "float"){ kp[0] = (AjxEnv.isIE)? "styleFloat": "cssFloat"; } el.style[kp[0]] = kp[1]; } } } widget.setText(this.getLabel()); var onActivateMethod = this.getOnActivateMethod(); if (onActivateMethod != null) { var ls = new AjxListener(this, onActivateMethod); widget.addSelectionListener(ls); } if (this._enabled !== void 0) { this.widget = widget; this.setElementEnabled(this._enabled); } return widget; } // XFormItem class: "dwt_select" // // Adapts a DwtSelect to work with the XForm // function Dwt_Select_XFormItem() {} XFormItemFactory.createItemType("_DWT_SELECT_", "dwt_select", Dwt_Select_XFormItem, Dwt_Adaptor_XFormItem) //XFormItemFactory.registerItemType("_SELECT1_", "select1", Dwt_Select_XFormItem) // type defaults Dwt_Select_XFormItem.prototype.writeElementDiv = false; // methods Dwt_Select_XFormItem.prototype.insertWidget = function (form, widget, element) { this.getForm()._reparentDwtObject(widget, this.getContainer()); } Dwt_Select_XFormItem.prototype.constructWidget = function () { var choices = this.getDwtSelectItemChoices(this.getChoices()); var widget = new DwtSelect(this.getForm(), choices); var height = this.getHeight(); var width = this.getWidth(); if (width != null || height != null){ var el = widget.getHtmlElement(); if (width != null) el.style.width = width; if (height != null) el.style.height = height; } var onChangeFunc = new Function("event", "var widget = event._args.selectObj;\r" + "value = event._args.newValue; " + this.getExternalChangeHandler() ); var ls = new AjxListener(this.getForm(), onChangeFunc); widget.addChangeListener(ls); if (this._enabled !== void 0) { this.widget = widget; this.setElementEnabled(this._enabled); } return widget; } Dwt_Select_XFormItem.prototype.updateWidget = function (newValue) { this.widget.setSelectedValue(newValue); } Dwt_Select_XFormItem.prototype.setElementEnabled = function (enable) { this._enabled = enable; if (this.widget == null) return; if (enable) { this.widget.enable(); } else { this.widget.disable(); } }; // XFormItem class: "dwt_date" // // Adapts a DwtDate to work with the XForm // function Dwt_Date_XFormItem() {} XFormItemFactory.createItemType("_DWT_DATE_", "dwt_date", Dwt_Date_XFormItem, Dwt_Adaptor_XFormItem) // type defaults Dwt_Date_XFormItem.prototype.cssStyle = "width:80px;"; // methods Dwt_Date_XFormItem.prototype.constructWidget = function () { var widget = new DwtButton(this.getForm()); widget.setActionTiming(DwtButton.ACTION_MOUSEDOWN); // ONE MENU?? var menu = this.menu = new DwtMenu(widget, DwtMenu.CALENDAR_PICKER_STYLE, null, null, this.getForm()); widget.setMenu(menu, true) menu.setAssociatedObj(widget); // For now, create a new DwtCalendar for each of the buttons, since on // IE, I'm having trouble getting the one calendar to work. // TODO: Figure out the IE problem. var cal = new DwtCalendar(menu); cal._invokingForm = this.getForm(); cal._invokingFormItemId = this.getId(); cal.addSelectionListener(new AjxListener(this, this._calOnChange)); widget.__cal = cal; // create a static instance of DwtCalendar that all instances will show //if (window.DwtCalendar && (this.constructor._calendarPopup == null)) { // DO WE NEED TO CONSTRUCT A MENU HERE FIRST??? // CAN THE MENU BE SHARED??? // var cal = this.constructor._calendarPopup = new DwtCalendar(menu); // cal.addSelectionListener(new AjxListener(this, this._calOnChange)); //} // We have to add listeners both for the drop down cell, and // the button proper, to get notified when any part of the // button is hit. //widget.addSelectionListener(new AjxListener(this, this._prePopup)); //widget.addDropDownSelectionListener(new AjxListener(this, this._prePopup)); // NOTE: WHEN THE BUTTON IS PRESSED, WE WANT TO CALL: //var cal = this.constructor._calendarPopup; //cal.setDate(this.widget._date, true); //cal._invokingForm = this.getForm(); //cal._invokingFormItemId = this.getId(); //cal.reparent(event.item.getMenu()); // THEN SHOW THE THING... ??? return widget; } Dwt_Date_XFormItem.prototype.updateWidget = function (newValue) { if (newValue == null) newValue = new Date(); this.widget.setText(this.getButtonLabel(newValue)); this.widget._date = newValue; this.widget.__cal.setDate(newValue,true); }; Dwt_Date_XFormItem.prototype._calOnChange = function (event) { var value = event.detail; var cal = event.item; var elemChanged = this.getElementChangedMethod(); elemChanged.call(this,value, this.getInstanceValue(), event); }; Dwt_Date_XFormItem.prototype._prePopup = function (event) { var cal = this.constructor._calendarPopup; cal.setDate(this.widget._date, true); cal._invokingForm = this.getForm(); cal._invokingFormItemId = this.getId(); cal.reparent(event.item.getMenu()); event.item._toggleMenu(); }; Dwt_Date_XFormItem.prototype.getButtonLabel = function (newValue) { if (newValue == null || !(newValue instanceof Date)) return ""; return (newValue.getMonth()+1) + "/" + newValue.getDate() + "/" + (newValue.getFullYear()); }; function Dwt_Time_XFormItem() { this.items[0].type = _DWT_SELECT_; this.items[0].errorLocation = _INHERIT_; this.items[1].type = _DWT_SELECT_; this.items[1].errorLocation = _INHERIT_; this.items[1].choices = Dwt_Time_XFormItem.TIME_MINUTE_CHOICES; this.items[1].getDisplayValue = function (newValue) { if (!(newValue instanceof Date)) newValue = new Date(); var ret = AjxDateUtil._pad(AjxDateUtil.getRoundedMins(newValue, 15)); return ret; }; this.items[2].type = _DWT_SELECT_; this.items[2].errorLocation = _INHERIT_; } Dwt_Time_XFormItem.TIME_MINUTE_CHOICES = ["00","15","30","45"]; XFormItemFactory.createItemType("_DWT_TIME_", "dwt_time", Dwt_Time_XFormItem, Time_XFormItem); // // XFormItem class: "dwt_datetime" // // Composes a _DWT_DATE_ and a (non-DWT) _TIME_ to make a date/time editor, just for kicks. // function Dwt_Datetime_XFormItem() {} XFormItemFactory.createItemType("_DWT_DATETIME_", "dwt_datetime", Dwt_Datetime_XFormItem, Composite_XFormItem) // type defaults Dwt_Datetime_XFormItem.prototype.numCols = 3; Dwt_Datetime_XFormItem.prototype.useParentTable = false; Dwt_Datetime_XFormItem.prototype.cssClass = "xform_dwt_datetime"; Dwt_Datetime_XFormItem.prototype.items = Datetime_XFormItem._datetimeFormatToItems( DwtMsg.xformDateTimeFormat, {type:_DWT_DATE_, ref:".", labelLocation:_NONE_, errorLocation:_PARENT_, elementChanged: function (newDate, currentDate, event) { newDate.setHours(currentDate.getHours(), currentDate.getMinutes(), currentDate.getSeconds(), 0); this.getParentItem().$elementChanged(newDate, currentDate, event); } }, {type:_DWT_TIME_, ref:".", labelLocation:_NONE_, errorLocation:_PARENT_, elementChanged: function (newDate, currentDate, event) { this.getParentItem().$elementChanged(newDate, currentDate, event); } } ); // // XFormItem class: "dwt_list" // // Composes a _DWT_DATE_ and a (non-DWT) _TIME_ to make a date/time editor, just for kicks. // function Dwt_List_XFormItem() {} XFormItemFactory.createItemType("_DWT_LIST_", "dwt_list", Dwt_List_XFormItem, Dwt_Adaptor_XFormItem) // type defaults //Dwt_Datetime_XFormItem.prototype.numCols = 3; Dwt_Datetime_XFormItem.prototype.useParentTable = false; Dwt_Datetime_XFormItem.prototype.cssClass = "xform_dwt_list"; Dwt_List_XFormItem.prototype.constructWidget = function () { var widget = new DwtListView(this.getForm()); return widget; }; Dwt_List_XFormItem.prototype.insertWidget = function (form, widget, element) { var form = this.getForm(); var val = form.get(this.refPath); widget.set(val); }; Dwt_List_XFormItem.prototype.updateWidget = function (newValue) { }; // // XFormItem class: "button_grid" // function Button_Grid_XFormItem() {} XFormItemFactory.createItemType("_BUTTON_GRID_", "button_grid", Button_Grid_XFormItem, WidgetAdaptor_XFormItem) // type defaults Button_Grid_XFormItem.prototype.numCols = 5; Button_Grid_XFormItem.prototype.cssClass = "xform_button_grid_medium"; Button_Grid_XFormItem.prototype.forceUpdate = true; // methods Button_Grid_XFormItem.prototype.constructWidget = function () { var changeHandler = this.getExternalChangeHandler(); var attributes = { choices:this.getChoices(), numCols:this.getNumCols(), cssClass:this.getCssClass(), onChange:changeHandler, addBracketingCells:(this.getAlign() == _CENTER_) } var multiple = this.getMultiple(); if (multiple !== null) attributes.multiple = multiple; return new ButtonGrid(attributes); } // // XFormItem class: "tab_bar" // // A simple tab (for switching a switch) // Note: right now it just looks like a button, but soon it'll look much cooler // function Tab_Bar_XFormItem() {} XFormItemFactory.createItemType("_TAB_BAR_", "tab_bar", Tab_Bar_XFormItem, Button_Grid_XFormItem) // type defaults Tab_Bar_XFormItem.prototype.multiple = false; Tab_Bar_XFormItem.prototype.cssClass = "xform_button_grid_tab"; Tab_Bar_XFormItem.prototype.align = _CENTER_; Tab_Bar_XFormItem.prototype.colSpan = "*"; // methods Tab_Bar_XFormItem.prototype.initFormItem = function() { this.numCols = this.getChoices().length; } // // XFormItem class: "add_remove" // function Dwt_AddRemove_XFormItem() {} XFormItemFactory.createItemType("_DWT_ADD_REMOVE_", "add_remove", Dwt_AddRemove_XFormItem, Dwt_Adaptor_XFormItem); /*** NOTE: this won't work because attributes.ref is accessed before this method is called in XFormItemFactory#createItem. Dwt_AddRemove_XFormItem.prototype._setAttributes = function(attributes) { // allows "targetRef" alias for "ref" attribute if (!attributes.ref && attributes.targetRef) { attributes.ref = attributes.targetRef; } XFormItem.prototype._setAttributes.call(this, attributes); } /***/ Dwt_AddRemove_XFormItem.prototype.getSorted = function() { return this.getInheritedProperty("sorted"); } Dwt_AddRemove_XFormItem.prototype.getListCssClass = function() { return this.getInheritedProperty("listCssClass"); } Dwt_AddRemove_XFormItem.prototype.getSourceInstanceValue = function() { var items = this.getModel().getInstanceValue(this.getInstance(), this.getInheritedProperty("sourceRef")); return items ? items : []; } Dwt_AddRemove_XFormItem.prototype.getTargetInstanceValue = function() { var items = this.getInstanceValue(); return items ? items : []; } Dwt_AddRemove_XFormItem.prototype._handleStateChange = function(event) { var form = this.getForm(); var id = this.getId(); var widget = this.getWidget(); var value = widget.getTargetItems(); form.itemChanged(id, value); } Dwt_AddRemove_XFormItem.prototype.constructWidget = function() { var form = this.getForm(); var cssClass = this.getCssClass(); var listCssClass = this.getListCssClass(); var widget = new DwtAddRemove(form, cssClass, null, listCssClass); return widget; } Dwt_AddRemove_XFormItem.prototype.updateWidget = function(newvalue) { if(this.widget.isUpdating) { this.widget.isUpdating = false; return; } if (this._skipUpdate) { return; } if (this._stateChangeListener) { this.widget.removeStateChangeListener(this._stateChangeListener); } else { this._stateChangeListener = new AjxListener(this, Dwt_AddRemove_XFormItem.prototype._handleStateChange) } var sourceItems = this.getSourceInstanceValue(); var targetItems = this.getTargetInstanceValue(); var sorted = this.getSorted(); if (sorted) { sourceItems = sourceItems.sort(); targetItems = targetItems.sort(); } this.widget.setSourceItems(sourceItems); this.widget.removeSourceItems(targetItems); this.widget.setTargetItems(targetItems); this.widget.addStateChangeListener(this._stateChangeListener); } // // XFormItem class: "alert" // function Dwt_Alert_XFormItem() {} XFormItemFactory.createItemType("_DWT_ALERT_", "alert", Dwt_Alert_XFormItem, Dwt_Adaptor_XFormItem); Dwt_Alert_XFormItem.prototype.colSpan = "*"; Dwt_Alert_XFormItem.prototype.labelLocation = _NONE_; Dwt_Alert_XFormItem.prototype.getStyle = function() { return this.getInheritedProperty("style"); } Dwt_Alert_XFormItem.prototype.getIconVisible = function() { return this.getInheritedProperty("iconVisible"); } Dwt_Alert_XFormItem.prototype.getTitle = function() { return this.getInheritedProperty("title"); } Dwt_Alert_XFormItem.prototype.getContent = function() { return this.getInheritedProperty("content"); } Dwt_Alert_XFormItem.prototype.getAlertCssClass = function() { return this.getInheritedProperty("alertCssClass"); } Dwt_Alert_XFormItem.prototype.constructWidget = function() { var style = this.getStyle(); var iconVisible = this.getIconVisible(); var title = this.getTitle(); var content = this.getContent(); var alertCssClass = this.getAlertCssClass(); var form = this.getForm(); var alert = new DwtAlert(form, alertCssClass); alert.setStyle(style); alert.setIconVisible(iconVisible); alert.setTitle(title); alert.setContent(content); return alert; } Dwt_Alert_XFormItem.prototype.updateWidget = function(newvalue) { // nothing } // // XFormItem class: "dwt_tab_bar" // function Dwt_TabBar_XFormItem() {} XFormItemFactory.createItemType("_DWT_TAB_BAR_", "dwt_tab_bar", Dwt_TabBar_XFormItem, Dwt_Adaptor_XFormItem); Dwt_TabBar_XFormItem.prototype.colSpan = "*"; Dwt_TabBar_XFormItem.prototype.labelLocation = _NONE_; // NOTE: Overriding the _TAB_BAR_ XFormItemFactory.registerItemType(_TAB_BAR_, "tab_bar", Dwt_TabBar_XFormItem); Dwt_TabBar_XFormItem.prototype._value2tabkey; Dwt_TabBar_XFormItem.prototype._tabkey2value; Dwt_TabBar_XFormItem.prototype._stateChangeListener; Dwt_TabBar_XFormItem.prototype.getChoices = function() { return this.getInheritedProperty("choices"); } Dwt_TabBar_XFormItem.prototype._handleStateChange = function(event) { var form = this.getForm(); var widget = this.getWidget(); var tabKey = widget.getCurrentTab(); var newvalue = this._tabkey2value[tabKey]; var id = this.getId(); form.itemChanged(id, newvalue); } Dwt_TabBar_XFormItem.prototype.constructWidget = function() { var form = this.getForm(); var cssClass = this.getCssClass(); var widget = new DwtTabView(form, cssClass, DwtControl.STATIC_STYLE); this._value2tabkey = {}; this._tabkey2value = {}; var choices = this.getChoices(); for (var i = 0; i < choices.length; i++) { var choice = choices[i]; // NOTE: DwtTabView keeps its own internal keys that are numerical this._value2tabkey[choice.value] = i + 1; this._tabkey2value[i + 1] = choice.value; var page = new DwtTabViewPage(widget); widget.addTab(choice.label, page); } return widget; } Dwt_TabBar_XFormItem.prototype.updateWidget = function(newvalue) { if(this.widget.isUpdating) { this.widget.isUpdating = false; return; } if (this._stateChangeListener) { this.widget.removeStateChangeListener(this._stateChangeListener); } else { this._stateChangeListener = new AjxListener(this, Dwt_TabBar_XFormItem.prototype._handleStateChange); } var tabKey = this._value2tabkey[newvalue]; if (tabKey != this.widget.getCurrentTab()) { this.widget.switchToTab(tabKey); } this.widget.addStateChangeListener(this._stateChangeListener); }