1 /*
  2  * ***** BEGIN LICENSE BLOCK *****
  3  * Zimbra Collaboration Suite Web Client
  4  * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016 Synacor, Inc.
  5  *
  6  * The contents of this file are subject to the Common Public Attribution License Version 1.0 (the "License");
  7  * you may not use this file except in compliance with the License.
  8  * You may obtain a copy of the License at: https://www.zimbra.com/license
  9  * The License is based on the Mozilla Public License Version 1.1 but Sections 14 and 15
 10  * have been added to cover use of software over a computer network and provide for limited attribution
 11  * for the Original Developer. In addition, Exhibit A has been modified to be consistent with Exhibit B.
 12  *
 13  * Software distributed under the License is distributed on an "AS IS" basis,
 14  * WITHOUT WARRANTY OF ANY KIND, either express or implied.
 15  * See the License for the specific language governing rights and limitations under the License.
 16  * The Original Code is Zimbra Open Source Web Client.
 17  * The Initial Developer of the Original Code is Zimbra, Inc.  All rights to the Original Code were
 18  * transferred by Zimbra, Inc. to Synacor, Inc. on September 14, 2015.
 19  *
 20  * All portions of the code are Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016 Synacor, Inc. All Rights Reserved.
 21  * ***** END LICENSE BLOCK *****
 22  */
 23 
 24 
 25 //
 26 //	Factory to create XFormItems from simple attributes (eg: from JS object literals or XML)
 27 //
 28 
 29 /**
 30  * This object is never instantiated.
 31  * @class
 32  * @private 
 33  */
 34 XFormItemFactory = function() {}
 35 
 36 /**
 37  * Creates a form item.
 38  *
 39  * @param attributes		an object whose properties map to component attribute name/value pairs
 40  * @param parentItem 		the parent item of this item
 41  * @param {XForm}	xform      the form to which this item is being created
 42  * 
 43  * @private
 44  */
 45 XFormItemFactory.createItem = function (attributes, parentItem, xform) {
 46 	// assign a modelItem to the item
 47 	var refPath = this.getRefPath(attributes, parentItem);
 48 	var subRefPath = this.getSubRefPath(attributes, parentItem);
 49 
 50 	var modelItem, subModelItem;
 51 	if (refPath != null) {
 52 		// assign a modelItem to the item
 53 		modelItem = this.getModelItem(xform.xmodel, attributes, refPath);
 54 	}
 55 	
 56 	if (subRefPath != null) {
 57 		// assign a modelItem to the item
 58 		subModelItem = this.getModelItem(xform.xmodel, attributes, subRefPath);
 59 	}
 60 	// get the class for that type and create one
 61 	var type = this.getItemType(attributes, modelItem);
 62 	var constructor = this.getItemTypeConstructor(type, xform);
 63 
 64 	var item = new constructor();
 65 	item._setAttributes(attributes);
 66 
 67 	// get a unique id for the item
 68 	var idPrefix = (	attributes.id ? xform.getId() + "_" + attributes.id :
 69 							  refPath ? xform.getId() + "_" + refPath :
 70 					item.__parentItem ? item.__parentItem.getId() :
 71 										xform.getId() + "_" + item.type
 72 					);
 73 	// assign a unique id to each item
 74 	//	(if the item specifies an id, we use a variant of that, just in case there's more than one)
 75 	item.id = xform.getUniqueId(idPrefix);
 76 
 77 	item.refPath = refPath;
 78 	item.subRefPath = subRefPath;
 79 	item.__modelItem = modelItem;
 80 	item.__subModelItem = subModelItem;
 81 	
 82 	item.__xform = xform;
 83 	item.__parentItem = parentItem;
 84 	
 85 	// assign the item into our form's index so we can be found later
 86 	xform.indexItem(item, item.id);
 87 	
 88 
 89 	// tell the item to initialize any special properties it needs to on construction
 90 	item.initFormItem();
 91 	
 92 		
 93 	return item;
 94 } 
 95 
 96 XFormItemFactory.getRefPath = function (attributes, parentItem) {
 97 	if (attributes.refPath) return attributes.refPath;
 98 	
 99 	var ref = attributes.ref;
100 	if (ref == null) return null;
101 	
102 	if (parentItem) {
103 		var parentPath = parentItem.getRefPath();
104 		if (parentPath == null) parentPath = "";
105 	} else {
106 		var parentPath = "";
107 	}
108 	
109 	var path = ref;
110 	if (ref == ".") {
111 		path = parentPath;
112 
113 	} else if (ref == "..") {
114 		parentPath = parentPath.split("/");
115 		path = parentPath.slice(0, parentPath.length - 1).join("/");
116 
117 	} else if (parentPath == "") {
118 		path = ref;
119 
120 	} else {
121 		path = parentPath + "/" + ref;
122 	}
123 	return path;
124 }
125 
126 XFormItemFactory.getSubRefPath = function (attributes, parentItem) {
127 	if (attributes.subRefPath) return attributes.subRefPath;
128 	
129 	var subRref = attributes.subRef;
130 	if (subRref == null) return null;
131 	
132 	if (parentItem) {
133 		var parentPath = parentItem.getSubRefPath();
134 		if (parentPath == null) parentPath = "";
135 	} else {
136 		var parentPath = "";
137 	}
138 	
139 	var path = subRref;
140 	if (subRref == ".") {
141 		path = parentPath;
142 
143 	} else if (subRref == "..") {
144 		parentPath = parentPath.split("/");
145 		path = parentPath.slice(0, parentPath.length - 1).join("/");
146 
147 	} else if (parentPath == "") {
148 		path = subRref;
149 
150 	} else {
151 		path = parentPath + "/" + subRref;
152 	}
153 	return path;
154 }
155 
156 XFormItemFactory.getModelItem = function (xmodel, attributes, refPath) {
157 	if (refPath == null || refPath == "") return null;
158 	return xmodel.getItem(refPath, true);
159 }
160 
161 XFormItemFactory.getItemType = function (attributes, modelItem) {
162 	var type = attributes.type;
163 
164 	if (type == null) {
165 		type = attributes.type = _OUTPUT_;
166 	}
167 	
168 	var modelType = (modelItem && modelItem.type ? modelItem.type : _STRING_);
169 
170 	if (type == _INPUT_) {
171 		if (attributes.value !== _UNDEFINED_) {
172 			type = _CHECKBOX_;
173 		} else {
174 			switch (modelType) {
175 				case _STRING_:
176 				case _NUMBER_:
177 					type = _INPUT_;
178 					break;
179 
180 				case _DATE_:
181 				case _DATETIME_:
182 				case _TIME_:
183 					type = modelType;			
184 					break;
185 
186 				default:
187 					type = _INPUT_;
188 			}
189 		}
190 	} else if (type == _SELECT_) {
191 		var appearance = attributes.appearance;
192 		if (appearance == _RADIO_) {
193 			type = _RADIO_;
194 		} else {
195 			type = _SELECT_;
196 		}
197 	}
198 	return type;
199 }
200 
201 XFormItemFactory.typeConstructorMap = {};
202 
203 XFormItemFactory.createItemType = 
204 function (typeConstant, typeName, constructor, superClassConstructor) {
205 	if (constructor == null) constructor = new Function();
206 	if (typeof superClassConstructor == "string") superClassConstructor = this.getItemTypeConstructor(superClassConstructor);
207 	if (superClassConstructor == null) superClassConstructor = XFormItem;
208 
209 	// initialize the constructor
210 	constructor.prototype = new superClassConstructor();	
211 
212 	constructor.prototype.type = typeName;
213 	constructor.prototype.constructor = constructor;
214 	constructor.prototype.toString = new Function("return '[XFormItem:" + typeName + " ' + this.getId() + ']'");
215 	constructor.toString = new Function("return '[Class XFormItem:" + typeName + "]'");
216 	
217 	// put the item type into the typemap
218 	this.registerItemType(typeConstant, typeName, constructor);
219 	
220 	// return the prototype
221 	return constructor;
222 }
223 
224 XFormItemFactory.registerItemType = 
225 function(typeConstant, typeName, constructor) {
226 	// assign the type constant to the window so everyone else can use it
227 	window[typeConstant] = typeName;
228 	this.typeConstructorMap[typeName] = constructor;	
229 }
230 
231 XFormItemFactory.defaultItemType = "output";
232 XFormItemFactory.getItemTypeConstructor = 
233 function (typeName, form) {
234 	var typeConstructorMap = (form && form.typeConstructorMap ? form.typeConstructorMap : this.typeConstructorMap);
235 	
236 	var typeConstructor = typeConstructorMap[typeName];
237 	if (typeConstructor == null) {
238 		var defaultItemType = (form ? form.defaultItemType : this.defaultItemType);
239 		typeConstructorMap[defaultItemType];
240 	}
241 	return typeConstructor;
242 }
243 
244 XFormItemFactory.quickClone = 
245 function(object) {
246 	this.cloner.prototype = object;
247 	return new this.cloner();
248 }
249 XFormItemFactory.cloner = function(){}
250 
251 XFormItemFactory.initItemDefaults = function(form, itemDefaults) {
252 	// create a clone of the XFormItemFactory typeConstructorMap for the form
253 	form.typeConstructorMap =  this.quickClone(this.typeConstructorMap);
254 
255 	if (itemDefaults == null) itemDefaults = form.itemDefaults;
256 	if (itemDefaults != null) {
257 		// for each type in itemDefaults
258 		for (var type in itemDefaults) {
259 			var originalConstructor = this.typeConstructorMap[type];
260 			var defaults = itemDefaults[type];
261 
262 			if (originalConstructor == null) {
263 				type = window[type];
264 				originalConstructor = this.typeConstructorMap[type];
265 			}
266 			if (originalConstructor == null) {
267 				continue;
268 			}
269 			var newConstructor = form.typeConstructorMap[type] = new Function();
270 			newConstructor.prototype = new originalConstructor();
271 			// NOTE: reassigning the constructor here is technically correct,
272 			//		but will result in (item.constructor == originalClass.constructor) not working...
273 			newConstructor.prototype.constructor = newConstructor;
274 			
275 			for (var prop in defaults) {
276 				newConstructor.prototype[prop] = defaults[prop];
277 			}
278 		}
279 	}
280 }
281 
282 
283 
284 
285 //
286 //	Abstract Class XFormItem
287 //
288 //	All other form item classes inherit from this.
289 //
290 
291 
292 /**
293  * @private
294  */
295 XFormItem = function() {}
296 XFormItem.prototype.constructor = XFormItem;
297 XFormItemFactory.registerItemType("_FORM_ITEM_", "form_item", XFormItem);
298 
299 XFormItem.ERROR_STATE_ERROR = 0;
300 XFormItem.ERROR_STATE_VALID = 1;
301 
302 
303 //
304 // set base class defaults
305 // 
306 
307 XFormItem.prototype._isXFormItem = true;
308 
309 // outputting and inserting
310 XFormItem.prototype.writeElementDiv = false;
311 
312 // appearance
313 XFormItem.prototype.labelLocation = _LEFT_;
314 XFormItem.prototype.tableCssClass = "xform_table";				// table that encloses one or more cells
315 XFormItem.prototype.tableCssStyle = null;						// table that encloses one or more cells
316 XFormItem.prototype.containerCssClass =  "xform_container";		// td that contains the element
317 XFormItem.prototype.containerCssStyle =  null;					// td that contains the element
318 XFormItem.prototype.cssClass = null;							// element itself (or element div)
319 XFormItem.prototype.labelCssClass =  "xform_label";				// label td
320 XFormItem.prototype.errorCssClass =  "xform_error";				// error DIV
321 XFormItem.prototype.nowrap = false; 
322 XFormItem.prototype.labelWrap = false; 
323 XFormItem.prototype.align = _UNDEFINED_;						// _UNDEFINED_ because it's a bit faster to draw
324 XFormItem.prototype.valign = _UNDEFINED_;						// _UNDEFINED_ because it's a bit faster to draw
325 XFormItem.prototype.focusable = false;
326 XFormItem.prototype.bmolsnr = false; //Be My Own Listener
327 // updating
328 XFormItem.prototype.forceUpdate = false;			// SET TO true TO FORCE AN ITEM TO UPDATE, EVEN IF VALUE HAS NOT CHANGED
329 //XFormItem.prototype.relevant;
330 //XFormItem.prototype.relevantIfEmpty = true;
331 //XFormItem.prototype.relevantBehavior = _HIDE_;		//	_HIDE_, _DISABLE_
332 XFormItem.prototype.isBlockElement = false;
333 XFormItem.prototype.visibilityChecks = []; //array of method references that check whether this element should be visible
334 XFormItem.prototype.enableDisableChecks = []; //array of methods that check whether this element should be enabled 
335 XFormItem.prototype.visibilityChangeEventSources = []; //paths to XModelItems that influence visibility of this XFormItem
336 XFormItem.prototype.enableDisableChangeEventSources = []; //paths to XModelItems that influence Enabled/Disabled state of this XFormItem
337 XFormItem.prototype.valueChangeEventSources = []; //paths to XModelItems that influence the value this XFormItem
338 
339 /* array of references to XModel items that may affect the visibility of this item. 
340 * Whenever any of the XModel items referenced in this array change, they will notify this XForm item
341 */
342 XFormItem.prototype.visibilityUpdaters = [];
343 
344 /* array of references to XModel items that may affect whether this item is enabled. 
345 * Whenever any of the XModel items referenced in this array change, they will notify this XForm item
346 */
347 XFormItem.prototype.enabledDisabledUpdaters = [];
348 
349 // changing/saving
350 XFormItem.prototype.elementChangeHandler = "onchange";
351 
352                               
353 // choices map
354 XFormItem.prototype.selection = _CLOSED_;
355 XFormItem.prototype.openSelectionLabel = "";
356 
357 // error handling
358 XFormItem.prototype.errorLocation = _SELF_;
359 
360 // show help tooltip icon
361 XFormItem.prototype.helpTooltip = false;
362 //
363 // Methods
364 //
365 
366 
367 // set the initializing attributes of this firm
368 XFormItem.prototype._setAttributes = function (attributes) {
369 	this.__attributes = attributes;
370 }
371 
372 // override this to do any item initialization you need to do
373 //	NOTE: this is called AFTER the formItem is initiaized with its modelItem, set in its form, etc
374 XFormItem.prototype.initFormItem = function() {
375 //	window.status = '';
376 	if(this.focusable) {
377 		var currentTabId = XFormItem.getParentTabGroupId(this);
378 		if(currentTabId) {
379 			var tabGroupItem = this.getForm().getItemById(currentTabId);
380 			tabGroupItem.tabIdOrder.push(this.getId());
381 		}
382 	}
383 }	
384 
385 // DEFAULT IMPLEMENTATION calls this.getForm().initItemList() on our items array
386 //	SOME CLASSES MAY NOT WANT TO DO THIS (eg: _REPEAT_, which does this dynamically later)
387 XFormItem.prototype.initializeItems = function () {
388 	var items = this.getItems();
389 	if (items != null) {
390 		this.items = this.getForm().initItemList(items, this);
391 	}
392 }
393 
394 XFormItem.prototype.registerActiveChild = function(item) {
395 	if(!this.activeChildren)
396 		this.activeChildren = {};
397 	this.activeChildren[item.getId()]=true;	
398 }
399 
400 XFormItem.prototype.signUpForEvents = function () {
401 	var modelItem;
402 	modelItem = this.getModelItem();
403 
404 	//register this item's listeners with model items
405 	var itemsVisibilityChangers = this.getInheritedProperty("visibilityChangeEventSources");
406 	if(!AjxUtil.isEmpty(itemsVisibilityChangers)) {
407 		var model = this.getModel();
408 		var cnt = itemsVisibilityChangers.length;
409 		if(model && cnt>0) {
410 			for (var i=0; i < cnt; i++) {
411 				var modelItm = model.getItem(itemsVisibilityChangers[i], false);
412 				if(modelItm) {
413 					var lsnr = new AjxListener(this, XFormItem.prototype.updateVisibilityLsnr);
414 					modelItm.addListener(DwtEvent.XFORMS_VALUE_CHANGED, lsnr);
415 				}
416 			}
417 		}
418 	}
419 	
420 	var itemsEnableDisableChangers = this.getInheritedProperty("enableDisableChangeEventSources");
421 	if(!AjxUtil.isEmpty(itemsEnableDisableChangers)) {
422 		var model = this.getModel();
423 		var cnt = itemsEnableDisableChangers.length;
424 		if(model && cnt>0) {
425 			for (var i=0; i < cnt; i++) {
426 				var modelItm = model.getItem(itemsEnableDisableChangers[i], false);
427 				if(modelItm) {
428 					var lsnr = new AjxListener(this, XFormItem.prototype.updateEnabledDisabledLsnr);
429 					modelItm.addListener(DwtEvent.XFORMS_VALUE_CHANGED, lsnr);
430 				}
431 			}
432 		}
433 	}	
434 	
435 	var itemsValueChangers = this.getInheritedProperty("valueChangeEventSources");
436 	if(!AjxUtil.isEmpty(itemsValueChangers)) {
437 		var model = this.getModel();
438 		var cnt = itemsValueChangers.length;
439 		if(model && cnt>0) {
440 			for (var i=0; i < cnt; i++) {
441 				var modelItm = model.getItem(itemsValueChangers[i], false);
442 				if(modelItm) {
443 					var lsnr = new AjxListener(this, XFormItem.prototype.valueChangeLsnr);
444 					modelItm.addListener(DwtEvent.XFORMS_VALUE_CHANGED, lsnr);
445 				}
446 			}
447 		}
448 	}
449 	
450 	//listen to changes of my own model item
451 	var bmolsnr = this.getInheritedProperty("bmolsnr");
452 	if(modelItem && bmolsnr) {
453 		var lsnr = new AjxListener(this, XFormItem.prototype.valueChangeLsnr);
454 		modelItem.addListener(DwtEvent.XFORMS_VALUE_CHANGED, lsnr);
455 	}
456 }
457 
458 XFormItem.prototype.valueChangeLsnr = function (event) {
459 	var updateMethod = this.getUpdateElementMethod();
460 	if(!updateMethod)
461 		return;
462 		
463 	var value = this.getInstanceValue();	
464 	var getDisplayValueMethod = this.getDisplayValueMethod();
465 	if(getDisplayValueMethod)
466 		value = getDisplayValueMethod.call(this,value);
467 	
468 	updateMethod.call(this, value);
469 }
470 
471 XFormItem.prototype.updateElement = function() {
472 	//run update methods on all initialized children
473 	if(!this.activeChildren)
474 		return;
475 		
476 	for(var itemId in this.activeChildren) {
477 		if(this.activeChildren[itemId]===true) {
478 			var item = this.getForm().getItemById(itemId);
479 			if(item && this.getInstance()) {
480 				var updateMethod = item.getUpdateElementMethod();
481 				var getDisplayValueMethod = item.getDisplayValueMethod();
482 				
483 				if(updateMethod) {
484 					var xmodel = this.getModel();
485 					var value = item.getRefPath() ? xmodel.getInstanceValue(this.getInstance(), item.getRefPath()) : item.getValue();
486 					if (getDisplayValueMethod) {
487 						value =  getDisplayValueMethod.call(item,value);
488 					}
489 					updateMethod.call(item,value);
490 				}
491 			}
492 		}
493 	}
494 }
495 
496 XFormItem.prototype.hasReadPermission = function (refToCheck) {
497 	var instance = this.getInstance();
498 	if (!instance.getAttrs)
499 		return false;
500 	
501 	var refPath=null;
502 	if(refToCheck) {
503 		refPath=refToCheck;
504 	} else {
505 		if(!this.refPath)
506 			return true;
507 		else
508 			refPath=this.refPath;
509 	}
510 		
511 	return ((instance.getAttrs.all === true) || (instance.getAttrs[refPath] === true));
512 }
513 
514 XFormItem.prototype.hasWritePermission = function (refToCheck) {
515 	var instance = this.getInstance();
516 	if (!instance.setAttrs)
517 		return false;
518 	
519 	var refPath=null;
520 	if(refToCheck) {
521 		refPath=refToCheck;
522 	} else {
523 		if(!this.refPath)
524 			return true;
525 		else
526 			refPath=this.refPath;
527 	}
528 		
529 	return ((instance.setAttrs.all === true) || (instance.setAttrs[refPath] === true));
530 }
531 
532 XFormItem.prototype.hasRight = function (right) {
533 	var instance = this.getInstance();
534 	if (!instance.rights)
535 		return false;
536 	
537 	if(!right)
538 		return true;
539 		
540 	return (instance.rights[right] === true);
541 }
542 
543 XFormItem.prototype.updateVisibilityLsnr = function (event) {
544 	var updateMethod = this.getUpdateVisibilityMethod();
545 	updateMethod.call(this);
546 }
547 
548 XFormItem.prototype.updateVisibility = function () {
549 	var isVisible = true;
550 	
551 	//check if the parent element is visible
552 	var parentItem = this.getParentItem();
553 	if(parentItem)
554 		isVisible=this.getParentItem().getIsVisible();
555 	
556 	//run stack of visibility checks until encounter a negative result
557 	if(isVisible) {
558 		var myVisibilityChecks = this.getInheritedProperty("visibilityChecks");
559 		if(myVisibilityChecks && myVisibilityChecks instanceof Array) {
560 			var cnt = myVisibilityChecks.length;
561 			for(var i=0;i<cnt;i++) {
562 				if(myVisibilityChecks[i] != null) {
563 					if(typeof(myVisibilityChecks[i])=="function") {
564 						isVisible = myVisibilityChecks[i].call(this);
565 						if(!isVisible)
566 							break;
567 					} else if (myVisibilityChecks[i] instanceof Array) {
568 						//first element is a func reference, the rest of elements are arguments
569 						var func = myVisibilityChecks[i].shift();
570 						isVisible = func.apply(this, myVisibilityChecks[i]);
571 						myVisibilityChecks[i].unshift(func);
572 						if(!isVisible)
573 							break;
574 					} else if (typeof (myVisibilityChecks[i]) == "string") {
575                         //for relevant backward compatibility
576                         var instance = this.getInstance();
577                         isVisible = eval(myVisibilityChecks[i]) ;
578                         if(!isVisible)
579 							break;
580                     }
581 				}
582 			}
583 		}
584 	}	
585 	var reRunRefresh = false;	
586 	if(isVisible) {
587 		if(this.deferred)
588 			reRunRefresh=true;
589 			
590 		this.show();
591 	} else
592 		this.hide();
593 	
594 	//update visibility for active child items
595 	for(var itemId in this.activeChildren) {
596 		if(this.activeChildren[itemId]===true) {
597 			var item = this.getForm().getItemById(itemId);
598 			if(item && this.getInstance()) {
599 				var updateMethod = item.getUpdateVisibilityMethod();				
600 				if(updateMethod) {
601 					updateMethod.call(item);
602 				}
603 			}
604 		}
605 	}
606 	
607 	if(reRunRefresh) {
608 		this.updateEnabledDisabled();
609 		this.updateElement();
610 	}	
611 }
612 
613 XFormItem.prototype.updateEnabledDisabledLsnr = function (event) {
614 	var updateMethod = this.getUpdateEnabledDisabledtMethod();
615 	updateMethod.call(this);	
616 }
617 
618 XFormItem.prototype.updateEnabledDisabled = function (parentDisabled) {
619 	var isEnabled = true;
620 	
621 	//check if the parent element is visible
622 	var parentItem = this.getParentItem();
623 	if(parentItem)
624 		isEnabled=this.getParentItem().getIsEnabled();
625 		
626 	//run stack of visibility checks until encounter a negative result
627 	if(isEnabled) {
628 		var myEnabledDisabledChecks = this.getInheritedProperty("enableDisableChecks");
629 		if(myEnabledDisabledChecks && myEnabledDisabledChecks instanceof Array) {
630 			var cnt = myEnabledDisabledChecks.length;
631 			for(var i=0;i<cnt;i++) {
632 				if(myEnabledDisabledChecks[i] != null) {
633 					if(typeof(myEnabledDisabledChecks[i])=="function") {
634 						isEnabled = myEnabledDisabledChecks[i].call(this);
635 						if(!isEnabled)
636 							break;
637 					} else if (myEnabledDisabledChecks[i] instanceof Array) {
638 						//first element is a func reference, the rest of elements are arguments
639 						var func = myEnabledDisabledChecks[i].shift();
640 						if(!func || !func.apply) continue;
641 						isEnabled = func.apply(this, myEnabledDisabledChecks[i]);
642 						myEnabledDisabledChecks[i].unshift(func);
643 						if(!isEnabled)
644 							break;
645 					}                      
646 				}
647 			}
648 		}else if (myEnabledDisabledChecks == false) {   //always disable this element
649             isEnabled = false ;
650         }
651 	}	
652 	
653 	if(isEnabled)
654 		this.enableElement();
655 	else
656 		this.disableElement();
657 	
658 	//update enableddisabled for active child items
659 	for(var itemId in this.activeChildren) {
660 		if(this.activeChildren[itemId]===true) {
661 			var item = this.getForm().getItemById(itemId);
662 			if(item && this.getInstance()) {
663 				var updateMethod = item.getUpdateEnabledDisabledtMethod();				
664 				if(updateMethod) {
665 					updateMethod.call(item);
666 				}
667 			}
668 		}
669 	}
670 }
671 // error handling
672 
673 /**
674  * Sets the error message for this form item.
675  * This will set the error for this item, or 
676  * useing the errorLocation, follow the chain up,
677  * to set the error on the related item.
678  *
679  * @param message The message to display. This message should already
680  *                be localized.
681  */
682 XFormItem.prototype.setError = function(message, childError) {
683 	var errLoc = this.getErrorLocation();
684 	if (errLoc == _PARENT_ || errLoc == _INHERIT_){
685 		this.getParentItem().setError(message, true);
686 		return;
687 	}
688 	this.getForm().addErrorItem(this);
689 	this.__errorState = XFormItem.ERROR_STATE_ERROR;
690 	var container = this.getErrorContainer(true);
691 	if (container) container.innerHTML = message;
692 };
693 
694 /** 
695  * Clears the error message for this form item. 
696  * This will clear the error for this item, or 
697  * useing the errorLocation, follow the chain up,
698  * to clear the error on the related item.
699  */
700 XFormItem.prototype.clearError = function() {
701 	var errLoc = this.getErrorLocation();
702 	if (errLoc == _PARENT_ || errLoc == _INHERIT_){
703 		this.getParentItem().clearError();
704 		return;
705 	}
706 
707 	this.getForm().removeErrorItem(this);
708 	this.__errorState = XFormItem.ERROR_STATE_VALID;
709 	this.removeErrorContainer();
710 };
711 
712 XFormItem.prototype.hasError = function () {
713 	return (this.__errorState == XFormItem.ERROR_STATE_ERROR);
714 };
715 
716 XFormItem.prototype.getErrorContainer = function(createIfNecessary) {
717 	var container = this.getElement(this.getId() + "___error_container");
718 	if (container != null) return container;
719 	
720 	if (createIfNecessary == true && this.getContainer()) {
721 		return this.createErrorContainer();
722 	}
723 	return null;
724 }
725 
726 XFormItem.prototype.createErrorContainer = function () {
727 	// output an error container
728 	var errorContainer = document.createElement("div");
729 	errorContainer.id = this.getId() + "___error_container";
730 	errorContainer.className = this.getErrorCssClass();
731 
732 	var container = this.getContainer();
733 	if (container.hasChildNodes()) {
734 		container.insertBefore(errorContainer, container.firstChild);
735 	} else {
736 		container.appendChild(errorContainer);
737 	}	
738 	return errorContainer;
739 }
740 
741 XFormItem.prototype.removeErrorContainer = function () {
742 	var errorContainer = this.getErrorContainer();
743 	if (errorContainer != null) {
744 		errorContainer.parentNode.removeChild(errorContainer);
745 	}
746 }
747 
748 
749 //
750 // PROPERTIES OF INDIVIDUAL ITEMS
751 //
752 
753 
754 XFormItem.prototype.getType = function () {
755 	return this.type;
756 }
757 
758 
759 //XXX
760 XFormItem.prototype.getParentItem = function () {
761 	return this.__parentItem;
762 }
763 
764 XFormItem.prototype.getForm = function () {
765 	return this.__xform;
766 }
767 
768 XFormItem.prototype.getGlobalRef = function() {
769 	return this.getForm().getGlobalRefString() + ".getItemById('" + this.getId() + "')";
770 }
771 
772 XFormItem.prototype.getFormGlobalRef = function() {
773 	return this.getForm().getGlobalRefString();
774 }
775 
776 XFormItem.prototype.getInstance = function() {
777 	return this.getForm().instance;
778 }
779 
780 XFormItem.prototype.getModel = function () {
781 	return this.getForm().getModel();
782 }
783 
784 XFormItem.prototype.getController = function () {
785 	return this.getForm().getController();
786 }
787 
788 XFormItem.prototype.getFormController = function () {
789 	return this.getForm().getController();
790 }
791 
792 
793 XFormItem.prototype.getModelItem = function() {
794 	return this.__modelItem;
795 }
796 
797 XFormItem.prototype.getSubModelItem = function() {
798 	return this.__subModelItem;
799 }
800 
801 //XXX NON-STANDARD
802 XFormItem.prototype.getRef = function () {
803 	if (this.ref !== _UNDEFINED_) return this.ref;
804 	return this.__attributes.ref;
805 }
806 
807 XFormItem.prototype.getRefPath = function () {
808 	return this.refPath;
809 }
810 
811 XFormItem.prototype.getSubRefPath = function () {
812 	return this.subRefPath;
813 }
814 
815 XFormItem.prototype.getId = function () {
816 	return this.id;
817 }
818 
819 XFormItem.prototype.getExternalId = function () {
820 	var ret = null;
821 	if (this.__attributes.id !== _UNDEFINED_) {
822 		ret = this.__attributes.id;
823 	} else if ( (ret = this.getRef()) !== _UNDEFINED_) {
824 		// nothing
825 	} else {
826 		ret = null;
827 	}
828 	return ret;
829 };
830 
831 
832 
833 //
834 //	GENERIC HTML WRITING ROUTINES
835 //
836 
837 
838 XFormItem.prototype.getOnChangeMethod = function() {
839 	return this.cacheInheritedMethod("onChange","$onChange","value,event,form");
840 }
841 
842 XFormItem.prototype.getOnActivateMethod = function() {
843 	return this.cacheInheritedMethod("onActivate","$onActivate","event");
844 }
845 
846 XFormItem.prototype.getOnClickMethod = function() {
847 	return this.cacheInheritedMethod("onClick","$onClick","event");
848 }
849 
850 XFormItem.prototype.getExternalChangeHandler = function() {
851 	return "var item = " + this.getGlobalRef() + "; var elementChangedMethod = item.getElementChangedMethod(); elementChangedMethod.call(item, value, item.getInstanceValue(), event||window.event);";
852 }
853 XFormItem.prototype.getElementValueGetterHTML = function () {
854 	return "var value = this.value;";
855 }
856 
857 /**
858 * returns the HTML part of an <input > element that is used to set "onchange" 
859 * (or whatever is defined by elementChangehandler)  property of the element
860 **/
861 XFormItem.prototype.getChangeHandlerHTML = function() {
862 	var elementChangeHandler = this.getElementChangeHandler();
863 	if (elementChangeHandler != "onkeypress") {
864 		return AjxBuffer.concat(" ", elementChangeHandler, "=\"", this.getChangehandlerJSCode() + "\"",this.getKeyPressHandlerHTML());
865 	} else {
866 		return this.getKeyPressHandlerHTML();
867 	}
868 }
869 
870 /**
871 * returns JavaScript code that should be executed when an element is changed by a user
872 * @author Greg Solovyev
873 **/
874 XFormItem.prototype.getChangehandlerJSCode = function () {
875 	return AjxBuffer.concat(this.getElementValueGetterHTML(),this.getExternalChangeHandler());
876 }
877 
878 XFormItem.prototype.getFocusHandlerHTML = function () {
879 	var formId = this.getFormGlobalRef(),
880 		itemId = this.getId()
881 	;
882 	
883 	var inputHelp =  this.getInheritedProperty("inputHelp");
884 	var clearInputHelpScript = "";
885 	if (inputHelp != null) {
886 		clearInputHelpScript = "if (this.value == '" + inputHelp + "') this.value=''; ";
887 		DBG.println("ClearnInputHelpScript = " + clearInputHelpScript);
888 	}
889 	
890 	var onFocusAction = null;
891 	if (this.getInheritedProperty("onFocus") != null) {
892 		onFocusAction = AjxBuffer.concat(" onfocus=\"", formId, ".onFocus('", itemId, "'); " ,	
893 				 clearInputHelpScript ,			 	
894 				 this.getInheritedProperty("onFocus") , ".call(" ,   this.getGlobalRef(), ", event )\"");
895 	}else{
896 		onFocusAction = AjxBuffer.concat(" onfocus=\"", formId, ".onFocus('", itemId, "');",
897 										clearInputHelpScript, "\"" );
898 	}
899 	return AjxBuffer.concat(
900 		//" onfocus=\"", formId, ".onFocus('", itemId, "')\"",
901 		//HC: unflexible hacking way to support the License Portal text field onFocus event
902 		onFocusAction ,		
903 		" onblur=\"", formId, ".onBlur('", itemId, "')\""
904 	);
905 }
906 
907 
908 XFormItem.prototype.getOnActivateHandlerHTML = function() {
909 	var method = this.getOnActivateMethod();
910 	if (method == null) return "";
911 	
912 	return AjxBuffer.concat(
913 			" ", this.getElementChangeHandler(), "=\"", 
914 			this.getGlobalRef(),".$onActivate(event||window.event)\""
915 		);
916 }
917 
918 XFormItem.prototype.getClickHandlerHTML =
919 function () {
920 	var onClickFunc = this.getOnClickMethod();
921 	if (onClickFunc == null) return "" ;
922 	
923 	return AjxBuffer.concat(" onclick=\"", 
924 				this.getGlobalRef(),".$onClick(event||window.event)\""
925 			);
926 			
927 	return AjxBuffer.concat( onClickAction );	
928 }
929 
930 /**
931 * Schedules {@link #handleKeyPressDelay} to fire later when the user finishes typing
932 * @param ev - "onkeypress" event 
933 * @param domItem - HTML form element
934 * @author Greg Solovyev
935 **/
936 XFormItem.prototype.handleKeyUp = function (ev, domItem) {
937 	var key = DwtKeyEvent.getCharCode(ev);
938 	// don't fire off another if we've already set one up unless this is an ENTER key
939 	if (!AjxUtil.isEmpty(this.keyPressDelayHdlr) && key != DwtKeyEvent.KEY_ENTER) {
940 		AjxTimedAction.cancelAction(this.keyPressDelayHdlr);
941 		this.keyPressDelayHdlr = null;
942 	}
943 	var form = this.getForm();
944 	var evt = new DwtKeyEvent();
945 	evt.setFromDhtmlEvent(ev);
946 
947 	if (key == DwtKeyEvent.KEY_TAB) {
948 		DwtUiEvent.setBehaviour(ev, true, false);
949 		return false;
950 	} else {
951 		var action = new AjxTimedAction(this, this.handleKeyPressDelay, [evt, domItem]);
952 		//XForm.keyPressDelayHdlr = setTimeout(XForm.handleKeyPressDelay, 250, item, ev, formItem);
953 		this.keyPressDelayHdlr = AjxTimedAction.scheduleAction(action, 250);
954 	}
955 };
956 
957 XFormItem.prototype.handleKeyDown = function (ev, domItem) {
958 	ev = (ev != null)? ev: window.event;
959 	var key = DwtKeyEvent.getCharCode(ev);
960 	if (key == DwtKeyEvent.KEY_ENTER) {
961 		// By telling the browser just to let this do the default, and 
962 		// not let the event bubble, our keyup handler
963 		// wil see the enter key.
964 		DwtUiEvent.setBehaviour(ev, true, true);
965 		return false;
966 	} else if (key == DwtKeyEvent.KEY_TAB) {
967 		DwtUiEvent.setBehaviour(ev, true, false);
968 		var currentTabId = XFormItem.getParentTabGroupId(this) ;
969 		//DBG.println(AjxDebug.DBG1, "Current Tab ID = " + currentTabId);
970 		if(ev.shiftKey)
971 			this.getForm().focusPrevious(this.getId(), currentTabId);	
972 		else
973 			this.getForm().focusNext(this.getId(), currentTabId);	
974 		return false;
975 	}
976 	return true;
977 };
978 
979 /**
980 * Implements delayed handling of "keypress" event. 
981 * Calls change handler script on the item.
982 * See {@link XFormItem.#getChangehandlerJSCode} for change handler script.
983 
984 **/
985 XFormItem.prototype.handleKeyPressDelay = function(ev, domItem) {	
986 	this.keyPressDelayHdlr = null;
987 	if (this.$changeHandlerFunc == null) {
988 		var JSCode = this.getChangehandlerJSCode();
989 		this.$changeHandlerFunc = new Function("event", JSCode);
990 	}
991 	if (this.$changeHandlerFunc) {
992 		this.$changeHandlerFunc.call(domItem, ev);
993 	}
994 };
995 
996 XFormItem.prototype.getKeyPressHandlerHTML = function () {
997 
998 	var keydownEv = "onkeydown";
999 	if (AjxEnv.isNav) {
1000 		keydownEv = "onkeypress";
1001 	}
1002 	return AjxBuffer.concat(" ", keydownEv,"=\"",this.getGlobalRef(), ".handleKeyDown(event, this)\"",
1003 						   " onkeyup=\"", this.getGlobalRef(), ".handleKeyUp(event, this)\"");
1004 };
1005 
1006 
1007 //
1008 //	container
1009 //
1010 
1011 
1012 XFormItem.prototype.outputContainerTDStartHTML = function (html,  colSpan, rowSpan) {
1013 	var _align = this.getAlign();
1014 	html.append( "<td id=\"",  this.getId(), "___container\"",
1015 					(colSpan > 1 ? " colspan=" + colSpan : ""),
1016 					(rowSpan > 1 ? " rowspan=" + rowSpan : ""),
1017 					this.getContainerCssString(), 
1018 					(_align != _UNDEFINED_ ? " align='" + _align + "'" : ""),
1019 					">"
1020 	);
1021 } 
1022 
1023 XFormItem.prototype.outputContainerTDEndHTML = function (html) {
1024 	html.append("</td id=\"",  this.getId(), "___container\">");
1025 } 
1026 
1027 
1028 //
1029 //	element div
1030 //
1031 // for items that are effectively elements (or are drawn by something other than this form)
1032 // NOTE: you can pass in any random CSS properties you want in cssStyle
1033 XFormItem.prototype.outputElementDivStart = function (html) {
1034 	html.append( "<div id=", this.getId(), this.getCssString(), " xform_type='elementDiv'>");
1035 }
1036 
1037 XFormItem.prototype.outputElementDivEnd = function (html) {
1038 	html.append("</div id=\"", this.getId(), "\">");
1039 }
1040 
1041 //
1042 //	label td
1043 //
1044 XFormItem.prototype.outputLabelCellHTML = function (html,  rowSpan, labelLocation) {
1045 	var label = this.getLabel();
1046 	if (label == null) return;
1047 	
1048 	if (label == "") label = " ";
1049 	
1050 	if (labelLocation == _INLINE_) {
1051 		var style = this.getLabelCssStyle();
1052 		if (style == null) style = "";
1053 		style = "position:relative;left:10px;top:5px;text-align:left;background-color:#eeeeee;margin-left:5px;margin-right:5px;" + style;
1054 		html.append( "<div id=\"", this.getId(),"___label\"", 
1055 								this.getLabelCssString(null, style), ">",
1056 								label,
1057 							"</div>"
1058 					);
1059 	} else {
1060 		//lable for is allowd the label to associate with an input item
1061 		var enableLabelFor = this.getInheritedProperty("enableLabelFor");
1062 		if (enableLabelFor) {
1063 			html.append( "<td id=\"", this.getId(),"___label\"", 
1064 								this.getLabelCssString(), 
1065 								(rowSpan > 1 ? " rowspan=" + rowSpan : ""), ">", 
1066 								"<label for='", this.getId(), "'>", label, "</label>"
1067 				);
1068 		}else{
1069             if(!this.getInheritedProperty("helpTooltip") ||
1070                !this.getInheritedProperty("showHelpTooltip") ||
1071                !this.getInheritedProperty("hideHelpTooltip") ){
1072                 html.append( "<td id=\"", this.getId(),"___label\"",
1073                     this.getLabelCssString(),
1074                     (rowSpan > 1 ? " rowspan=" + rowSpan : ""), ">",
1075                     label
1076                 );
1077             }else{
1078                 html.append( "<td id=\"", this.getId(),"___label\"",
1079                     this.getLabelCssString(),
1080                     " onclick=\"", "XFormItem.prototype.showHelpTooltip" ,
1081 			        ".call(" ,   this.getGlobalRef(), ", event );\" ",
1082                     " onmouseout=\"", "XFormItem.prototype.hideHelpTooltip" ,
1083 			        ".call(" ,   this.getGlobalRef(), ", event );\" ",
1084                     (rowSpan > 1 ? " rowspan=" + rowSpan : ""), ">",
1085                     label
1086                 );
1087             }
1088 		}
1089 		if (this.getRequired()) {
1090 			html.append("<span class='redAsteric'>*</span>");
1091 		}
1092 		html.append("</td>");
1093 	}
1094 
1095 
1096 }
1097 
1098 XFormItem.getParentTabGroupId =
1099 function (item){
1100 	//DBG.println(AjxDebug.DBG1, "Enter the getParentTabGroupId() ...");
1101 	
1102 	while (item != null) {
1103 		var p = item.getParentItem();
1104 		if (p == null || (! p instanceof XFormItem)){
1105 			return null ; //no parent item or p is not an XFormItem
1106 		}else if (p instanceof Group_XFormItem && p.getInheritedProperty("isTabGroup") == true) {	
1107 			return p.getId ();
1108 		}
1109 		//DBG.println(AjxDebug.DBG1, "Continue the getParentTabGroupId() ...");
1110 		item = p ;
1111 	}
1112 }
1113 
1114 
1115 //
1116 //	change handling
1117 //
1118 
1119 XFormItem.prototype.elementChanged = function(elementValue, instanceValue, event) {
1120 	this.getForm().itemChanged(this.getId(), elementValue, event);
1121 }
1122 
1123 //
1124 //	get and set instance values!
1125 //
1126 
1127 
1128 XFormItem.prototype.getInstanceValue = function (path) {
1129 	if (path == null) path = this.getRefPath();
1130 	if (path == null) return null;
1131 	return this.getModel().getInstanceValue(this.getInstance(), path);
1132 }
1133 
1134 //NOTE: model.getInstance() gets count of PARENT
1135 XFormItem.prototype.getInstanceCount = function () {
1136 	if (this.getRefPath() == null) return 0;
1137 	return this.getModel().getInstanceCount(this.getInstance(), this.getRefPath());
1138 }
1139 
1140 XFormItem.prototype.setInstanceValue = function (value, path) {
1141 	if (path == null) path = this.getRefPath();
1142 	if (path == null) return null;
1143 	return this.getModel().setInstanceValue(this.getInstance(), path, value);
1144 }
1145 XFormItem.prototype.set = XFormItem.prototype.setInstancevalue;
1146 
1147 XFormItem.getValueFromHTMLSelect = function (element) {
1148 	var values = [];
1149 	for (var i = 0; i < element.options.length; i++) {
1150 		if (element.options[i].selected) {
1151 			values[values.length] = element.options[i].value;	
1152 		}
1153 	}
1154 	return values.join(",");
1155 }
1156 
1157 XFormItem.prototype.getValueFromHTMLSelect = function(element) {
1158 	if (element == null) element = this.getElement();
1159 	return XFormItem.getValueFromHTMLSelect(element);
1160 }
1161 
1162 XFormItem.updateValueInHTMLSelect1 = function (newValue, element, selectionIsOpen) {
1163 	if (element == null) return null;
1164 	if (selectionIsOpen == null) selectionIsOpen = false;
1165 	
1166 	var options = element.options;
1167 	for (i = 0; i < options.length; i++) {
1168 		var choice = options[i];
1169 		if (choice.value == newValue) {
1170 			element.selectedIndex = i;
1171 			return element.value;
1172 		}
1173 	}
1174 	// default to the first element if nothing was selected (?)
1175 	if (options.length > 0) {
1176 		element.selectedIndex = 0;
1177 		return options[0].value;
1178 	}
1179 	return null;
1180 }
1181 XFormItem.prototype.updateValueInHTMLSelect1 = function (newValue, element, selectionIsOpen) {
1182 	if (element == null) element = this.getElement();
1183 	if (selectionIsOpen == null) selectionIsOpen = this.getSelectionIsOpen();
1184 	return XFormItem.updateValueInHTMLSelect1(newValue, element, selectionIsOpen);
1185 }
1186 
1187 
1188 XFormItem.updateValueInHTMLSelect = function (newValue, element, selectionIsOpen) {
1189 	if (element == null) return null;
1190 	if (newValue == null) newValue = "";
1191 	if (selectionIsOpen == null) selectionIsOpen = false;
1192 	
1193 	// assumes newValue is a comma-delimited string or an array
1194 	if (typeof newValue == "string") newValue = newValue.split(",");
1195 	// hack up newValue to make searching for a particular option newValue easier
1196 	var uniqueStartStr = "{|[", 
1197 		uniqueEndStr = "]|}"
1198 	;
1199 	newValue = uniqueStartStr + newValue.join(uniqueEndStr + uniqueStartStr) + uniqueEndStr;
1200 	
1201 	var options = element.options;
1202 	var anySelected = false;
1203 	for (var i = 0; i < options.length; i++) {
1204 		var isPresent = (newValue.indexOf(uniqueStartStr + options[i].value + uniqueEndStr) > -1);
1205 		options[i].selected = isPresent;
1206 		anySelected = anySelected || isPresent;		
1207 	}
1208 	
1209 	if (!anySelected && !selectionIsOpen) {
1210 		// select the first value???
1211 		options[0].selected = true;
1212 	}
1213 }
1214 
1215 XFormItem.prototype.updateValueInHTMLSelect = function (newValue, element, selectionIsOpen) {
1216 	if (newValue == null) newValue = "";
1217 	if (element == null) element = this.getElement();
1218 	if (selectionIsOpen == null) selectionIsOpen = this.getSelectionIsOpen();
1219 	return XFormItem.updateValueInHTMLSelect(newValue, element, selectionIsOpen);
1220 }
1221 
1222 XFormItem.prototype.getChoicesHTML = function() {
1223 	var choices = this.getNormalizedChoices();
1224 	if (choices == null) return "";	//throw an error?
1225 	var html = new AjxBuffer();
1226 	
1227 
1228 	this.outputChoicesHTMLStart(html);
1229 	var values = choices.values;
1230 	var labels = choices.labels;
1231     var visible = choices.visible ;
1232 
1233     var choiceCssClass = this.getChoiceCssClass();
1234 	for (var i = 0; i < values.length; i++) {
1235         if (visible && (visible[i] == false)) {
1236             //don't display this choice
1237         }else {       //by default, the choice should be visible
1238             html.append("", this.getChoiceHTML(i, values[i], labels[i], choiceCssClass, ""));
1239         }
1240     }
1241 	this.outputChoicesHTMLEnd(html);
1242 	return html.toString();
1243 }
1244 
1245 XFormItem.prototype.outputChoicesHTMLStart = function(html) {
1246 	return;
1247 }
1248 XFormItem.prototype.outputChoicesHTMLEnd = function(html) {
1249 	return;
1250 }
1251 
1252 XFormItem.prototype.getChoiceCssClass = function() {
1253 	return "";
1254 }
1255 
1256 XFormItem.prototype.getChoiceHTML = function (itemNum, value, label, cssClass) {
1257 	return AjxBuffer.concat("<option value=\"", value, "\">", label,"</option>");
1258 }
1259 
1260 XFormItem.prototype.updateChoicesHTML = function () {
1261 	this.cleanChoiceDisplay();
1262 
1263 	// NOTE: setting the innerHTML of the options doesn't work
1264 	//	for now, just set the outer HTML of the entire widget
1265 	// TODO: do this by frobbing the options manually for speed and so things don't flash
1266 	var html = new AjxBuffer();
1267 	this.outputHTML(html, new AjxBuffer());
1268 	if (this.getContainer())  this.getContainer().innerHTML = html.toString();
1269 	return;       
1270 }
1271 
1272 
1273 XFormItem.prototype.getInheritedProperty = function(prop) {
1274 	// first look in the instance attributes
1275 	if (this.__attributes[prop] !== _UNDEFINED_) return this.__attributes[prop];
1276 
1277 	// look up the inheritance chain for this type
1278 	if (this[prop] !== _UNDEFINED_) return this[prop];
1279 
1280 	// if not found there, look in the xmodel
1281 	var modelItem = this.__modelItem;
1282 	if (modelItem && modelItem[prop] !== _UNDEFINED_) return modelItem[prop];
1283 
1284 	return null;
1285 }
1286 
1287 // NOTE: cacheProp MUST be different than prop!
1288 XFormItem.prototype.cacheInheritedProperty = function (prop, cacheProp) {
1289 	if (this[cacheProp] !== _UNDEFINED_) return this[cacheProp];
1290 	return (this[cacheProp] = this.getInheritedProperty(prop));
1291 }
1292 
1293 XFormItem.prototype.cacheInheritedMethod = function (methodName, cacheProp, arguments) {
1294 	if (this[cacheProp] !== _UNDEFINED_) return this[cacheProp];
1295 	var func = this.getInheritedProperty(methodName);
1296 	if (func != null) func = this.convertToFunction(func, arguments);
1297 	this[cacheProp] = func;
1298 	return func;
1299 }
1300 
1301 
1302 
1303 
1304 //
1305 //	properties of the element after its' been drawn
1306 //
1307 
1308 
1309 XFormItem.prototype.getElement = XForm.prototype.getElement;
1310 XFormItem.prototype.showElement = function (id) {
1311 	XForm.prototype.showElement.call(this, id);
1312 }
1313 
1314 XFormItem.prototype.getIsVisible = function () {
1315 	return this.__isVisible;
1316 }
1317 
1318 XFormItem.prototype.getIsEnabled = function () {
1319 	return this.__isEnabled;
1320 }
1321  
1322 XFormItem.prototype.hideElement = function (id,isBlock) {
1323 	XForm.prototype.hideElement.call(this,id,isBlock);
1324 }
1325 
1326 XFormItem.prototype.createElement = XForm.prototype.createElement;
1327 
1328 XFormItem.estimateMyWidth = function (label,withIcon,extraMargin, minimum) {
1329 	var width = (String(label).length/2)*XForm.FONT_WIDTH1 + (String(label).length/2)*XForm.FONT_WIDTH2 + 14;
1330 	if(withIcon)
1331 		width = width + 24;
1332 	
1333 	if(extraMargin>0)
1334 		width = width + extraMargin;
1335 	
1336 	width = (width >= minimum) ? width : minimum;
1337 	return [width,"px"].join("");
1338 }
1339 
1340 XFormItem.prototype.getWidget = function() {
1341 	return this.widget;
1342 }
1343 
1344 XFormItem.prototype.setWidget = function(widget) {
1345 	this.widget = widget;
1346 }
1347 
1348 
1349 XFormItem.prototype.getContainer = function() {
1350 	return this.getElement(this.getId() + "___container");
1351 }
1352 XFormItem.prototype.getLabelContainer = function() {
1353 	return this.getElement(this.getId() + "___label");
1354 }
1355 XFormItem.prototype.show = function() {
1356 	if(this.deferred) {
1357 		this._outputHTML();
1358 	}	
1359 	var container = this.getLabelContainer();
1360 	if (container) this.showElement(container);
1361 	container = this.getContainer();
1362 	if (container != null) {
1363 		this.showElement(container);
1364 	} 
1365 	this.__isVisible = true;
1366 }
1367 
1368 XFormItem.prototype.hide = function(isBlock) {
1369 	isBlock = this.getInheritedProperty("isBlockElement") || isBlock;
1370 	var container = this.getLabelContainer()
1371 	if (container) this.hideElement(container,isBlock);
1372 	container = this.getContainer();
1373 	if (container != null) {
1374 		this.hideElement(container,isBlock);
1375 	} else {
1376 		var items = this.getItems();
1377 		if (items != null) {
1378 			for (var i = 0; i < items.length; i++) {
1379 				items[i].hide(isBlock);
1380 			}
1381 		}
1382 	}
1383 	this.__isVisible = false;
1384 }
1385 
1386 XFormItem.prototype.focus = function () {
1387 	this.getForm().focusElement(this.getId());
1388 };
1389 
1390 
1391 //
1392 //	SIMPLE ATTRIBUTE ACCESSORS
1393 //
1394 //	NOTE: this is effectively the public API for the properties you can define
1395 //			for a FormItem
1396 //
1397 
1398 XFormItem.prototype.getRequired = function() {
1399 	return this.getInheritedProperty("required");
1400 }
1401 
1402 XFormItem.prototype.getValue = function() {
1403 	return this.getInheritedProperty("value");
1404 }
1405 
1406 // SPECIAL CASE:  don't take ITEMS from the model...
1407 //XXX NON-STANDARD
1408 XFormItem.prototype.getItems = function () {
1409 	if (this.items) return this.items;
1410 	return this.__attributes.items;
1411 }
1412 
1413 XFormItem.prototype.getChoices = function () {
1414 	return this.getInheritedProperty("choices");
1415 }
1416 
1417 // normalized choices look like:  {values:[v1, v2, v3...], labels:[l1, l2, l3...]}
1418 XFormItem.prototype.getNormalizedChoices = function () {
1419 	if (this.$normalizedChoices) return this.$normalizedChoices;
1420 
1421 	var choices = this.getChoices();
1422 	if (choices == null) return null;
1423     if (typeof choices == "function") choices = choices.call(this) ;
1424     
1425     var normalizedChoices;
1426 	if (typeof choices.getChoices == "function") {
1427 		normalizedChoices = choices.getChoices();
1428 	} else if (AjxUtil.isArray(choices)) {
1429 		// it's either an array of objects or an array of strings
1430 		if (typeof choices[0] == "object") {
1431 			// list of objects
1432 			normalizedChoices = XFormChoices.normalizeChoices(choices, XFormChoices.OBJECT_LIST);
1433 		} else {
1434 			// list of simple values
1435 			normalizedChoices = XFormChoices.normalizeChoices(choices, XFormChoices.SIMPLE_LIST);
1436 		}
1437 	} else {
1438 		// assume it's a hash
1439 		normalizedChoices = XFormChoices.normalizeChoices(choices, XFormChoices.HASH);
1440 	}
1441 	this.$normalizedChoices = normalizedChoices;
1442 	return this.$normalizedChoices;
1443 }
1444 
1445 
1446 XFormItem.prototype.getNormalizedValues = function () {
1447 	var choices = this.getNormalizedChoices();
1448 	if (choices) return choices.values;
1449 	return null;
1450 }
1451 
1452 
1453 XFormItem.prototype.getNormalizedLabels = function () {
1454 	var choices = this.getNormalizedChoices();
1455 	if (choices) return choices.labels;
1456 	return null;
1457 }
1458 	
1459 	
1460 	
1461 //
1462 //	appearance methods
1463 //
1464 
1465 XFormItem.prototype.getAppearance = function () {
1466 	return this.getInheritedProperty("appearance");
1467 }
1468 XFormItem.prototype.getCssClass = function () {
1469 	return this.getInheritedProperty("cssClass");
1470 }
1471 
1472 XFormItem.prototype.getCssStyle = function () {
1473 	return this.getInheritedProperty("cssStyle");
1474 }
1475 
1476 XFormItem.prototype.getLabel = function (value) {
1477 	return this.getInheritedProperty("label");
1478 }
1479 
1480 XFormItem.prototype.getErrorCssClass = function () {
1481 	return this.getInheritedProperty("errorCssClass");
1482 }
1483 XFormItem.prototype.getLabelCssClass = function (className) {
1484 	if (className != null) return className;
1485 	return this.getInheritedProperty("labelCssClass");
1486 }
1487 
1488 XFormItem.prototype.getLabelCssStyle = function (style) {
1489 	if (style != null) return style;
1490 	return this.getInheritedProperty("labelCssStyle");
1491 }
1492 
1493 XFormItem.prototype.getLabelWrap = function () {
1494 	return this.getInheritedProperty("labelWrap");
1495 }
1496 
1497 XFormItem.prototype.getLabelLocation = function () {
1498 	return this.getInheritedProperty("labelLocation");
1499 }
1500 
1501 XFormItem.prototype.getContainerCssClass = function () {
1502 	return this.getInheritedProperty("containerCssClass");
1503 }
1504 
1505 XFormItem.prototype.getContainerCssStyle = function () {
1506 	return this.getInheritedProperty("containerCssStyle");
1507 }
1508 
1509 XFormItem.prototype.getTableCssClass = function () {
1510 	return this.getInheritedProperty("tableCssClass");
1511 }
1512 XFormItem.prototype.getTableCssStyle = function () {
1513 	return this.getInheritedProperty("tableCssStyle");
1514 }
1515 
1516 XFormItem.prototype.getNowrap = function () {
1517 	return this.getInheritedProperty("nowrap");
1518 }
1519 
1520 XFormItem.prototype.getWidth = function () {
1521 	return this.cacheInheritedProperty("width","_width");
1522 }
1523 
1524 XFormItem.prototype.getHeight = function () {
1525 	return this.getInheritedProperty("height");
1526 }
1527 
1528 XFormItem.prototype.getOverflow = function () {
1529 	return this.getInheritedProperty("overflow");
1530 }
1531 
1532 XFormItem.prototype.getNumCols = function () {
1533 	return this.getInheritedProperty("numCols");
1534 }
1535 
1536 XFormItem.prototype.getAlign = function () {
1537 	return this.getInheritedProperty("align");
1538 }
1539 
1540 
1541 XFormItem.prototype.getValign = function() {
1542 	return this.getInheritedProperty("valign");
1543 }
1544 
1545 XFormItem.prototype.getName = function () {
1546 	return this.getInheritedProperty("name");
1547 }
1548 
1549 // NEW TABLE LAYOUT STUFF
1550 XFormItem.prototype.useParentTable = true;
1551 XFormItem.prototype.getUseParentTable = function () {
1552 	return this.getInheritedProperty("useParentTable");
1553 }
1554 XFormItem.prototype.colSizes = _UNDEFINED_;
1555 XFormItem.prototype.getColSizes = function () {
1556 	return this.getInheritedProperty("colSizes");
1557 }
1558 XFormItem.prototype.colSpan = 1;
1559 XFormItem.prototype.getColSpan = function () {
1560 	return this.getInheritedProperty("colSpan");
1561 }
1562 XFormItem.prototype.rowSpan = 1;
1563 XFormItem.prototype.getRowSpan = function () {
1564 	return this.getInheritedProperty("rowSpan");
1565 }
1566 
1567 // END NEW TABLE LAYOUT STUFF
1568 
1569 // error handling
1570 XFormItem.prototype.getErrorLocation = function () {
1571 	return this.getInheritedProperty("errorLocation");
1572 };
1573 
1574 //
1575 //	convenience methods to figure out drawing types for you
1576 //
1577 
1578 // return the "label" in the choices array for this item
1579 //	(allows us to do lookup of displayed values easily)
1580 XFormItem.prototype.getChoiceLabel = function (value) {
1581 	var choices = this.getNormalizedChoices();
1582 	if (choices == null) return value;
1583 	if (value == null) value = "" ; //make it an empty string, so empty value label can be returned
1584     
1585     // choices will look like:  {values:[v1, v2, v3...], labels:[l1, l2, l3...]}
1586 	var values = choices.values;
1587 	for (var i = 0; i < values.length; i++) {
1588 		if (values[i] == value) {
1589 			return choices.labels[i];
1590 		}
1591 	}
1592 	// if we didn't find it, simply return the original value
1593 	return value;
1594 }
1595 
1596 // return the "label" in the choices array for this item
1597 //	(allows us to do lookup of displayed values easily)
1598 // If no matching choice is found, the label is returned. 
1599 XFormItem.prototype.getChoiceValue = function (label) {
1600 	function labelComparator (a, b) {
1601 			return String(a).toLowerCase() < String(b).toLowerCase() ? -1 : (String(a).toLowerCase() > String(b).toLowerCase() ? 1 : 0);
1602 	 };
1603 	var choices = this.getNormalizedChoices();
1604 	if (choices == null) return label;
1605 	
1606 	// choices will look like:  {values:[v1, v2, v3...], labels:[l1, l2, l3...]}
1607 	// bug 6738: sort will change the mapping between value and label.
1608 	/*
1609 	var labels = choices.labels;
1610 	var vec = AjxVector.fromArray(labels);
1611 	vec.sort(labelComparator);
1612 	var ix = vec.binarySearch(label,labelComparator); */
1613 	var labels = choices.labels;
1614 	var ix = -1;
1615 	for (var i=0; i < labels.length ; i++ ){
1616 		if (labelComparator (label, labels[i]) == 0) {
1617 			ix = i ;
1618 			break;
1619 		}		
1620 	}
1621 	
1622 	if(ix>=0) 
1623 		return choices.values[ix];
1624 	else 		
1625 		//return choices.values[0];// If no matching choice is found, the label is returned, instead of the first value
1626 		return label;
1627 }
1628 
1629 // return the number of the choice for a particular value
1630 //	returns -1 if not found
1631 XFormItem.prototype.getChoiceNum = function (value) {
1632 	var choices = this.getNormalizedChoices();
1633 	if (choices == null) return -1;
1634 	
1635 	// choices will look like:  {values:[v1, v2, v3...], labels:[l1, l2, l3...]}
1636 	var values = choices.values;
1637 	for (var i = 0; i < values.length; i++) {
1638 		if (values[i] == value) {
1639 			return i;
1640 		}
1641 	}
1642 	return -1
1643 }
1644 
1645 XFormItem.prototype.getCssString = function () {
1646 	var css = (this.getCssClass() || '');
1647 	if (css != '' && css != null) css = " class=\"" + css + "\"";
1648 
1649 	var style = (this.getCssStyle() || '');
1650 
1651 	var width = this.getWidth();
1652 	if (width != null && width != "auto") {
1653 		if(style.length)
1654 			style += ";";
1655 			
1656 		if (!isNaN(Number(width)))
1657 			width += 'px';
1658 
1659 		style += "width:" + width;
1660 	}
1661 
1662 	var height = this.getHeight();
1663 	if (height != null) {
1664 		if(style.length)
1665 			style += ";";
1666 	
1667 		if (!isNaN(Number(height)))
1668 			height += 'px';
1669 
1670 		style += "height:" + height;
1671 	}
1672 
1673 	var overflow = this.getOverflow();
1674 	if (overflow != null) {
1675 		if(style.length)
1676 			style += ";";
1677 	
1678 		style += "overflow:" + overflow;
1679 	}
1680 	
1681 	if (this.getNowrap()) {
1682 		if(style.length)
1683 			style += ";";
1684 	
1685 		style += "white-space:nowrap";
1686 	}
1687 
1688 	var valign = this.getValign();
1689 	if (valign) {
1690 		if(style.length)
1691 			style += ";";
1692 	
1693 		style += "vertical-align:"+valign;
1694 	}
1695 	
1696 	if (style != '') css += " style=\"" + style + ";\"";
1697 	return css;
1698 }
1699 
1700 
1701 XFormItem.prototype.getLabelCssString = function (className, style) {
1702 	var css = (this.getLabelCssClass(className) || '');
1703 	if (css != '' && css != null) css = " class=\"" + css + "\"";
1704 	var style = (this.getLabelCssStyle(style) || '');
1705 	if (this.getLabelWrap() == false) {
1706 		if(style.length)
1707 			style += ";";
1708 
1709 		style += "white-space:nowrap";
1710 	}
1711 	if (style != '') css += " style=\"" + style + ";\"";
1712 	
1713 	return css;
1714 }
1715 
1716 
1717 
1718 
1719 XFormItem.prototype.getTableCssString = function () {
1720 	var css = (this.getTableCssClass() || '');
1721 	if (css != '' && css != null) css = " class=\"" + css + "\"";
1722 
1723 	var style = this.getTableCssStyle();
1724 	if (style == null) style = '';
1725 	
1726 	var colSizes = this.getColSizes();
1727 	if (colSizes != null) {
1728 		if(style.length)
1729 			style += ";";
1730 					
1731 		style += "table-layout:fixed";
1732 	}
1733 
1734 	var width = this.getWidth();
1735 	if (width != null) 	style += ";width:"+ width;
1736 	
1737 	var overflow = this.getOverflow();
1738 	if (overflow != null) {
1739 		if(style.length)
1740 			style += ";";
1741 
1742 		style += "overflow:" + overflow;
1743 	}
1744 
1745 	return css + (style != null ? " style=\"" + style + ";\"" : "");
1746 }
1747 
1748 
1749 XFormItem.prototype.getContainerCssString = function () {
1750 	var css = (this.getContainerCssClass() || '');
1751 	if (css != '' && css != null) css = " class=\"" + css + "\"";
1752 	var style = this.getContainerCssStyle();
1753 	if (style == null) style = '';
1754 	
1755 	var align = this.getAlign();
1756 	if (align != _LEFT_) {
1757 		if (align == _CENTER_ || align == _MIDDLE_) {
1758 			if(style.length)
1759 				style += ";";
1760 						
1761 			style += "text-align:center";
1762 		} else if (align == _RIGHT_) {
1763 			if(style.length)
1764 				style += ";";			
1765 		
1766 			style += "text-align:right";
1767 		}
1768 	}
1769 	var valign = this.getValign();
1770 	if (valign == _TOP_) {
1771 		if(style.length)
1772 			style += ";";
1773 					
1774 		style += "vertical-align:top";
1775 	} else if (valign == _BOTTOM_) {
1776 		if(style.length)
1777 			style += ";";
1778 					
1779 		style += "vertical-align:bottom";
1780 	} else if (valign == _CENTER_ || valign == _MIDDLE_) {
1781 		if(style.length)
1782 			style += ";";		
1783 			
1784 		style += "vertical-align:middle";
1785 	}
1786 
1787 	if (style != "") css += " style=\"" + style + ";\"";
1788 	return css;
1789 }
1790 
1791 
1792 
1793 
1794 //
1795 //	handling changes to items
1796 //
1797 XFormItem.prototype.getElementChangeHandler = function () {
1798 	return this.getInheritedProperty("elementChangeHandler");
1799 }
1800 
1801 
1802 
1803 
1804 //
1805 //	outputting, inserting and updating items
1806 //
1807 
1808 XFormItem.prototype.getForceUpdate = function() {
1809 	return this.getInheritedProperty("forceUpdate");
1810 }
1811 
1812 XFormItem.prototype.getOutputHTMLMethod = function() {
1813 	return this.convertToFunction(
1814 				this.getInheritedProperty("outputHTML"),
1815 				"html,currentCol"
1816 		);
1817 }
1818 
1819 XFormItem.prototype.getElementChangedMethod = function () {
1820 	return this.cacheInheritedMethod("elementChanged","$elementChanged","elementValue, instanceValue, event");
1821 }
1822 
1823 XFormItem.prototype.getUpdateElementMethod = function() {
1824 	return this.cacheInheritedMethod("updateElement","$updateElement","newValue");
1825 }
1826 
1827 XFormItem.prototype.getDisplayValueMethod = function() {
1828 	return this.cacheInheritedMethod("getDisplayValue","$getDisplayValue","newValue");
1829 }
1830 
1831 XFormItem.prototype.getUpdateVisibilityMethod = function() {
1832 	return this.cacheInheritedMethod("updateVisibility","$updateVisibility");
1833 }
1834 
1835 XFormItem.prototype.getUpdateEnabledDisabledtMethod = function() {
1836 	return this.cacheInheritedMethod("updateEnabledDisabled","$updateEnabledDisabled");
1837 }
1838 
1839 XFormItem.prototype.convertToFunction = function (script, arguments) {
1840 	if ((script == null) || (typeof(script) == "function")) return script;
1841 	if (typeof(this[script]) == "function") return this[script];
1842 	// CLOSURE???
1843 	return new Function(arguments, script);
1844 }
1845 
1846 
1847 // note that this form item's display needs to be updated
1848 XFormItem.prototype.dirtyDisplay = function () {
1849 	delete this.$lastDisplayValue;
1850 }
1851 
1852 // override the next method in your subclass to enable/disable element
1853 XFormItem.prototype.setElementEnabled = function(enable) {}
1854 
1855 // convenience methods that call the above routine
1856 XFormItem.prototype.disableElement = function () {
1857 	this.setElementEnabled(false);
1858 	this.__isEnabled = false;
1859 }
1860 
1861 XFormItem.prototype.enableElement = function () {
1862 	this.setElementEnabled(true);
1863 	this.__isEnabled = true;
1864 }
1865 
1866 // you can use these to 
1867 XFormItem.prototype.setElementDisabledProperty = function (enable) {
1868 	this.getElement().disabled = (enable != true)
1869 }
1870 
1871 
1872 XFormItem.prototype.setElementEnabledCssClass = function (enable) {
1873 	var el = this.getElement();
1874 	if (!el) return;
1875 	
1876 	if (enable) {
1877 		el.className = this.getCssClass();
1878 	} else {
1879 		el.className = (this.getCssClass() + "_disabled");
1880 	}
1881 }
1882 
1883 
1884 
1885 //
1886 //	_SELECT_ etc type properties
1887 //
1888 XFormItem.prototype.getSelection = function () {
1889 	return this.getInheritedProperty("selection");
1890 }
1891 
1892 XFormItem.prototype.getSelectionIsOpen = function () {
1893 	return this.getInheritedProperty("selection");
1894 }
1895 
1896 XFormItem.prototype.getOpenSelectionLabel = function () {
1897 	return this.getInheritedProperty("openSelectionLabel");
1898 }
1899 
1900 
1901 //
1902 //	_REPEAT_ type properties
1903 //
1904 
1905 XFormItem.prototype.getNumberToShow = function () {
1906 	return this.getInheritedProperty("number");
1907 }
1908 
1909 XFormItem.prototype.getShowAddButton = function () {
1910 	return this.getInheritedProperty("showAddButton");
1911 }
1912 
1913 XFormItem.prototype.getShowRemoveButton = function () {
1914 	return this.getInheritedProperty("showRemoveButton");
1915 }
1916 
1917 XFormItem.prototype.getShowMoveUpButton = function () {
1918 	return this.getInheritedProperty("showMoveUpButton");
1919 }
1920 
1921 XFormItem.prototype.getShowMoveDownButton = function () {
1922 	return this.getInheritedProperty("showMoveDownButton");
1923 }
1924 
1925 XFormItem.prototype.getAddButton = function () {
1926 	return this.getInheritedProperty("addButton");
1927 }
1928 
1929 XFormItem.prototype.getRemoveButton = function () {
1930 	return this.getInheritedProperty("removeButton");
1931 }
1932 
1933 XFormItem.prototype.getMoveUpButton = function () {
1934 	return this.getInheritedProperty("moveUpButton");
1935 }
1936 
1937 XFormItem.prototype.getMoveDownButton = function () {
1938 	return this.getInheritedProperty("moveDownButton");
1939 }
1940 
1941 XFormItem.prototype.getAlwaysShowAddButton = function () {
1942 	return this.getInheritedProperty("alwaysShowAddButton");
1943 }
1944 
1945 XFormItem.prototype.getRepeatInstance = function () {
1946 	return this.getInheritedProperty("repeatInstance");
1947 }
1948 
1949 
1950 
1951 
1952 //
1953 //	_IMAGE_ type properties
1954 //
1955 
1956 XFormItem.prototype.getSrc = function () {
1957 	return this.getInheritedProperty("src");
1958 }
1959 
1960 XFormItem.prototype.getSrcPath = function () {
1961 	return this.getInheritedProperty("srcPath");
1962 }
1963 
1964 
1965 
1966 //
1967 //	_ANCHOR_, _URL_, etc
1968 //
1969 //	type defaults
1970 XFormItem.prototype.getShowInNewWindow = function () {
1971 	return this.getInheritedProperty("showInNewWindow");
1972 }
1973 
1974 
1975 
1976 
1977 //
1978 //	internal properties for creating various item types
1979 //
1980 
1981 
1982 XFormItem.prototype.getWriteElementDiv = function () {
1983 	return this.getInheritedProperty("writeElementDiv");
1984 }
1985 
1986 XFormItem.prototype.getMultiple = function () {
1987 	return this.getInheritedProperty("multiple");
1988 }
1989 
1990 XFormItem.prototype.getAlwaysUpdateChoices = function () {
1991 	return this.getInheritedProperty("alwaysUpdateChoices");
1992 }
1993 
1994 XFormItem.prototype.choicesAreDirty = function () {
1995 	return (this._choiceDisplayIsDirty == true || this.getAlwaysUpdateChoices());
1996 }
1997 
1998 XFormItem.prototype.cleanChoiceDisplay = function () {
1999 	this._choiceDisplayIsDirty = false;
2000 }
2001 
2002 XFormItem.prototype.showInputTooltip =
2003 function (event) {
2004 	var dwtEv = new DwtUiEvent(true);
2005 	dwtEv.setFromDhtmlEvent(event)
2006 	var shell = DwtShell.getShell(window);
2007 	var tooltip = shell.getToolTip();
2008 	tooltip.setContent(this.getInheritedProperty("toolTipContent"));
2009 	tooltip.popup(dwtEv.docX, dwtEv.docY);
2010 }
2011 
2012 XFormItem.prototype.hideInputTooltip =
2013 function (event) {
2014 	var shell = DwtShell.getShell(window);
2015 	var tooltip = shell.getToolTip();
2016 	tooltip.popdown();
2017 }
2018 
2019 
2020 
2021 
2022 
2023 
2024 
2025 
2026 
2027 /**
2028  * @class defines XFormItem type _OUTPUT_
2029  * @constructor
2030  * 
2031  * @private
2032  */
2033 Output_XFormItem = function() {}
2034 XFormItemFactory.createItemType("_OUTPUT_", "output", Output_XFormItem, XFormItem);
2035 
2036 
2037 //	type defaults
2038 Output_XFormItem.prototype.writeElementDiv = true;
2039 Output_XFormItem.prototype.labelWrap = true;
2040 Output_XFormItem.prototype.cssClass =  "xform_output";	// element itself (or element div)
2041 Output_XFormItem.prototype.containerCssClass =  "xform_output_container";	// element itself (or element div)
2042 
2043 //	methods
2044 
2045 Output_XFormItem.prototype.outputHTML = function (html) {
2046 	// by defaut, we output the "attributes.value" if set 
2047 	//	(in case an item only wants to write out on the initial draw)
2048 	// NOTE: dereferencing through the choice map happens in getDisplayValue()
2049 	var value = this.getValue();
2050 	var method = this.getDisplayValueMethod();
2051 	if (method) {
2052 		value = method.call(this, value);
2053 	}
2054 	
2055 	//set the onClick event handler
2056 	var clickMethod = this.getClickHandlerHTML();
2057 	var htmlWithEvent = null ;
2058 	if (clickMethod != null && clickMethod != "") {
2059 		htmlWithEvent = "<div " + this.getClickHandlerHTML() +
2060 		 				">" + value + "</div>" ; 
2061 	}
2062 	
2063 	html.append(htmlWithEvent || value);
2064 }
2065 
2066 
2067 Output_XFormItem.prototype.getDisplayValue = function(newValue) {
2068 	// dereference through the choices array, if provided
2069 	newValue = this.getChoiceLabel(newValue);
2070 
2071 	if (newValue == null) {
2072 		newValue = "";
2073 	} else {
2074 		newValue = "" + newValue;
2075 	}
2076 	return newValue;
2077 }
2078 
2079 Output_XFormItem.prototype.updateElement = function (newValue) {
2080 	var el = this.getElement();
2081 	if(el) {
2082 	    //set the onClick event handler
2083 	    var clickMethod = this.getClickHandlerHTML();
2084 	    var htmlWithEvent = null ;
2085 	    if (clickMethod != null && clickMethod != "") {
2086 		    htmlWithEvent = "<div " + this.getClickHandlerHTML() +
2087 		 				">" + newValue + "</div>" ;
2088 	    }
2089 
2090         newValue = htmlWithEvent || newValue;
2091 		this.getElement().innerHTML = newValue;
2092     }
2093 }
2094 
2095 Output_XFormItem.prototype.initFormItem = function () {
2096 	
2097 	XFormItem.prototype.initFormItem.call(this);
2098 	
2099 	// if we're dealing with an XFormChoices object...
2100 	var choices = this.getChoices();
2101 	if (choices == null || choices.constructor != XFormChoices) return;
2102 
2103 	//	...set up to receive notification when its choices change
2104 	var listener = new AjxListener(this, this.dirtyDisplay);
2105 	choices.addListener(DwtEvent.XFORMS_CHOICES_CHANGED, listener);
2106 
2107     this.signUpForEvents();   //so when the instance value changed, the output display can be updated.
2108 }
2109 
2110 Output_XFormItem.prototype.dirtyDisplay = function () {
2111 	XFormItem.prototype.dirtyDisplay.call(this);
2112 	this._choiceDisplayIsDirty = true;
2113 	delete this.$normalizedChoices;
2114 }
2115 
2116 // set up how disabling works for this item type
2117 Output_XFormItem.prototype.setElementEnabled = XFormItem.prototype.setElementEnabledCssClass;
2118 
2119 
2120 /**
2121  * @class defines XFormItem type _TEXTFIELD_
2122  * @constructor
2123  * 
2124  * @private
2125  */
2126 Textfield_XFormItem = function() {}
2127 XFormItemFactory.createItemType("_TEXTFIELD_", "textfield", Textfield_XFormItem, XFormItem);
2128 // aliases for _TEXTFIELD_:  _INPUT_
2129 XFormItemFactory.registerItemType("_INPUT_", "input", Textfield_XFormItem);
2130 
2131 //	type defaults
2132 //Textfield_XFormItem.prototype.width = 100;
2133 Textfield_XFormItem.prototype._inputType = "text";
2134 Textfield_XFormItem.prototype.cssClass = "xform_field";
2135 Textfield_XFormItem.prototype.elementChangeHandler="onchange";
2136 //Textfield_XFormItem.prototype.onclickHandler="onclick";
2137 Textfield_XFormItem.prototype.focusable = true;
2138 Textfield_XFormItem.prototype.nowrap = false;
2139 Textfield_XFormItem.prototype.labelWrap = true;
2140 Textfield_XFormItem.prototype.containerCssClass = "xform_field_container";
2141 Textfield_XFormItem.prototype.visibilityChecks = [XFormItem.prototype.hasReadPermission];
2142 Textfield_XFormItem.prototype.enableDisableChecks = [XFormItem.prototype.hasWritePermission];
2143 //	methods
2144 Textfield_XFormItem.prototype.outputHTML = function (html,  currentCol) {
2145 	var inputType = this._inputType;
2146 	var value = this.getValue();
2147 	var modelItem = this.getModelItem();
2148 	var inputHelp = this.getInheritedProperty("inputHelp");
2149 
2150 
2151 	/***
2152 //XXX this is probably not the best way to tell if we only want to enter numbers...
2153 	if (modelItem && (modelItem.type == _NUMBER_)) {// || modelItem.type == _COS_NUMBER_)) {
2154 		var keyStrokeHandler = " onkeypress=\""
2155 //			+"',45,46,48,49,50,51,52,53,54,55,56,57,69,101,'.indexOf(','+(event||window.event).keyCode+',') > -1\""		
2156 				+"var code = ','+(event||window.event).which+',';"
2157 				+"var isValidChar = (',45,46,48,49,50,51,52,53,54,55,56,57,69,101,'.indexOf(code) > -1);"
2158 				+"DBG.println(code + ':'+isValidChar);"
2159 				+"event.returnValue = isValidChar;"
2160 				+"return isValidChar;"
2161 				+"\""
2162 	}
2163 	/***/
2164 	html.append( 
2165 			"<input autocomplete='off' id=\"", this.getId(),"\" type=\"", inputType, "\"", this.getCssString(), 
2166 				this.getChangeHandlerHTML(), this.getFocusHandlerHTML(),
2167 				this.getClickHandlerHTML(), this.getMouseoutHandlerHTML(),
2168 				(value != null ? " value=\"" + value + "\"" :""), //: (inputHelp != null ? " value=\"" + inputHelp + "\""
2169 			">");
2170 }
2171 
2172 Textfield_XFormItem.prototype.getClickHandlerHTML =
2173 function () {
2174 	var formId = this.getFormGlobalRef(), 
2175 		itemId = this.getId()
2176 		;
2177 	
2178 	var onClickAction = "";
2179 	
2180 	var onClickFunc = this.getInheritedProperty("onClick") ;
2181 	onClickAction = AjxBuffer.concat(" onclick=\"", onClickFunc || "XFormItem.prototype.showInputTooltip" , 
2182 			".call(" ,   this.getGlobalRef(), ", event );\" ");
2183 			
2184 	return AjxBuffer.concat( onClickAction );	
2185 }
2186 
2187 Textfield_XFormItem.prototype.getMouseoutHandlerHTML =
2188 function () {
2189 	var formId = this.getFormGlobalRef(), 
2190 		itemId = this.getId()
2191 		;
2192 	
2193 	var onMouseoutAction = "";
2194 	
2195 	var onMouseoutFunc = this.getInheritedProperty("onMouseout") ;
2196 	onMouseoutAction = AjxBuffer.concat(" onmouseout=\"", onMouseoutFunc || "XFormItem.prototype.hideInputTooltip" , 
2197 						".call(" ,   this.getGlobalRef(), ", event );\" ");
2198 						
2199 	return AjxBuffer.concat( onMouseoutAction );	
2200 }
2201 
2202 Textfield_XFormItem.prototype.updateElement = function(newValue) {
2203 	if (newValue == null) newValue = this.getValue();
2204 	var inputHelp = this.getInheritedProperty("inputHelp");
2205 	/*
2206 	DBG.println("In updateElement: " + "newValue=" + newValue + "###" + "elementValue=" + this.getElement().value);	*/
2207 	if ((newValue == null) && (inputHelp != null)) {
2208 		 newValue = inputHelp ;
2209 	}else if (newValue == null){
2210 		 newValue = "";
2211 	}
2212 	
2213 	if (this.getElement() && this.getElement().value != newValue) {
2214 		this.getElement().value = newValue;
2215 	}
2216 }
2217 
2218 // set up how disabling works for this item type
2219 Textfield_XFormItem.prototype.setElementEnabled  = function (enabled) {
2220 	if (this.getElement()) {
2221 		this.setElementDisabledProperty(enabled);
2222 		this.setElementEnabledCssClass(enabled);
2223 	}
2224 }
2225 
2226 //Creates a datalist element which specifies a list of pre-defined options for an <input> element providing an autocomplete feature.
2227 Textfield_XFormItem.prototype.createDataList  = function (list) {
2228 	if (!AjxEnv.supported.input.list) {
2229 		return;
2230 	}
2231 	list = list || [];
2232 	var dataListId = this.getId() + "_datalist";
2233 	// If old datalist is already present remove it.
2234 	var oldDataList = Dwt.getElement(dataListId);
2235 	if (oldDataList) {
2236 		oldDataList.parentNode.removeChild(oldDataList);
2237 	}
2238 	var element = this.getElement();
2239 	element.setAttribute("list", dataListId);
2240 	var dataList = document.createElement("datalist");
2241 	dataList.id = dataListId;
2242 	for (var i = 0; i < list.length; i++) {
2243 		var option = document.createElement('option');
2244 		option.value = list[i];
2245 		dataList.appendChild(option);
2246 	}
2247 	element.parentNode.appendChild(dataList);
2248 
2249 	// if there is an onChange handler, call that during on input event
2250 	var onChangeMethod = this.getOnChangeMethod();
2251 	if (typeof onChangeMethod === "function") {
2252 		Dwt.setHandler(element, DwtEvent.ONINPUT, function() {
2253 			onChangeMethod.call(this, this.getElement().value, false, this.getForm());
2254 		}.bind(this));
2255 	}
2256 };
2257 
2258 
2259 /**
2260  * @class defines XFormItem type _SECRET_
2261  * @constructor
2262  * 
2263  * @private
2264  */
2265 Secret_XFormItem = function() {}
2266 XFormItemFactory.createItemType("_SECRET_", "secret", Secret_XFormItem, Textfield_XFormItem);
2267 // alias for the SECRET class:  PASSWORD
2268 XFormItemFactory.registerItemType("_PASSWORD_", "password", Secret_XFormItem);
2269 
2270 
2271 //	type defaults
2272 Secret_XFormItem.prototype._inputType = "password";
2273 Secret_XFormItem.prototype.focusable = true;
2274 
2275 
2276 
2277 
2278 /**
2279  * @class defines XFormItem type _FILE_
2280  * @constructor
2281  * 
2282  * @private
2283  */
2284 File_XFormItem = function() {}
2285 XFormItemFactory.createItemType("_FILE_", "file", File_XFormItem, Textfield_XFormItem)
2286 
2287 //	type defaults
2288 File_XFormItem.prototype._inputType = "file";
2289 File_XFormItem.prototype.forceUpdate = false;
2290 File_XFormItem.prototype.focusable = true;
2291 
2292 
2293 
2294 /**
2295  * @class defines XFormItem type _TEXTAREA_
2296  * @constructor
2297  * 
2298  * @private
2299  */
2300 Textarea_XFormItem = function() {}
2301 XFormItemFactory.createItemType("_TEXTAREA_", "textarea", Textarea_XFormItem, Textfield_XFormItem)
2302 
2303 Textarea_XFormItem.prototype.width = "100%";
2304 Textarea_XFormItem.prototype.height = 100;
2305 Textarea_XFormItem.prototype.focusable = true;
2306 //	methods
2307 Textarea_XFormItem.prototype.outputHTML = function (html,   currentCol) {
2308 	var wrap = this.getInheritedProperty("textWrapping");
2309 	if (!wrap)
2310 		wrap = "off";
2311 		
2312 	html.append( 
2313 		"<textarea id=\"", this.getId(), "\"", this.getCssString(),
2314 				this.getChangeHandlerHTML(), this.getFocusHandlerHTML(), "wrap='", wrap, "'",
2315 		"></textarea>");
2316 }
2317 
2318 // you can use these to 
2319 Textarea_XFormItem.prototype.setElementDisabledProperty = function (enable) {
2320 	this.getElement().disabled = (enable != true);
2321 	this.getElement().readOnly = (enable != true)
2322 }
2323 
2324 Textarea_XFormItem.prototype.getKeyPressHandlerHTML = function () {
2325 
2326         var keydownEv = "onkeydown";
2327         if (AjxEnv.isNav || AjxEnv.isChrome || AjxEnv.isSafari) {
2328                 keydownEv = "onkeypress";
2329         }
2330         return AjxBuffer.concat(" ", keydownEv,"=\"",this.getGlobalRef(), ".handleKeyDown(event, this)\"",
2331                                                    " onkeyup=\"", this.getGlobalRef(), ".handleKeyUp(event, this)\"");
2332 };
2333 
2334 /**
2335  * @class defines XFormItem type _CHECKBOX_
2336  * @constructor
2337  * 
2338  * @private
2339  */
2340 Checkbox_XFormItem = function() {}
2341 XFormItemFactory.createItemType("_CHECKBOX_", "checkbox", Checkbox_XFormItem, XFormItem)
2342  // Wiz_checkbox for appNewUI dialog
2343  Wiz_Checkbox_XFormItem = function() {}
2344 XFormItemFactory.createItemType("_WIZ_CHECKBOX_", "wiz_checkbox", Wiz_Checkbox_XFormItem, Checkbox_XFormItem)
2345 if(appNewUI){
2346    Wiz_Checkbox_XFormItem.prototype.labelLocation = _RIGHT_;
2347    Wiz_Checkbox_XFormItem.prototype.align = _RIGHT_;
2348    Wiz_Checkbox_XFormItem.prototype.subLabel = "";
2349 }
2350 
2351 
2352 //	type defaults
2353 Checkbox_XFormItem.prototype._inputType = "checkbox";
2354 Checkbox_XFormItem.prototype.elementChangeHandler = "onclick";
2355 Checkbox_XFormItem.prototype.labelLocation = (appNewUI?_LEFT_:_RIGHT_);
2356 Checkbox_XFormItem.prototype.cssClass = "xform_checkbox";
2357 Checkbox_XFormItem.prototype.labelCssClass = "xform_checkbox";
2358 Checkbox_XFormItem.prototype.align = (appNewUI?_LEFT_:_RIGHT_);
2359 Checkbox_XFormItem.prototype.trueValue = _UNDEFINED_;		// Don't set in proto so model can override
2360 Checkbox_XFormItem.prototype.falseValue = _UNDEFINED_;
2361 Checkbox_XFormItem.prototype.focusable = true;
2362 Checkbox_XFormItem.prototype.visibilityChecks = [XFormItem.prototype.hasReadPermission];
2363 Checkbox_XFormItem.prototype.enableDisableChecks = [XFormItem.prototype.hasWritePermission];
2364 Checkbox_XFormItem.prototype.nowrap = false;
2365 Checkbox_XFormItem.prototype.labelWrap = true;
2366 //if (appNewUI) {
2367    // Checkbox_XFormItem.prototype.subLabel = ZaMsg.CaptionEnabled;
2368 //}
2369 //	methods
2370 Checkbox_XFormItem.prototype.outputHTML = function (html, currentCol) {
2371 	// figure out how to show the checkbox as checked or not
2372 	var checked = "";
2373 	if (this.getInstanceValue() == this.getTrueValue()) {
2374 		checked = " CHECKED";
2375 	}
2376 	html.append( 
2377 		"<input autocomplete='off' id=\"", this.getId(),"\" type=\"", this._inputType, "\"",  
2378 				this.getChangeHandlerHTML(), this.getFocusHandlerHTML(), checked,
2379 		">");
2380 }
2381 
2382 
2383 Checkbox_XFormItem.prototype.getTrueValue = function () {
2384 	var trueValue = this.getInheritedProperty("trueValue");
2385 	if (trueValue == null) trueValue = true;
2386 	return trueValue;
2387 }
2388 
2389 Checkbox_XFormItem.prototype.getFalseValue = function () {
2390 	var falseValue = this.getInheritedProperty("falseValue");
2391 	if (falseValue == null) falseValue = false;
2392 	return falseValue;
2393 }
2394 
2395 
2396 
2397 Checkbox_XFormItem.prototype.updateElement = function(newValue) {
2398 	newValue = (newValue == this.getTrueValue());
2399 	this.getElement().checked = newValue;
2400 }
2401 
2402 Checkbox_XFormItem.prototype.getElementValueGetterHTML = function () {
2403 	var trueValue = this.getTrueValue();
2404 	if (trueValue !== _UNDEFINED_) {
2405 		if (typeof trueValue == "string") trueValue = "'" + trueValue + "'";
2406 		
2407 		var falseValue = this.getFalseValue();
2408 		if (typeof falseValue == "string") falseValue = "'" + falseValue + "'";
2409 	
2410 		if (trueValue == null) trueValue = true;
2411 		if (falseValue == null) falseValue = false;
2412 	
2413 		return AjxBuffer.concat(
2414 			"var value = (this.checked ? ",  trueValue, " : ", falseValue, ");"
2415 		);
2416 	} else {
2417 		return "var value = '"+this.getValue()+"';";
2418 	}
2419 }
2420 
2421 
2422 if (appNewUI) {  //   bug66133,for some particular places, subLabel need
2423     Checkbox_XFormItem.prototype.outputContainerTDEndHTML = function (html) {
2424         var tdLabel = this.getInheritedProperty("subLabel");
2425         if (AjxUtil.isEmpty(tdLabel)) {
2426             tdLabel = "";
2427         } else {
2428             tdLabel = " " + tdLabel;
2429         }
2430 
2431         html.append(tdLabel + "</td id=\"",  this.getId(), "___container\">");
2432     }
2433 }
2434 // set up how disabling works for this item type
2435 //	XXXX eventually we want to disable our label as well...
2436 Checkbox_XFormItem.prototype.setElementEnabled = XFormItem.prototype.setElementDisabledProperty;
2437 
2438 
2439 
2440 /**
2441  * @class defines XFormItem type _RADIO_
2442  * @constructor
2443  * 
2444  * @private
2445  */
2446 Radio_XFormItem = function() {}
2447 XFormItemFactory.createItemType("_RADIO_", "radio", Radio_XFormItem, Checkbox_XFormItem)
2448 
2449 //	type defaults
2450 Radio_XFormItem.prototype._inputType = "radio";
2451 Radio_XFormItem.prototype.focusable = true;
2452 Radio_XFormItem.prototype.groupname=null;
2453 Radio_XFormItem.prototype.subLabel = (appNewUI?"":null);
2454 Radio_XFormItem.prototype.align = _RIGHT_;
2455 Radio_XFormItem.prototype.labelLocation = _RIGHT_;
2456 //	methods
2457 
2458 Radio_XFormItem.prototype.updateElement = function(newValue) {
2459 	this.getElement().checked = (this.getValue() == newValue);
2460 }
2461 
2462 //	methods
2463 Radio_XFormItem.prototype.outputHTML = function (html,  currentCol) {
2464 	// figure out how to show the checkbox as checked or not
2465 	var checked = "";
2466 	if (this.getInstanceValue() == this.getTrueValue()) {
2467 		checked = " CHECKED";
2468 	}
2469 	html.append( 
2470 		"<input autocomplete='off' id=\"", this.getId(),"\" type=\"", this._inputType, "\"",  
2471 				this.getChangeHandlerHTML(), this.getFocusHandlerHTML(), checked);
2472 	var groupname = this.getInheritedProperty("groupname");
2473 	if(groupname) {
2474 			html.append(" name='",groupname,"'");
2475 	}
2476 	html.append(">");
2477 }
2478 
2479 /**
2480  * @class defines XFormItem type _RADIO_LABEL_
2481  * @constructor
2482  * 
2483  * @private
2484  */
2485 Radio_Label_XFormItem = function() {}
2486 XFormItemFactory.createItemType("_RADIO_LABEL_", "radio_label", Radio_Label_XFormItem, Radio_XFormItem)
2487 
2488 //	type defaults
2489 Radio_Label_XFormItem.prototype._inputType = "radio";
2490 Radio_Label_XFormItem.prototype.focusable = true;
2491 Radio_Label_XFormItem.prototype.groupname=null;
2492 //	methods
2493 
2494 Radio_XFormItem.prototype.elementChanged = function(elementValue, instanceValue, event) {
2495 	if(elementValue==true) {
2496 		//this.setInstanceValue(this.getValue());
2497 		this.getForm().itemChanged(this.getId(), this.getValue(), event);
2498 	}	
2499 }
2500 
2501 Radio_XFormItem.prototype.updateElement = function(newValue) {
2502 	this.getElement().checked = (this.getValue() == newValue);
2503 	var labelEl = XFG.getEl((this.getId()+"___labelValue"));
2504 	if(labelEl) {
2505 		var labelRef = this.getInheritedProperty("labelRef");
2506 		if (labelRef == null) 
2507 			return;
2508 		var label = this.getInstanceValue(labelRef);	
2509 		labelEl.innerHTML = label;
2510 	}
2511 }
2512 
2513 //	methods
2514 Radio_Label_XFormItem.prototype.outputHTML = function (html,  currentCol) {
2515 	// figure out how to show the checkbox as checked or not
2516 	var checked = "";
2517 	if (this.getInstanceValue() == this.getTrueValue()) {
2518 		checked = " CHECKED";
2519 	}
2520 	html.append( 
2521 		"<input autocomplete='off' id=\"", this.getId(),"\" type=\"", this._inputType, "\"",  
2522 				this.getChangeHandlerHTML(), this.getFocusHandlerHTML(), checked);
2523 	var groupname = this.getInheritedProperty("groupname");
2524 	if(groupname) {
2525 			html.append(" name='",groupname,"'");
2526 	}
2527 	html.append(">");
2528 }
2529 
2530 Radio_Label_XFormItem.prototype.outputLabelCellHTML = function (html,  rowSpan, labelLocation) {
2531 	var labelRef = this.getInheritedProperty("labelRef");
2532 	if (labelRef == null) return;
2533 	var label = this.getInstanceValue(labelRef);
2534 	if (label == null) return;
2535 	if (label == "") label = " ";
2536 	var accessKey = this.getInheritedProperty("labelValue");
2537 	if (labelLocation == _INLINE_) {
2538 		var style = this.getLabelCssStyle();
2539 		if (style == null) style = "";
2540 		style = "position:relative;left:10;top:5;text-align:left;background-color:#eeeeee;margin-left:5px;margin-right:5px;" + style;
2541 		html.append( "<label id=\"", this.getId(),"___labelValue\"", 
2542 								this.getLabelCssString(null, style), " FOR=\"",this.getId(), "\">",
2543 								label,
2544 							"</label>"
2545 					);
2546 	} else {
2547 		html.append( "<td ", this.getLabelCssString(), (rowSpan > 1 ? " rowspan=" + rowSpan : ""), ">",	
2548 		"<label id=\"", this.getId(),"___labelValue\"", " FOR=\"",this.getId(), "\">",
2549 		label,"</label>");
2550 		html.append("</td>");
2551 	}
2552 
2553 }
2554 
2555 /**
2556  * @class defines XFormItem type _BUTTON_
2557  * this item is a simple HTML <button> element
2558  * @constructor
2559  * 
2560  * @private
2561  */
2562 Button_XFormItem = function() {}
2563 XFormItemFactory.createItemType("_BUTTON_", "button", Button_XFormItem, XFormItem);
2564 XFormItemFactory.registerItemType("_TRIGGER_", "trigger", Button_XFormItem);
2565 //	type defaults
2566 Button_XFormItem.prototype.forceUpdate = false;
2567 Button_XFormItem.prototype.elementChangeHandler = "onclick";
2568 Button_XFormItem.prototype.labelLocation = _NONE_;
2569 Button_XFormItem.prototype.relevantBehavior = _DISABLE_;
2570 Button_XFormItem.prototype.cssClass = "xform_button";
2571 Button_XFormItem.prototype.focusable = true;
2572 // 	methods
2573 Button_XFormItem.prototype.outputHTML = function (html,  currentCol) {
2574 	// write the div to hold the value (will be filled in on update)
2575 	html.append(
2576 		"<button id=\"", this.getId(), "\"", this.getCssString(),
2577 			"\r  ", this.getOnActivateHandlerHTML(), 
2578 			"\r  ", this.getFocusHandlerHTML(),
2579 		"\r",">", 
2580 			this.getLabel(),
2581 		"</button>");
2582 }
2583 
2584 // set up how disabling works for this item type
2585 Button_XFormItem.prototype.setElementEnabled = XFormItem.prototype.setElementDisabledProperty;
2586 
2587 
2588 
2589 /**
2590  * @class defines XFormItem type _SUBMIT_
2591  * this item is a simple HTML <input type="submit"> element
2592  * @constructor
2593  * 
2594  * @private
2595  */
2596 Submit_XFormItem = function() {}
2597 XFormItemFactory.createItemType("_SUBMIT_", "submit", Submit_XFormItem, Button_XFormItem)
2598 
2599 
2600 //	methods
2601 Submit_XFormItem.prototype.outputHTML = function (html,   currentCol) {
2602 	// write the div to hold the value (will be filled in on update)
2603 	html.append(
2604 		"<input id=\"", this.getId(), "\" type=\"submit\"", this.getCssString(),
2605 			this.getChangeHandlerHTML(), this.getFocusHandlerHTML(),
2606 		" value=\"", this.getLabel(), ">"
2607 	);
2608 }
2609 
2610 
2611 
2612 
2613 
2614 
2615 /**
2616  * @class defines XFormItem type _ANCHOR_
2617  * this item is an HTML <a> element
2618  * @constructor
2619  * 
2620  * @private
2621  */
2622 Anchor_XFormItem = function() {}
2623 XFormItemFactory.createItemType("_ANCHOR_", "anchor", Anchor_XFormItem, XFormItem)
2624 
2625 //	type defaults
2626 Anchor_XFormItem.prototype.writeElementDiv = true;
2627 Anchor_XFormItem.prototype.forceUpdate = true;
2628 Anchor_XFormItem.prototype.cssClass = "xform_anchor";
2629 Anchor_XFormItem.prototype.elementChangeHandler = "onclick";
2630 Anchor_XFormItem.prototype.href = "javascript:;";
2631 Anchor_XFormItem.prototype.showInNewWindow = true;
2632 Anchor_XFormItem.prototype.focusable = true;
2633 
2634 Anchor_XFormItem.prototype.getHref = function () {
2635 	return this.getInheritedProperty("href");
2636 }
2637 
2638 //	type defaults
2639 
2640 
2641 Anchor_XFormItem.prototype.getAnchorTag = function(href, label) {
2642 	if (href == null) href = this.getHref();
2643 	if (label == null) label = this.getLabel();
2644 	
2645 	var inNewWindow = this.getShowInNewWindow();
2646 	return AjxBuffer.concat(
2647 			'<a href=', href, 
2648 				this.getOnActivateHandlerHTML(), 
2649 				(inNewWindow ? ' target="_blank"' : ''),
2650 			'>',
2651 				label,
2652 			'</a>');
2653 }
2654 
2655 //	methods
2656 Anchor_XFormItem.prototype.outputHTML = function (html) {
2657 	html.append(this.getAnchorTag());
2658 }
2659 
2660 
2661 Anchor_XFormItem.prototype.updateElement = function (value) {
2662 	this.getElement().innerHTML = this.getAnchorTag(value);
2663 }
2664 
2665 
2666 // set up how disabling works for this item type
2667 Anchor_XFormItem.prototype.setElementEnabled = XFormItem.prototype.setElementEnabledCssClass;
2668 
2669 
2670 
2671 
2672 /**
2673  * @class defines XFormItem type _DATA_ANCHOR_
2674  * this item is an HTML <a> element
2675  * @constructor
2676  * 
2677  * @private
2678  */
2679 Data_Anchor_XFormItem = function() {}
2680 XFormItemFactory.createItemType("_DATA_ANCHOR_", "data_anchor", Data_Anchor_XFormItem, Anchor_XFormItem)
2681 
2682 
2683 Data_Anchor_XFormItem.prototype.updateElement = function (value) {
2684 	this.getElement().innerHTML = this.getAnchorTag(null, value);
2685 }
2686 
2687 
2688 
2689 
2690 /**
2691  * @class defines XFormItem type _URL_
2692  * @constructor
2693  * 
2694  * @private
2695  */
2696 Url_XFormItem = function() {}
2697 XFormItemFactory.createItemType("_URL_", "url", Url_XFormItem, Anchor_XFormItem)
2698 
2699 
2700 Url_XFormItem.prototype.updateElement = function (value) {
2701 	this.getElement().innerHTML = this.getAnchorTag(value, value);
2702 }
2703 
2704 /**
2705  * @class defines XFormItem type _DATA_URL_
2706  * @constructor
2707  * @private
2708  */
2709 DataUrl_XFormItem = function() {}
2710 XFormItemFactory.createItemType("_DATA_URL_", "rata_url", DataUrl_XFormItem, Anchor_XFormItem)
2711 
2712 Url_XFormItem.prototype.updateElement = function (value) {
2713 	this.getElement().innerHTML = this.getAnchorTag(value, null);
2714 }
2715 
2716 
2717 
2718 /**
2719  * @class defines XFormItem type _MAILTO_
2720  * this item is an _ANCHOR_ element with "mailto:" link
2721  * @constructor
2722  * 
2723  * @private
2724  */
2725 Mailto_XFormItem = function() {}
2726 XFormItemFactory.createItemType("_MAILTO_", "mailto", Mailto_XFormItem, Anchor_XFormItem)
2727 Mailto_XFormItem.prototype.updateElement = function (value) {
2728 	this.getElement().innerHTML = this.getAnchorTag("mailto:"+value, value);
2729 }
2730 
2731 
2732 
2733 
2734 /**
2735  * @class defines XFormItem type _IMAGE_
2736  * @constructor
2737  * 
2738  * @private
2739  */
2740 Image_XFormItem = function() {}
2741 XFormItemFactory.createItemType("_IMAGE_", "image", Image_XFormItem, XFormItem)
2742 
2743 
2744 //	type defaults
2745 Image_XFormItem.prototype.forceUpdate = true;
2746 Image_XFormItem.prototype.src = _UNDEFINED_;
2747 Image_XFormItem.prototype.srcPath = _UNDEFINED_;;
2748 Image_XFormItem.prototype.writeElementDiv = true;
2749 
2750 
2751 //	methods
2752 Image_XFormItem.prototype.updateElement = function (src) {
2753 	if (src == null) src = this.getSrc();
2754 	
2755 	// dereference through the choices array, if provided
2756 	src = this.getChoiceLabel(src);
2757 
2758 	// if we didn't get an image name, output nothing (?)
2759 	if (src == null || src == "") {
2760 		var output = "";
2761 	} else {
2762 		// prepend the image path
2763 		var path = this.getSrcPath();
2764 		if (path != null) src = path + src;
2765 
2766 		var output = AjxBuffer.concat(
2767 			"<img id=\"", this.getId(), "\" border=0 ", this.getCssString(),
2768 				" src=\"", src, "\"",
2769 			">"
2770 		);
2771 	}
2772 	this.getElement().innerHTML = output;
2773 }
2774 
2775 
2776 // set up how disabling works for this item type
2777 Image_XFormItem.prototype.setElementEnabled = XFormItem.prototype.setElementEnabledCssClass;
2778 
2779 
2780 
2781 // Ajx_Image
2782 Ajx_Image_XFormItem = function() {}
2783 XFormItemFactory.createItemType("_AJX_IMAGE_", "ajx_image", Ajx_Image_XFormItem, XFormItem);
2784 
2785 
2786 //	type defaults
2787 Ajx_Image_XFormItem.prototype.forceUpdate = true;
2788 Ajx_Image_XFormItem.prototype.src = _UNDEFINED_;
2789 Ajx_Image_XFormItem.prototype.srcPath = _UNDEFINED_;;
2790 Ajx_Image_XFormItem.prototype.writeElementDiv = false;
2791 
2792 // //	methods
2793 Ajx_Image_XFormItem.prototype.updateElement = function (src) {
2794 	if (src == null) src = this.getSrc();
2795 
2796  	// dereference through the choices array, if provided
2797  	src = this.getChoiceLabel(src);
2798 	var output;
2799  	// if we didn't get an image name, output nothing (?)
2800  	if (src == null || src == "") {
2801  		output = "";
2802  	} else {
2803  		// prepend the image path
2804  		var path = this.getSrcPath();
2805  		if (path != null) src = path + src;
2806  		var style = this.getCssStyle();
2807 		output = AjxImg.getImageHtml(src, "position:relative;" + (style ? style : '' ));
2808  	}
2809  	if (this.getContainer()) this.getContainer().innerHTML = output;
2810 };
2811 
2812 
2813 // Dwt_Image
2814 Dwt_Image_XFormItem = function() {}
2815 XFormItemFactory.createItemType("_DWT_IMAGE_", "dwt_image", Dwt_Image_XFormItem, XFormItem);
2816 
2817 
2818 //	type defaults
2819 Dwt_Image_XFormItem.prototype.forceUpdate = true;
2820 Dwt_Image_XFormItem.prototype.src = _UNDEFINED_;
2821 Dwt_Image_XFormItem.prototype.srcPath = _UNDEFINED_;;
2822 Dwt_Image_XFormItem.prototype.writeElementDiv = false;
2823 
2824 // //	methods
2825 Dwt_Image_XFormItem.prototype.updateElement = function (src) {
2826 	if (src == null) src = this.getSrc();
2827 
2828  	// dereference through the choices array, if provided
2829  	src = this.getChoiceLabel(src);
2830 	var output;
2831  	// if we didn't get an image name, output nothing (?)
2832  	if (src == null || src == "") {
2833  		output = "";
2834  	} else {
2835  		// prepend the image path
2836  		var path = this.getSrcPath();
2837  		if (path != null) src = path + src;
2838  		var style = this.getCssStyle();
2839 		style = style || "";
2840 		var styleStr = "style='position:relative;"+ style + "'";
2841 
2842 		if (src) {
2843 			output = ["<div class='", src, "' ", styleStr, this.getClickHandlerHTML(), " ></div>"].join("");
2844 		} else {
2845 			output = ["<div ", styleStr, this.getClickHandlerHTML(), " ></div>"].join("");
2846 		}
2847  	}
2848  	this.getContainer().innerHTML = output;
2849 };
2850 
2851 /**
2852  * @class defines XFormItem type _SELECT1_
2853  * this item is rendered as HTML <select> element
2854  * @constructor
2855  * 
2856  * @private
2857  */
2858 Select1_XFormItem = function() {}
2859 XFormItemFactory.createItemType("_SELECT1_", "select1", Select1_XFormItem, XFormItem)
2860 
2861 //	type defaults
2862 Select1_XFormItem.prototype.multiple = false;
2863 Select1_XFormItem.prototype.alwaysUpdateChoices = false;
2864 Select1_XFormItem.prototype.focusable = true;
2865 Select1_XFormItem.prototype.cssClass = "xform_select1";
2866 Select1_XFormItem.prototype.containerCssClass = "xform_select_container";
2867 Select1_XFormItem.prototype.visibilityChecks = [XFormItem.prototype.hasReadPermission];
2868 Select1_XFormItem.prototype.enableDisableChecks = [XFormItem.prototype.hasWritePermission];
2869 //	methods
2870 Select1_XFormItem.prototype.initFormItem = function () {
2871 	// if we're dealing with an XFormChoices object...
2872 	var choices = this.getChoices();
2873 	if (choices == null || choices.constructor != XFormChoices) return;
2874 
2875 	//	...set up to receive notification when its choices change
2876 	var listener = new AjxListener(this, this.dirtyDisplay);
2877 	choices.addListener(DwtEvent.XFORMS_CHOICES_CHANGED, listener);
2878 }
2879 
2880 
2881 Select1_XFormItem.prototype.outputHTML = function (html,  currentCol) {
2882 	html.append( 
2883 		"<select id=\"", this.getId(), "\" ", this.getCssString(), 
2884 			(this.getMultiple() ? "multiple " : ""), 
2885 			this.getChangeHandlerHTML(), this.getFocusHandlerHTML(),
2886 		">",
2887 			this.getChoicesHTML(),
2888 		"</select>"
2889 		);
2890 	this.cleanChoiceDisplay();
2891 }
2892 
2893 Select1_XFormItem.prototype.getElementValueGetterHTML = function () {
2894 	return "var value = XFormItem.getValueFromHTMLSelect(this);";
2895 }
2896 
2897 
2898 
2899 Select1_XFormItem.prototype.setChoices = function(newChoices) {
2900 	this.choices = newChoices;
2901 	this.dirtyDisplay();
2902 	this.updateChoicesHTML();
2903 }
2904 
2905 Select1_XFormItem.prototype.dirtyDisplay = function () {
2906 	XFormItem.prototype.dirtyDisplay.call(this);
2907 	this._choiceDisplayIsDirty = true;
2908 	delete this.$normalizedChoices;
2909 }
2910 
2911 Select1_XFormItem.prototype.updateElement = function (newValue) {
2912 	if (this.choicesAreDirty()) this.updateChoicesHTML();
2913 	this.updateValueInHTMLSelect1(newValue, this.getElement(), this.getSelectionIsOpen());
2914 }
2915 
2916 
2917 Select1_XFormItem.prototype.cleanChoiceDisplay = function () {
2918 	this._choiceDisplayIsDirty = false;
2919 }
2920 
2921 // set up how disabling works for this item type
2922 Select1_XFormItem.prototype.setElementEnabled = XFormItem.prototype.setElementDisabledProperty;
2923 
2924 
2925 
2926 /**
2927  * @class defines XFormItem type _SELECT_
2928  * this item is rendered as HTML <select> element
2929  * @constructor
2930  * 
2931  * @private
2932  */
2933 Select_XFormItem = function() {}
2934 XFormItemFactory.createItemType("_SELECT_", "select", Select_XFormItem, Select1_XFormItem)
2935 
2936 //	type defaults
2937 Select_XFormItem.prototype.multiple = true;
2938 Select_XFormItem.prototype.selection = _OPEN_;
2939 Select_XFormItem.prototype.focusable = true;
2940 Select_XFormItem.prototype.containerCssClass = "xform_select_container";
2941 
2942 //	methods
2943 
2944 Select_XFormItem.prototype.updateElement = function (newValue) {
2945 	if (this.choicesAreDirty()) this.updateChoicesHTML();
2946 	this.updateValueInHTMLSelect(newValue, this.getElement(), this.getSelectionIsOpen());
2947 }
2948 
2949 
2950 
2951 /**
2952  * @class defines XFormItem type _SPACER_
2953  * Use to output an entire row spacer
2954  * @constructor
2955  * 
2956  * @private
2957  */
2958 Spacer_XFormItem = function() {}
2959 XFormItemFactory.createItemType("_SPACER_", "spacer", Spacer_XFormItem, XFormItem)
2960 
2961 //	type defaults
2962 Spacer_XFormItem.prototype.forceUpdate = false;
2963 Spacer_XFormItem.prototype.labelLocation = _NONE_;
2964 Spacer_XFormItem.prototype.width = 1;
2965 Spacer_XFormItem.prototype.height = 10;
2966 Spacer_XFormItem.prototype.cssStyle = "font-size:1px;overflow:hidden;";
2967 Spacer_XFormItem.prototype.colSpan = "*";
2968 Spacer_XFormItem.prototype.focusable = false;
2969 
2970 // 	methods
2971 Spacer_XFormItem.prototype.outputHTML = function (html,   currentCol) {
2972 	html.append( "<div id=", this.getId(), this.getCssString(),"></div>");
2973 }
2974 
2975 // set up how disabling works for this item type
2976 Spacer_XFormItem.prototype.setElementEnabled = XFormItem.prototype.setElementEnabledCssClass;
2977 
2978 /**
2979  * @class defines XFormItem type _CELL_SPACER_
2980  * Use to output a single cell of space
2981  * @constructor
2982  * 
2983  * @private
2984  */
2985 Cell_Spacer_XFormItem = function() {}
2986 XFormItemFactory.createItemType("_CELL_SPACER_", "cell_spacer", Cell_Spacer_XFormItem, Spacer_XFormItem)
2987 XFormItemFactory.registerItemType("_CELLSPACER_", "cell_spacer", Cell_Spacer_XFormItem);
2988 Cell_Spacer_XFormItem.prototype.width = 10;
2989 Cell_Spacer_XFormItem.prototype.height = 10;
2990 Cell_Spacer_XFormItem.prototype.colSpan = 1;
2991 Cell_Spacer_XFormItem.prototype.focusable = false;
2992 
2993 /**
2994  * @class defines XFormItem type _SEPARATOR_
2995  * @constructor
2996  * 
2997  * @private
2998  */
2999 Separator_XFormItem = function() {}
3000 XFormItemFactory.createItemType("_SEPARATOR_", "separator", Separator_XFormItem, XFormItem)
3001 
3002 //	type defaults
3003 Separator_XFormItem.prototype.cssClass = "xform_separator";
3004 Separator_XFormItem.prototype.colSpan = "*";
3005 Separator_XFormItem.prototype.align = _CENTER_;
3006 Separator_XFormItem.prototype.valign = _CENTER_;
3007 Separator_XFormItem.prototype.height = 10;
3008 Separator_XFormItem.prototype.focusable = false;
3009 
3010 // methods
3011 Separator_XFormItem.prototype.outputHTML = function (html,  currentCol) {
3012 	var css = (this.getCssClass() || '');
3013 	if (css != '' && css != null) css = " class=\"" + css + "\"";
3014 	
3015 	html.append( 
3016 			"<table width=100% cellspacing=0 cellpadding=0>",
3017 				"<tr><td height=",this.getHeight(),">",
3018 					"<div ", css,"></div>",
3019 			"</td></tr></table>"
3020 	);
3021 }
3022 
3023 
3024 // set up how disabling works for this item type
3025 Separator_XFormItem.prototype.setElementEnabled = XFormItem.prototype.setElementEnabledCssClass;
3026 
3027 
3028 
3029 
3030 
3031 
3032 
3033 /**
3034  * @class defines XFormItem type _GROUP_
3035  * @constructor
3036  * 
3037  * @private
3038  */
3039 Group_XFormItem = function() {
3040 	this.tabIdOrder = [];
3041 }
3042 XFormItemFactory.createItemType("_GROUP_", "group", Group_XFormItem, XFormItem)
3043 
3044 //	type defaults
3045 Group_XFormItem.prototype.forceUpdate = false;
3046 Group_XFormItem.prototype.numCols = 2;
3047 Group_XFormItem.prototype.useParentTable = false;
3048 Group_XFormItem.prototype.focusable = false;
3049 Group_XFormItem.prototype.cellspacing = 0;
3050 Group_XFormItem.prototype.border = 0;
3051 Group_XFormItem.prototype.cellpadding = 0;
3052 if(appNewUI){
3053 Group_XFormItem.prototype.tableCssClass = "grid_xform_table";
3054 }
3055 Group_XFormItem.prototype.initFormItem = function () {
3056 	XFormItem.prototype.initFormItem.call(this);	
3057 	if(this.getInheritedProperty("isTabGroup")) {
3058 		var form = this.getForm();
3059 		form.tabIdOrder[this.getId()] = this.tabIdOrder;
3060 		form.addTabGroup(this);
3061 	}
3062 
3063 }
3064 
3065 Group_XFormItem.prototype.outputHTML = function (html,  currentCol) {
3066 	this.getForm().outputItemList(this.getItems(), this, html,   this.getNumCols(), currentCol);
3067 }
3068 
3069 Group_XFormItem.prototype.clearError = function() {
3070 	var errLoc = this.getErrorLocation();
3071 	if (errLoc == _PARENT_ || errLoc == _INHERIT_){
3072 		this.getParentItem().clearError();
3073 		return;
3074 	}
3075 
3076 	this.getForm().removeErrorItem(this);
3077 	if(this.items) {
3078 		var cnt = this.items.length;
3079 		for(var i = 0; i < cnt; i++) {
3080 			if(this.items[i].getErrorLocation() != _PARENT_ &&  this.items[i].getErrorLocation() != _INHERIT_)
3081 				this.items[i].clearError();
3082 		}
3083 	}
3084 	this.__errorState = XFormItem.ERROR_STATE_VALID;
3085 	this.removeErrorContainer();
3086 };
3087 
3088 Group_XFormItem.prototype.setElementEnabled  =  function (enable) {
3089 		
3090 }
3091 
3092 Group_XFormItem.prototype.updateVisibility = function () {
3093 	var isVisible = true;
3094 	
3095 	//check if the parent element is visible
3096 	var parentItem = this.getParentItem();
3097 	if(parentItem)
3098 		isVisible=this.getParentItem().getIsVisible();
3099 	
3100 	//run stack of visibility checks until encounter a negative result
3101 	if(isVisible) {
3102 		var myVisibilityChecks = this.getInheritedProperty("visibilityChecks");
3103 		if(myVisibilityChecks && myVisibilityChecks instanceof Array) {
3104 			var cnt = myVisibilityChecks.length;
3105 			for(var i=0;i<cnt;i++) {
3106 				if(myVisibilityChecks[i] != null) {
3107 					if(typeof(myVisibilityChecks[i])=="function") {
3108 						isVisible = myVisibilityChecks[i].call(this);
3109 						if(!isVisible)
3110 							break;
3111 					} else if (myVisibilityChecks[i] instanceof Array) {
3112 						//first element is a func reference, the rest of elements are arguments
3113 						var func = myVisibilityChecks[i].shift();
3114 						isVisible = func.apply(this, myVisibilityChecks[i]);
3115 						myVisibilityChecks[i].unshift(func);
3116 						if(!isVisible)
3117 							break;
3118 					} else if (typeof (myVisibilityChecks[i]) == "string") {
3119                         //for relevant backward compatibility
3120                         var instance = this.getInstance();
3121                         isVisible = eval(myVisibilityChecks[i]) ;
3122                         if(!isVisible)
3123 							break;
3124                     }
3125 				}
3126 			}
3127 		}
3128 	}	
3129 	var reRunRefresh = false;	
3130 	if(isVisible) {
3131 		if(this.deferred)
3132 			reRunRefresh=true;
3133 			
3134 		this.show();
3135 	} else
3136 		this.hide();
3137 	
3138 	//update visibility for active child items
3139 	if(isVisible) {
3140 		for(var itemId in this.activeChildren) {
3141 			if(this.activeChildren[itemId]===true) {
3142 				var item = this.getForm().getItemById(itemId);
3143 				if(item && this.getInstance()) {
3144 					var updateMethod = item.getUpdateVisibilityMethod();				
3145 					if(updateMethod) {
3146 						updateMethod.call(item);
3147 					}
3148 				}
3149 			}
3150 		}
3151 	}
3152 	if(reRunRefresh) {
3153 		this.updateEnabledDisabled();
3154 		this.updateElement();
3155 	}	
3156 }
3157 
3158 
3159 
3160 Step_Choices_XFormItem = function() {}
3161 XFormItemFactory.createItemType("_STEPCHOICE_", "stepchoices", Step_Choices_XFormItem, Group_XFormItem);
3162 
3163 Step_Choices_XFormItem.prototype.numCols = 1;
3164 Step_Choices_XFormItem.prototype.labelVisibility = _UNDEFINED_;
3165 Step_Choices_XFormItem.prototype.labelUpdateMethod = function(newValue) {
3166     var el = this.getElement();
3167     var sourceValue =  this.getInheritedProperty("sourceValue");
3168     if (sourceValue < newValue) {
3169         el.className = "AdminOutputTabClick";
3170     } else if (sourceValue == newValue) {
3171         el.className =  "AdminOutputTabSelect";
3172     } else {
3173         el.className = "AdminOutputTab";
3174     }
3175 }
3176 
3177 Step_Choices_XFormItem.prototype.getLabelUpdateMethod = function() {
3178     return this.cacheInheritedMethod("labelUpdateMethod", "$labelUpdateMethod", "newValue");
3179 }
3180 
3181 Step_Choices_XFormItem.prototype.labelClickMethod = function(event) {
3182     var sourceValue =  this.getInheritedProperty("sourceValue");
3183     var instanceValue = this.getInstanceValue();
3184     if (sourceValue < instanceValue) {
3185         this.setInstanceValue(sourceValue);
3186     }
3187 }
3188 
3189 Step_Choices_XFormItem.prototype.getLabelClickMethod = function() {
3190     return this.cacheInheritedMethod("labelClickMethod", "$labelClickMethod", "event");
3191 }
3192 
3193 Step_Choices_XFormItem.prototype.initFormItem = function() {
3194     var choices = this.getNormalizedChoices();
3195     if (!choices)
3196         return;
3197 
3198 	XFormItem.prototype.initFormItem.call(this);
3199 
3200     this.signUpForEvents();
3201     var labels = choices.labels;
3202     var values =choices.values;
3203 
3204     this.items = [];
3205     var currentItem;
3206     var labelUpdateMethod = this.getLabelUpdateMethod();
3207     var labelVisibility = this.getInheritedProperty ("labelVisibility");
3208     var labelOnClickMethod = this.getLabelClickMethod();
3209     for (var i = 0; i < labels.length; i++) {
3210         if (labelVisibility && labelVisibility[values[i]]) {
3211             currentItem = {ref: ".", type:_OUTPUT_,
3212                 value:labels[i], sourceValue: values[i],
3213                 updateElement: labelUpdateMethod,
3214                 visibilityChecks: labelVisibility[values[i]].checks,
3215                 visibilityChangeEventSources:labelVisibility[values[i]].sources
3216             };
3217         } else {
3218             currentItem = {ref: ".", type:_OUTPUT_,
3219                 value:labels[i], sourceValue: values[i],
3220                 updateElement: labelUpdateMethod
3221             };
3222         }
3223 
3224         if (labelOnClickMethod) {
3225             currentItem.onClick = labelOnClickMethod;
3226         }
3227         this.items.push(currentItem);
3228     }
3229 }
3230  /*
3231 Step_Choices_XFormItem.prototype.updateElement = function (newValue) {
3232     var items = this.getItems();
3233     var el;
3234     for ( var i = 0; i < items.length; i++) {
3235         el = items[i].getElement();
3236         if (items[i].getInheritedProperty("sourceValue") == newValue) {
3237             Dwt.addClass(el, "AdminOutputTabSelect");
3238             Dwt.delClass(el, "AdminOutputTab");
3239         } else {
3240             Dwt.delClass(el, "AdminOutputTabSelect");
3241             Dwt.addClass(el, "AdminOutputTab");
3242         }
3243     }
3244 }
3245 */
3246 
3247 
3248 HomeGroup_XFormItem = function() {
3249     this.expanded = true;
3250 }
3251 XFormItemFactory.createItemType("_HOMEGROUP_", "homegroup", HomeGroup_XFormItem, Group_XFormItem)
3252 
3253 //	type defaults
3254 HomeGroup_XFormItem.prototype.headCss = "homeGroupHeader";
3255 HomeGroup_XFormItem.prototype.bodyCss = "homeGroupBody";
3256 HomeGroup_XFormItem.prototype.numCols = 1;
3257 HomeGroup_XFormItem.prototype.width = "90%";
3258 HomeGroup_XFormItem.prototype.cssStyle = "margin-left:5%; margin-top: 10px;";
3259 HomeGroup_XFormItem.prototype.headerLabel = "Home Group";
3260 HomeGroup_XFormItem.prototype.expandedImg =  "ImgNodeExpanded";
3261 HomeGroup_XFormItem.prototype.collapsedImg =  "ImgNodeCollapsed";
3262 HomeGroup_XFormItem.prototype.initializeItems = function () {
3263     this.items = [];
3264     this.items[0] = this.getHeaderItems();
3265     this.items[1] = this.getContentItems();
3266     var content = this.items[1].items;
3267     var choices = this.getInheritedProperty("contentChoices");
3268     if (!choices[0].label)
3269         this.items[1].numCols = 1;
3270     for (var i = 0; i < choices.length; i ++) {
3271         var currentItem = {type:_OUTPUT_, label: choices[i].label,
3272                         value: choices[i].value, containerCssStyle:"color:blue;cursor:pointer"};
3273         if (choices[i].onClick) {
3274             currentItem.onClick = choices[i].onClick;
3275         }
3276         content.push(currentItem);
3277     }
3278     Group_XFormItem.prototype.initializeItems.call(this);
3279 }
3280 
3281 HomeGroup_XFormItem.prototype.onClick = function(ev) {
3282     var homeItem = this.getParentItem().getParentItem();
3283     var contentContainer = homeItem.items[1];
3284     if (homeItem.expanded) {
3285         homeItem.expanded = false;
3286         this.updateElement(homeItem.collapsedImg);
3287         contentContainer.hide();
3288     } else {
3289         homeItem.expanded = true;
3290         this.updateElement(homeItem.expandedImg);
3291         contentContainer.show();
3292     }
3293 }
3294 
3295 HomeGroup_XFormItem.prototype.getHeaderItems =
3296 function () {
3297     var headerLabel = this.getInheritedProperty("headerLabel");
3298     var headerCss = this.getInheritedProperty("headCss");
3299     var headerItems = { type:_COMPOSITE_, numCols:3, width:"100%",
3300             colSizes:["20px", "100%", "20px"],
3301             items:[
3302                 {type:_DWT_IMAGE_, value: this.expandedImg, cssStyle:"position:static;", onClick:this.onClick},
3303                 {type:_OUTPUT_, value: headerLabel},
3304                 {type:_AJX_IMAGE_, value: "BorderNone"}
3305             ],
3306             cssClass:headerCss
3307         };
3308     return headerItems;
3309 }
3310 
3311 HomeGroup_XFormItem.prototype.getContentItems =
3312 function () {
3313     var bodyCss = this.getInheritedProperty("bodyCss");
3314     var contentItems = { type:_GROUP_, items:[], cssClass:bodyCss
3315     };
3316     contentItems.items = [];
3317     return contentItems;
3318 }
3319 
3320 CollapsedGroup_XFormItem = function() {
3321     this.expanded = true;
3322 }
3323 XFormItemFactory.createItemType("_COLLAPSED_GROUP_", "collapsedgroup", CollapsedGroup_XFormItem, Group_XFormItem)
3324 
3325 //	type defaults
3326 CollapsedGroup_XFormItem.prototype.headCss = "gridGroupHeader";
3327 CollapsedGroup_XFormItem.prototype.contentCss = "gridGroupContent";
3328 CollapsedGroup_XFormItem.prototype.gridLabelCss = "gridGroupBodyLabel";
3329 CollapsedGroup_XFormItem.prototype.colSizes = "100%";
3330 CollapsedGroup_XFormItem.prototype.numCols = 1;
3331 CollapsedGroup_XFormItem.prototype.width = "100%";
3332 CollapsedGroup_XFormItem.prototype.defaultDisplay = true;
3333 CollapsedGroup_XFormItem.prototype.displayLabelItem = false;
3334 CollapsedGroup_XFormItem.prototype.cssClass = "grid_group_container";
3335 CollapsedGroup_XFormItem.prototype.cssStyle = "margin-top: 10px;";
3336 CollapsedGroup_XFormItem.prototype.headerLabel = AjxMsg.collapsedGroup;
3337 CollapsedGroup_XFormItem.prototype.expandedImg =  "ImgNodeExpanded";
3338 CollapsedGroup_XFormItem.prototype.collapsedImg =  "ImgNodeCollapsed";
3339 CollapsedGroup_XFormItem.prototype.contentTableCssClass = "grid_table";
3340 CollapsedGroup_XFormItem.prototype.containerCssClass = "grid_table_cell_sheet";
3341 CollapsedGroup_XFormItem.prototype.initializeItems = function () {
3342     var gridLabelCss = this.getInheritedProperty("gridLabelCss");
3343     var oldItems = this.getItems();
3344     this.items = [];
3345     if(this.__attributes.label) {
3346         this.headerLabel = this.__attributes.label;
3347     }
3348     this.items[0] = this.getHeaderItems();
3349     this.items[1] = this.getContentItems();
3350     if(!this.items[1] || this.items[1].items.length == 0) {
3351         if(oldItems) {
3352             for(var i = 0; i < oldItems.length; i++) {
3353                 if(oldItems[i].type == "radio")
3354                     continue;  // don't deal with _RADIO_
3355                 if(oldItems[i].label || oldItems[i].txtBoxLabel) {
3356                     if (oldItems[i].type) {
3357                         var form = this.getForm();
3358                         var constructor =   XFormItemFactory.getItemTypeConstructor(oldItems[i].type, form);
3359                         //oldItems[i].labelCssStyle = "text-align:left; background-color:#DEE5F1 !important;padding-left:10px;";
3360                         if (constructor.prototype.labelCssClass) {
3361                            oldItems[i].labelCssClass =  constructor.prototype.labelCssClass + " " + gridLabelCss;
3362                         } else {
3363                             oldItems[i].labelCssClass = gridLabelCss;
3364                         }
3365                     }
3366                     else {
3367                         oldItems[i].labelCssClass = gridLabelCss;
3368                     }
3369                 }
3370             }
3371             this.items[1].items =  oldItems;
3372         }
3373     }
3374 
3375     Group_XFormItem.prototype.initializeItems.call(this);
3376 }
3377 
3378 CollapsedGroup_XFormItem.prototype.onClick = function(ev) {
3379     var headerItem =  this.getParentItem();
3380     var collapsedItem = headerItem.getParentItem();
3381     var headerContainer = headerItem.items[2];
3382     var contentContainer = collapsedItem.items[1];
3383     var displayLabelItem = collapsedItem.getInheritedProperty("displayLabelItem");
3384     if (collapsedItem.expanded) {
3385         collapsedItem.expanded = false;
3386         this.updateElement(collapsedItem.collapsedImg);
3387         contentContainer.hide();
3388         if(displayLabelItem)
3389             headerContainer.show();
3390     } else {
3391         collapsedItem.expanded = true;
3392         this.updateElement(collapsedItem.expandedImg);
3393         contentContainer.show();
3394         headerContainer.hide();
3395     }
3396 }
3397 
3398 CollapsedGroup_XFormItem.prototype.getHeaderItems =
3399 function () {
3400     var headerLabel = this.getInheritedProperty("headerLabel");
3401     var headerLabelWidth = this.getInheritedProperty("headerLabelWidth");
3402     var headerCss = this.getInheritedProperty("headCss");
3403     var headItems = this.getInheritedProperty("headerItems") || [];
3404     var headerItems = { type:_COMPOSITE_, numCols:3, width:"100%",
3405             colSizes:["20px", headerLabelWidth || "100%", "100%"], colSpan:"*",
3406             items:[
3407                 {type:_DWT_IMAGE_, value: this.expandedImg, cssStyle:"position:static;", onClick:this.onClick},
3408                 {type:_OUTPUT_, value: headerLabel},
3409                 {type:_GROUP_, items: headItems}
3410             ],
3411             cssClass:headerCss
3412         };
3413     return headerItems;
3414 }
3415 
3416 CollapsedGroup_XFormItem.prototype.getContentItems =
3417 function () {
3418     var colsize = this.getInheritedProperty("colSizes");
3419     var numcols = this.getInheritedProperty("numCols");
3420     var contentCss = this.getInheritedProperty("contentCss");
3421     var tableCssClass = this.getInheritedProperty("contentTableCssClass");
3422     var contentItems = { type:_GROUP_, items:[], colSpan:"*",
3423                          colSizes:colsize,numCols:numcols, width:"100%",
3424                          cssClass:contentCss, tableCssClass:tableCssClass
3425     };
3426     var ref = this.getInheritedProperty("ref");
3427     if(ref) {
3428         contentItems.ref = ref;
3429     }
3430     var content =  this.getInheritedProperty("contentItems");
3431     if(content)
3432         contentItems.items = content;
3433     return contentItems;
3434 }
3435 
3436 CollapsedGroup_XFormItem.prototype.updateVisibility = function () {
3437 
3438     XFormItem.prototype.updateVisibility.call(this);
3439     var display = this.getInheritedProperty("defaultDisplay");
3440     var displayLabelItem = this.getInheritedProperty("displayLabelItem");
3441     if(display) {
3442         this.items[0].items[2].hide();
3443         this.items[1].show();
3444         this.items[0].items[0].value = this.expandedImg;
3445         this.expanded = true;
3446     } else {
3447         if(displayLabelItem)
3448             this.items[0].items[2].show();
3449         else this.items[0].items[2].hide();
3450         this.items[1].hide();
3451         this.items[0].items[0].__attributes.value = this.collapsedImg;
3452         this.expanded = false;
3453     }
3454 }
3455 
3456 CollapsedGroup_XFormItem.prototype.getLabel = function () {
3457     return null;
3458 }
3459 
3460 
3461 /**
3462  * @class defines XFormItem type _GROUPER_
3463  * Draws a simple border around the group, with the label placed over the border
3464  * @constructor
3465  * 
3466  * @private
3467  */
3468 Grouper_XFormItem = function() {}
3469 XFormItemFactory.createItemType("_GROUPER_", "grouper", Grouper_XFormItem, Group_XFormItem);
3470 Grouper_XFormItem.prototype.labelCssClass = "GrouperLabel";
3471 Grouper_XFormItem.prototype.labelLocation = _INLINE_;		// managed manually by this class
3472 Grouper_XFormItem.prototype.borderCssClass = "GrouperBorder";
3473 Grouper_XFormItem.prototype.insetCssClass = "GrouperInset";
3474 
3475 Grouper_XFormItem.prototype.getBorderCssClass = function () {
3476 	return this.getInheritedProperty("borderCssClass");
3477 }
3478 
3479 Grouper_XFormItem.prototype.getInsetCssClass = function () {
3480 	return this.getInheritedProperty("insetCssClass");
3481 }
3482 
3483 // output the label
3484 Grouper_XFormItem.prototype.outputHTMLStart = function (html,  currentCol) {
3485 	html.append(
3486 			"<div class=", this.getBorderCssClass(), ">",
3487 				"<span ", this.getLabelCssString(),">", this.getLabel(), "</span>",
3488 				"<div class=", this.getInsetCssClass(),">"
3489 		);
3490 }
3491 
3492 Grouper_XFormItem.prototype.outputHTMLEnd = function (html,  currentCol) {
3493 	html.append(
3494 			"</div></div>"
3495 		);
3496 }
3497 
3498 
3499 
3500 RadioGrouper_XFormItem = function() {}
3501 XFormItemFactory.createItemType("_RADIO_GROUPER_", "radiogrouper", RadioGrouper_XFormItem, Grouper_XFormItem)
3502 RadioGrouper_XFormItem.prototype.labelCssClass = "xform_radio_grouper_label";
3503 RadioGrouper_XFormItem.prototype.borderCssClass = "xform_radio_grouper_border";
3504 RadioGrouper_XFormItem.prototype.insetCssClass = "xform_radio_grouper_inset";
3505 RadioGrouper_XFormItem.prototype.width = "100%";
3506 
3507 
3508 
3509 CollapsableRadioGrouper_XFormItem = function() {}
3510 XFormItemFactory.createItemType("_COLLAPSABLE_RADIO_GROUPER_", "collapsableradiogrouper", CollapsableRadioGrouper_XFormItem, RadioGrouper_XFormItem)
3511 
3512 CollapsableRadioGrouper_XFormItem.prototype.getLabel = function () {
3513 	var label = XFormItem.prototype.getLabel.apply(this);
3514 	return "<nobr><span class=xform_button style='font-size:9px;color:black;'> – </span> "+label+"</nobr>";
3515 }
3516 
3517 
3518 
3519 
3520 /**
3521  * @class defines XFormItem type _CASE_
3522  * @constructor
3523  * 
3524  * @private
3525  */
3526 Case_XFormItem = function() {
3527 	Group_XFormItem.call(this);
3528 
3529 }
3530 XFormItemFactory.createItemType("_CASE_", "case", Case_XFormItem, Group_XFormItem);
3531 
3532 //	type defaults
3533 Case_XFormItem.prototype.labelLocation = _NONE_;
3534 Case_XFormItem.prototype.useParentTable = false;
3535 Case_XFormItem.prototype.width = "100%";
3536 Case_XFormItem.prototype.focusable = false;
3537 Case_XFormItem.prototype.deferred = true;
3538 Case_XFormItem.prototype.cellspacing = 0;
3539 Case_XFormItem.prototype.cellpadding = 0;
3540 Case_XFormItem.prototype.cssClass = "XFormCase";
3541 Case_XFormItem.prototype.isTabGroup = true;	
3542 Case_XFormItem.prototype.caseVarRef = "currentStep";
3543 Case_XFormItem.prototype.visibilityChangeEventSources = [Case_XFormItem.prototype.caseVarRef];
3544 Case_XFormItem.prototype.initFormItem = function () {
3545 	XFormItem.prototype.initFormItem.call(this);	
3546 	if(this.getInheritedProperty("isTabGroup")) {
3547 		var form = this.getForm();
3548 		form.tabIdOrder[this.getId()] = this.tabIdOrder;
3549 		form.addTabGroup(this,"caseKey");
3550 	}
3551 
3552 }
3553 Case_XFormItem.prototype.outputHTML = function (html,  currentCol) {
3554 	this.deferred = this.getInheritedProperty("deferred");
3555 	if(this.deferred) {
3556 		this.getForm().outputItemList([], this, html,  this.getNumCols(), 0, true, false);
3557 	} else {
3558 		this.getForm().outputItemList(this.getItems(), this, html,  this.getNumCols(), currentCol);
3559 	}
3560 }
3561 
3562 Case_XFormItem.prototype._outputHTML = function () {
3563 	var form = this.getForm();
3564 	
3565 	var element = this.getElement();
3566 	if(!element) {
3567 		return;
3568 	}
3569 	var masterId = this.getId();
3570 	
3571 	if(this.cacheInheritedMethod("getCustomHeight", "$getCustomHeight")) {
3572 		var height = this.cacheInheritedMethod("getCustomHeight", "$getCustomHeight").call(this);
3573 		var width = this.cacheInheritedMethod("getCustomWidth", "$getCustomWidth").call(this);
3574 		Dwt.setSize(element, width, height);
3575 		var container = (form.parent instanceof DwtControl) ? form.parent : DwtControl.fromElementId(window._dwtShellId);
3576 		if(container) {
3577 			if(this.cacheInheritedMethod("resizeHdlr", "$resizeHdlr")) {
3578 				container.addControlListener(new AjxListener(this, this.cacheInheritedMethod("resizeHdlr", "$resizeHdlr")));
3579 			}
3580 		}
3581 	}	
3582 
3583     if(this.cacheInheritedMethod("getCustomPaddingStyle", "$getCustomPaddingStyle")) {
3584         var paddingStyle = this.cacheInheritedMethod("getCustomPaddingStyle", "$getCustomPaddingStyle").call(this);
3585         if(paddingStyle)
3586             element.style.cssText += ";"+paddingStyle;  //";"for IE
3587     }
3588 
3589 	if (AjxEnv.isIE) {
3590 		var tempDiv = this.createElement("temp",null,"div","");
3591 		tempDiv.display = "none";
3592 	}
3593 
3594 	var html = new AjxBuffer();
3595 	
3596 	if (this.outputHTMLStart) {
3597 		this.outputHTMLStart(html,  0);
3598 	}
3599 	
3600 	var drawTable = (this.getUseParentTable() == false);
3601 	if (drawTable) {
3602 		var colSizes = this.getColSizes();
3603 		var cellspacing = this.getInheritedProperty("cellspacing");
3604 		var cellpadding = this.getInheritedProperty("cellpadding");		
3605 		html.append("<table cellspacing=",cellspacing," cellpadding=",cellpadding," ",  
3606 				(XForm._showBorder ? "border=1" : "border=0"),
3607 				" id=\"", this.getId(),"_table\" ", this.getTableCssString(),">");
3608 		if (colSizes != null) {
3609 			html.append(" <colgroup>");
3610 			for (var i = 0; i < colSizes.length; i++) {
3611 				var size = colSizes[i];
3612 				if (size < 1) size = size * 100 + "%";
3613 				html.append("<col width=", size, ">");
3614 			}
3615 			html.append("</colgroup>");
3616 		}
3617 		html.append("<tbody>");
3618 	}
3619 	//output HTML for all child elements
3620 	form.outputItemList(this.getItems(), this, html, this.getNumCols(), 0, true, true);
3621 	html.append("</table>");	
3622 
3623 	
3624 //	DBG.dumpObj(html.toString());
3625     element.innerHTML = html.toString();
3626     this.deferred = false;
3627 }
3628 
3629 Case_XFormItem.prototype.hide = function(isBlock) {
3630 	XFormItem.prototype.hide.call(this, isBlock);
3631 	this.hideElement(this.getElement(),isBlock)	;
3632 }
3633 
3634 Case_XFormItem.prototype.show = function(isBlock) {
3635 	XFormItem.prototype.show.call(this, isBlock);
3636 	this.showElement(this.getElement(),isBlock)	;
3637 }
3638 
3639 Case_XFormItem.prototype.isCurrentTab = function () {
3640 	var isCurrent = false;
3641 	var caseKey = this.getInheritedProperty("caseKey");
3642 	if(!AjxUtil.isEmpty(caseKey)) {
3643 		var caseVarRef = this.getInheritedProperty("caseVarRef");
3644 		var currentKey = this.getInstanceValue(caseVarRef);
3645 		isCurrent = (currentKey == caseKey);
3646 	}
3647 	return isCurrent;
3648 }
3649 Case_XFormItem.prototype.visibilityChecks = [Case_XFormItem.prototype.isCurrentTab];
3650 
3651 /**
3652  * @class defines XFormItem type _TOP_GROUPER_
3653  * Draws a simple border around the group, with the label placed over the border
3654  * @constructor
3655  * 
3656  * @private
3657  */
3658 TopGrouper_XFormItem = function() {}
3659 XFormItemFactory.createItemType("_TOP_GROUPER_", "top_grouper", TopGrouper_XFormItem, RadioGrouper_XFormItem)
3660 TopGrouper_XFormItem.prototype.borderCssClass = "TopGrouperBorder";
3661 TopGrouper_XFormItem.prototype.labelCssClass = "GrouperLabel";
3662 TopGrouper_XFormItem.prototype.labelLocation = _INLINE_;		// managed manually by this class
3663 TopGrouper_XFormItem.prototype.insetCssClass = "GrouperInset";
3664 
3665 
3666 // output the label
3667 TopGrouper_XFormItem.prototype.outputHTMLStart = function (html,   currentCol) {
3668 	html.append(
3669 			"<div class=", this.getBorderCssClass(), ">",
3670 				"<div ", this.getLabelCssString(),">", this.getLabel(), "</div>",
3671 				"<div class=", this.getInsetCssClass(),">"
3672 		);
3673 }
3674 
3675 TopGrouper_XFormItem.prototype.outputHTMLEnd = function (html,  currentCol) {
3676 	html.append(
3677 			"</div></div>"
3678 		);
3679 }
3680 
3681 if (appNewUI) {
3682     XFormItemFactory.createItemType("_TOP_GROUPER_", "top_grouper", TopGrouper_XFormItem, CollapsedGroup_XFormItem);
3683 }
3684 
3685 BaseTopGrouper_XFormItem = function() {}
3686 XFormItemFactory.createItemType("_BASE_TOP_GROUPER_", "base_top_grouper", BaseTopGrouper_XFormItem, RadioGrouper_XFormItem)
3687 BaseTopGrouper_XFormItem.prototype.borderCssClass = "TopGrouperBorder";
3688 BaseTopGrouper_XFormItem.prototype.labelCssClass = "GrouperLabel";
3689 BaseTopGrouper_XFormItem.prototype.labelLocation = _INLINE_;		// managed manually by this class
3690 BaseTopGrouper_XFormItem.prototype.insetCssClass = "GrouperInset";
3691 
3692 // output the label
3693 BaseTopGrouper_XFormItem.prototype.outputHTMLStart = function (html,   currentCol) {
3694     html.append(
3695             "<div class=", this.getBorderCssClass(), ">",
3696                 "<div ", this.getLabelCssString(),">", this.getLabel(), "</div>",
3697                 "<div class=", this.getInsetCssClass(),">"
3698         );
3699 }
3700 
3701 BaseTopGrouper_XFormItem.prototype.outputHTMLEnd = function (html,  currentCol) {
3702     html.append(
3703             "</div></div>"
3704         );
3705     }
3706 
3707 /**
3708  * @class defines XFormItem type _SWITCH_
3709  * @constructor
3710  * 
3711  * @private
3712  */
3713 Switch_XFormItem = function() {}
3714 XFormItemFactory.createItemType("_SWITCH_", "switch", Switch_XFormItem, Group_XFormItem)
3715 
3716 //	type defaults
3717 Switch_XFormItem.prototype.labelLocation = _NONE_;
3718 Switch_XFormItem.prototype.colSpan = "*";
3719 Switch_XFormItem.prototype.width = "100%";
3720 Switch_XFormItem.prototype.numCols = 1;
3721 
3722 Switch_XFormItem.prototype.outputHTML = function (html) {
3723 	Switch_XFormItem.outputItemList.call(this.getForm(),this.getItems(), this, html);
3724 }
3725 
3726 Switch_XFormItem.prototype.setElementEnabled = function (enable) {};
3727 
3728 Switch_XFormItem.outputItemList = function (items, parentItem, html,   numCols, currentCol, skipTable, skipOuter) {
3729 	if (parentItem.outputHTMLStart) {
3730 		parentItem.outputHTMLStart(html,  currentCol);
3731 	}
3732 	var outerStyle = null;
3733 	if(!skipOuter) {
3734 		outerStyle = parentItem.getCssString();
3735 		if (outerStyle != null && outerStyle != "") {
3736 			parentItem.outputElementDivStart(html);
3737 		}
3738 	}
3739 	for (var itemNum = 0; itemNum < items.length; itemNum++) {	
3740 		var item = items[itemNum];
3741 		var isNestingItem = (item.getItems() != null);
3742 		var itemUsesParentTable = (item.getUseParentTable() != false);
3743 
3744 		var writeElementDiv = item.getWriteElementDiv();
3745 		var outputMethod = item.getOutputHTMLMethod();
3746 		
3747 		if (isNestingItem && itemUsesParentTable) {
3748 			// actually write out the item
3749 			if (outputMethod) outputMethod.call(item, html,  currentCol);
3750 
3751 		} else {
3752 
3753 			// begin the element div, if required
3754 			if (writeElementDiv) 	item.outputElementDivStart(html);
3755 			
3756 			// actually write out the item
3757 			if (outputMethod) outputMethod.call(item, html,  0);
3758 
3759 	
3760 			// end the element div, if required
3761 			if (writeElementDiv) 	item.outputElementDivEnd(html);
3762 	
3763 		}
3764 		
3765 		if(parentItem)
3766 			parentItem.registerActiveChild(item);
3767 		
3768 		item.signUpForEvents();
3769 		
3770 		var itemUpdateMethod = item.getUpdateElementMethod();
3771 		if(itemUpdateMethod) {
3772 			var itemRefpath = item.getRefPath();
3773 			if(itemRefpath) {
3774 				var instance = this.getInstance();
3775 				if(instance) {
3776 					itemUpdateMethod.call(item, item.getInstanceValue());
3777 				}
3778 			}
3779 		}
3780 	}
3781 	if (outerStyle != null && outerStyle != "") {
3782 		parentItem.outputElementDivEnd(html);
3783 	}
3784 
3785 
3786 	if (parentItem.outputHTMLEnd) {
3787 		parentItem.outputHTMLEnd(html,  currentCol);
3788 	}		
3789 }
3790 
3791 /**
3792  * @class defines XFormItem type _REPEAT_
3793  * @constructor
3794  * 
3795  * @private
3796  */
3797 Repeat_XFormItem = function() {
3798 	Group_XFormItem.call(this);
3799 }
3800 XFormItemFactory.createItemType("_REPEAT_", "repeat", Repeat_XFormItem, Group_XFormItem)
3801 
3802 //	type defaults
3803 Repeat_XFormItem.prototype.useParentTable = false;
3804 Repeat_XFormItem.prototype.writeElementDiv = true;
3805 Repeat_XFormItem.prototype.numCols = 1;
3806 Repeat_XFormItem.prototype.number = 1;
3807 Repeat_XFormItem.prototype.showRemoveButton = true;
3808 Repeat_XFormItem.prototype.showAddButton = true;
3809 Repeat_XFormItem.prototype.alwaysShowAddButton = false;
3810 Repeat_XFormItem.prototype.showMoveUpButton = false;
3811 Repeat_XFormItem.prototype.showMoveDownButton = false;
3812 Repeat_XFormItem.prototype.bmolsnr = true;
3813 Repeat_XFormItem.prototype.enableDisableChecks = [XFormItem.prototype.hasWritePermission];
3814 Repeat_XFormItem.prototype.visibilityChecks = [XFormItem.prototype.hasReadPermission];
3815 
3816 Repeat_XFormItem.haveAnyRows = function () {
3817 	return (this.getParentItem().getInstanceCount() != 0);
3818 }
3819 
3820 Repeat_XFormItem.isLastRow = function () {
3821 	return ((this.getParentItem().getInstanceCount()-1) == this.getParentItem().instanceNum);
3822 }
3823 
3824 Repeat_XFormItem.isAddButtonVisible = function () {
3825 	return (this.getParentItem().getParentItem().getAlwaysShowAddButton() || Repeat_XFormItem.isLastRow.call(this) || !(Repeat_XFormItem.haveAnyRows.call(this)));
3826 }
3827 
3828 Repeat_XFormItem.prototype.getRemoveButton = function () {
3829 	if(!this.removeButton) {
3830 		this.removeButton = {
3831 			type:_BUTTON_, 
3832 			label: AjxMsg.xformRepeatRemove, 
3833 			//width:20,
3834 			cssStyle:"margin-left:20px;",
3835 			onActivate:function (event) {
3836 				var repeatItem = this.getParentItem().getParentItem();
3837 				repeatItem.removeRowButtonClicked(this.getParentItem().instanceNum);
3838 			},
3839 			visibilityChecks:[Repeat_XFormItem.haveAnyRows],
3840 			visibilityChangeEventSources:[this.getRef()]
3841 		};
3842 		var label = this.getInheritedProperty("removeButtonLabel");
3843 		if(label)
3844 			this.removeButton.label = label;
3845 		
3846 		var width = this.getInheritedProperty("removeButtonWidth");		
3847 		if (width)
3848 			this.removeButton.width = width ;		
3849 			
3850 		var cssStyle = this.getInheritedProperty("removeButtonCSSStyle");
3851 		if (cssStyle) 
3852 			this.removeButton.cssStyle = cssStyle ;	
3853 	}
3854 	return this.removeButton;	
3855 }
3856 
3857 Repeat_XFormItem.prototype.getAddButton = function () {
3858 	if(!this.addButton) {
3859 		var showAddOnNextRow = this.getInheritedProperty("showAddOnNextRow");
3860 		this.addButton = {
3861 			ref:".",
3862 			type:_BUTTON_, 
3863 			label: AjxMsg.xformRepeatAdd, 
3864 			onActivate:function (event) {
3865 				var repeatItem = this.getParentItem().getParentItem();
3866 				repeatItem.addRowButtonClicked(this.getParentItem().instanceNum);
3867 			},
3868 			visibilityChecks:[Repeat_XFormItem.isAddButtonVisible],
3869 			visibilityChangeEventSources:[this.getRefPath()],
3870 			forceUpdate:true
3871 		};
3872 		var label = this.getInheritedProperty("addButtonLabel");
3873 		if(label)
3874 			this.addButton.label = label;			
3875 		
3876 		var width = this.getInheritedProperty("addButtonWidth");		
3877 		if (width)
3878 			this.addButton.width = width ;
3879 
3880         var cssStyle = this.getInheritedProperty("addButtonCSSStyle");
3881 		if (cssStyle)
3882 			this.addButton.cssStyle = cssStyle ;
3883 
3884 		if(showAddOnNextRow) {
3885 			this.addButton.colSpan = "*";
3886 		}
3887 			
3888 	}
3889 	return this.addButton;	
3890 }
3891 
3892 Repeat_XFormItem.prototype.moveUpButton = {
3893 	type:_BUTTON_, 
3894 	label:"^", 
3895 	width:20,
3896 	cssStyle:"margin-left:20px;",
3897 	onActivate:function (event) {
3898 		var repeatItem = this.getParentItem().getParentItem();
3899 		repeatItem.moveUpButtonClicked(this.getParentItem().instanceNum);
3900 	}
3901 }
3902 Repeat_XFormItem.prototype.moveDownButton = {
3903 	ref:".",
3904 	type:_BUTTON_, 
3905 	label:"v", 
3906 	width:20,
3907 	onActivate:function (event) {
3908 		var repeatItem = this.getParentItem().getParentItem();
3909 		repeatItem.moveDownButtonClicked(this.getParentItem().instanceNum);
3910 	},
3911 	forceUpdate:true
3912 }
3913 
3914 Repeat_XFormItem.groupVisibilityCheck = function () {
3915 	return ( (this.instanceNum < this.getNumberToShow()) || (this.instanceNum < this.getInstanceCount()) || (this.instanceNum==0));	
3916 }
3917 
3918 Repeat_XFormItem.prototype.initializeItems = function () {
3919 	var items = this.getItems();
3920 
3921 	if (items.length == 1 && items[0].items) {
3922 		var group = items[0];
3923 	} else {
3924 		var group = {	
3925 				ref: this.getRef(), 
3926 				fromRepeat:true, 
3927 //				useParentTable:true,
3928 				type:_GROUP_, 
3929 				numCols: items.length,
3930 				items:[].concat(items),
3931 				visibilityChangeEventSources:[this.getRefPath()],
3932 				visibilityChecks:[function() {
3933 					return (this.instanceNum==0 || (this.instanceNum < this.getNumberToShow()) || (this.instanceNum < this.getInstanceCount()));
3934 				}]
3935 			};
3936 	}
3937 	
3938 	group.colSpan = 1;
3939 
3940 	//Check if we have an explicit condition defined for Remove button
3941 	
3942 	// add the add and remove buttons to the original items array, if appropriate
3943 	if (this.getShowRemoveButton()) {
3944 		var button = this.getRemoveButton();
3945 		group.items[group.items.length] = button;
3946 		group.numCols++;			
3947 	}
3948 	if (this.getShowAddButton()) {
3949 		var button = this.getAddButton();
3950 	
3951 		var showAddOnNextRow = this.getInheritedProperty("showAddOnNextRow");
3952 		group.items[group.items.length] = button;
3953 		if(showAddOnNextRow) {
3954 			group.items[group.items.length] = 
3955 			{type:_SPACER_, colSpan:(group.numCols-1), 
3956 				visibilityChecks:[Repeat_XFormItem.isLastRow], 
3957 				visibilityChangeEventSources:[this.getRefPath()]
3958 			};
3959 		} else {
3960 			group.numCols++;
3961 		}
3962 	}
3963 	if (this.getShowMoveUpButton()) {
3964 		group.items[group.items.length] = this.getMoveUpButton();
3965 		group.numCols++;
3966 	}
3967 	if (this.getShowMoveDownButton()) {
3968 		group.items[group.items.length] = this.getMoveDownButton();
3969 		group.numCols++;
3970 	}
3971 
3972 	// save off the original items in the group
3973 	this.__originalItems = group;
3974 	// and reset the items array
3975 	this.items = [];
3976 }
3977 
3978 Repeat_XFormItem.prototype.makeRepeatInstance = function() {
3979 	// NOTE: We always append the new items to the end, which is OK,
3980 	//			since if a *data value* is inserted in the middle,
3981 	//			each row will show the proper thing when the update script is called
3982 	//
3983 	//  NOTE: XFORMS SPEC REQUIRES REPEAT ITEMS TO START AT 1, this implementation starts at 0!!!
3984 	//
3985 	var originalGroup = this.__originalItems;
3986 	var numCols = this.getNumCols();
3987 	var newItems = [];
3988 	
3989 	for (var i = 0; i < numCols; i++) {
3990 		var instanceNum = this.items.length;
3991 	
3992 		originalGroup.refPath = this.getRefPath() + "[" + instanceNum + "]";
3993 	
3994 		// initialize the originalGroup and its cloned items
3995 		groupItem = this.getForm().initItem(originalGroup, this);
3996 		groupItem.instanceNum = instanceNum;
3997 	
3998 		newItems.push(groupItem);
3999 		this.items.push(groupItem);
4000 	}	
4001 	return newItems;
4002 }
4003 
4004 
4005 Repeat_XFormItem.prototype.outputHTML = function (html,   currentCol) {
4006 	// output one item to start
4007 	//	all other items will be output dynamically
4008 	this.makeRepeatInstance();
4009 	this.getForm().outputItemList(this.items, this, html, this.getNumCols(), 0);
4010 }
4011 
4012 
4013 Repeat_XFormItem.prototype.updateElement = function (value) {
4014 	var form = this.getForm();
4015 	
4016 	var element = this.getElement();
4017 	if (value == null || value === "") value = [];
4018 	var itemsToShow = Math.max(value.length, this.getNumberToShow());
4019 	var slotsPresent = this.items.length;
4020 
4021 	var masterId = this.getId();
4022 	if (itemsToShow > slotsPresent) {
4023 		var missingElementCount = (itemsToShow - slotsPresent);
4024 		// create some more slots and show them
4025 
4026 		var table = element.getElementsByTagName("table")[0];
4027 		var tbody = element.getElementsByTagName("tbody")[0];
4028 	
4029 		var tempDiv;	
4030 		if (AjxEnv.isIE) {
4031 			tempDiv = this.createElement("temp",null,"div","");
4032 			tempDiv.display = "none";
4033 		}
4034 		while (this.items.length < itemsToShow) {
4035 			var newItems = this.makeRepeatInstance(this);
4036 			var html = new AjxBuffer();
4037 			form.outputItemList(newItems, this, html,  this.getNumCols(), 0, true);
4038 			if (AjxEnv.isIE) {
4039 				tempDiv.innerHTML = "<table>" + html.toString() + "</table>";
4040 				var rows = tempDiv.getElementsByTagName("table")[0].rows;
4041 				for (var r = 0; r < rows.length; r++) {
4042 					tbody.appendChild(rows[r]);
4043 				}
4044 			} else {
4045 				var row = table.insertRow(-1);
4046 				row.innerHTML = html;
4047 			}
4048 			var cnt = newItems.length;
4049 			for(var i = 0; i <cnt; i++) {
4050 				var updateMethod = newItems[i].getUpdateVisibilityMethod();
4051 				if(updateMethod)
4052 					updateMethod.call(newItems[i]);
4053 				
4054 				updateMethod = newItems[i].getUpdateEnabledDisabledtMethod();
4055 				if(updateMethod)
4056 					updateMethod.call(newItems[i]);				
4057 			}
4058 		}
4059 	}
4060 	/*var updateMethod = this.getUpdateVisibilityMethod();
4061 	if(updateMethod)
4062 		updateMethod.call(this);
4063 	updateMethod = this.getUpdateEnabledDisabledtMethod();
4064 	if(updateMethod)
4065 		updateMethod.call(this);	*/
4066 	
4067 	XFormItem.prototype.updateElement.call(this, value);
4068 }
4069 
4070 Repeat_XFormItem.prototype.addRowButtonClicked = function (instanceNum) {
4071 	var path = this.getRefPath();
4072 	this.getModel().addRowAfter(this.getInstance(), path, instanceNum);
4073 }
4074 
4075 Repeat_XFormItem.prototype.removeRowButtonClicked = function (instanceNum) {
4076 	var form = this.getForm();
4077 	if (this.getOnRemoveMethod() ) {
4078 		this.getOnRemoveMethod().call(this, instanceNum, form)
4079 	} else {
4080 		var path = this.getRefPath();
4081 		this.getModel().removeRow(this.getInstance(), path, instanceNum);
4082 	}
4083 	this.items[instanceNum].clearError();
4084 //	this.getForm().setIsDirty(true,this);
4085 	
4086 	var event = new DwtXFormsEvent(form, this, this.getInstanceValue());
4087 	form.notifyListeners(DwtEvent.XFORMS_VALUE_CHANGED, event);
4088 }
4089 
4090 Repeat_XFormItem.prototype.getOnRemoveMethod = function() {
4091 	return this.cacheInheritedMethod("onRemove","$onRemove","index,form");
4092 }
4093 
4094 
4095 /**
4096  * @class defines XFormItem type _REPEAT_GRID_
4097  * @constructor
4098  * 
4099  * @private
4100  */
4101 Repeat_Grid_XFormItem = function() {}
4102 XFormItemFactory.createItemType("_REPEAT_GRID_", "repeat_grid", Repeat_Grid_XFormItem, Repeat_XFormItem)
4103 Repeat_Grid_XFormItem.prototype.showRemoveButton = false;
4104 Repeat_Grid_XFormItem.prototype.showAddButton = false;
4105 Repeat_Grid_XFormItem.numCols = 2;
4106 
4107 
4108 
4109 
4110 
4111 /**
4112  * @class defines XFormItem type _COMPOSITE_
4113  * @constructor
4114  * 
4115  * @private
4116  */
4117 Composite_XFormItem = function() {
4118 	Group_XFormItem.call(this);
4119 }
4120 XFormItemFactory.createItemType("_COMPOSITE_", "composite", Composite_XFormItem, Group_XFormItem)
4121 
4122 //	type defaults
4123 Composite_XFormItem.prototype.useParentTable = false;
4124 Composite_XFormItem.prototype.tableCssClass = "xform_composite_table";
4125 Composite_XFormItem.prototype.focusable = false;
4126 
4127 Composite_XFormItem.prototype.initializeItems = function () {
4128 	var items = this.getItems();
4129 	if (items == null) return;
4130 	
4131 	// make sure the numCols is defined (default to the number of items in the composite)
4132 	if (this.numCols == null) this.numCols = items.length;
4133 	
4134 	// actually instantiate them as formItems
4135 	this.items = this.getForm().initItemList(items, this);
4136 }
4137 
4138 Composite_XFormItem.onFieldChange = function(value, event, form) {
4139 	if (this.getParentItem() && this.getParentItem().getOnChangeMethod()) {
4140 		return this.getParentItem().getOnChangeMethod().call(this, value, event, form);
4141 	} else {
4142 		return this.setInstanceValue(value);
4143 	}
4144 }
4145 
4146 
4147 SetupGroup_XFormItem = function() {
4148 }
4149 SetupGroup_XFormItem.prototype.width="100%";
4150 XFormItemFactory.createItemType("_SETUPGROUP_", "setupgroup", SetupGroup_XFormItem, Composite_XFormItem)
4151 SetupGroup_XFormItem.prototype.initializeItems = function () {
4152     var headerLabels = this.getInheritedProperty("headerLabels");
4153     var contentItems = this.getInheritedProperty("contentItems");
4154     this.items = [];
4155     this.width="100%";
4156 
4157     if (headerLabels.length!= 0 && headerLabels.length == contentItems.length) {
4158         var firstlabel = 1;
4159         var isLast;
4160         for (var i = 0; i < headerLabels.length; i++) {
4161             if (i != headerLabels.length - 1) {
4162                 isLast = false;
4163             } else {
4164                 isLast = true;
4165             }
4166             var result =  this.constructSingleGroup(headerLabels[i], contentItems[i], firstlabel, isLast);
4167             if (result != undefined) {
4168                 this.items.push(result);
4169                 firstlabel ++;
4170             }
4171         }
4172     }
4173     this.numCols = this.items.length;
4174     if (this.numCols > 1)  {
4175         var colSize =Math.floor(100/(this.numCols));
4176         var lastCol = 100 - colSize* (this.numCols - 1);
4177         var colArr = [];
4178         for (var i = 0; i < this.numCols - 1; i ++) {
4179             colArr.push(colSize + "%");
4180         }
4181         colArr.push(lastCol + "%");
4182         this.colSizes = colArr;
4183     }
4184     Composite_XFormItem.prototype.initializeItems.call(this);
4185 }
4186 
4187 SetupGroup_XFormItem.prototype.constructSingleGroup = function (headerLabel, contentItem, index, isLast) {
4188     var currentGroup = {type:_GROUP_, numCols:2, width: "100%", valign:_TOP_, items:[]};
4189     var labelMessage = (index) + "  " + headerLabel;
4190     /*Header Start*/
4191     var headerItems;
4192     if (isLast) {
4193         headerItems = {type:_OUTPUT_, colSpan: "*", value: labelMessage, cssClass: "ZaHomeSetupHeader ZaHomeSetupTitle"};
4194     } else {
4195         headerItems = {type:_GROUP_, colSpan: "*", numCols:3, cssClass: "ZaHomeSetupHeader",
4196             items:[
4197                 {type:_OUTPUT_, value: labelMessage, cssClass: "ZaHomeSetupTitle"},
4198                 {type:_SPACER_, width:"5px", colSpan:1},
4199                 {type:_AJX_IMAGE_, src:"SetupArrow"}
4200             ]
4201         };
4202     }
4203 
4204     currentGroup.items.push(headerItems);
4205     /*Body Start*/
4206     var singleContentItem;
4207     var isAdd = false;
4208     var labelNumber = 1;
4209     var currentLabel ;
4210     for (var i = 0; i < contentItem.length; i++) {
4211         if (contentItem[i] && contentItem[i].value) {
4212             isAdd = true;
4213             currentLabel = labelNumber + ".";
4214             labelNumber ++;
4215             singleContentItem = {type:_OUTPUT_, label: currentLabel, value: contentItem[i].value, onClick: contentItem[i].onClick, labelCssClass:"ZaHomeLinkItemLabel", containerCssClass:"ZaLinkedItem"};
4216             currentGroup.items.push(singleContentItem);
4217         }
4218     }
4219 
4220     if (!isAdd)
4221         return undefined;
4222     else
4223         return currentGroup;
4224 }
4225 //Composite_XFormItem.prototype.getErrorContainer = function () {
4226 //	
4227 //}
4228 
4229 /**
4230  * @class defines XFormItem type _DATE_
4231  * @constructor
4232  * 
4233  * @private
4234  */
4235 Date_XFormItem = function() {}
4236 XFormItemFactory.createItemType("_DATE_", "date", Date_XFormItem, Composite_XFormItem)
4237 
4238 //	type defaults
4239 Date_XFormItem.prototype.DATE_MONTH_CHOICES = [
4240 				{value:1, label:I18nMsg.monthJanMedium},
4241 				{value:2, label:I18nMsg.monthFebMedium},
4242 				{value:3, label:I18nMsg.monthMarMedium},
4243 				{value:4, label:I18nMsg.monthAprMedium},
4244 				{value:5, label:I18nMsg.monthMayMedium},
4245 				{value:6, label:I18nMsg.monthJunMedium},
4246 				{value:7, label:I18nMsg.monthJulMedium},
4247 				{value:8, label:I18nMsg.monthAugMedium},
4248 				{value:9, label:I18nMsg.monthSepMedium},
4249 				{value:10, label:I18nMsg.monthOctMedium},
4250 				{value:11, label:I18nMsg.monthNovMedium},
4251 				{value:12, label:I18nMsg.monthDecMedium}
4252 			];
4253 Date_XFormItem.prototype.DATE_DAY_CHOICES = ["1","2","3","4","5","6","7","8","9","10","11","12",
4254 						  "13","14","15","16","17","18","19","20","21","22",
4255 						  "23","24","25","26","27","28","29","30","31"];
4256 Date_XFormItem.prototype.numCols = 3;
4257 Date_XFormItem.prototype.items = [
4258 	{	type:_SELECT1_, 
4259 		ref:".",
4260 		width:50,
4261 		valign:_MIDDLE_,
4262 		relevantBehavior:_PARENT_,
4263 		choices: Date_XFormItem.prototype.DATE_MONTH_CHOICES,
4264 		labelLocation:_NONE_,
4265 		getDisplayValue:function (newValue) {
4266 			if (!(newValue instanceof Date)) newValue = new Date();
4267 			return "" + (newValue.getMonth() + 1);
4268 		},
4269 		elementChanged:function (monthStr, currentDate, event) {
4270 			if (currentDate == null) currentDate = new Date();	//??? should get values of other field???
4271 		
4272 			var month = parseInt(monthStr);
4273 			if (!isNaN(month)) {
4274 				month -= 1;
4275 				currentDate.setMonth(month);
4276 			}
4277 			this.getForm().itemChanged(this.getParentItem(), currentDate, event);
4278 		}
4279 	},
4280 	{	type:_SELECT1_, 
4281 		ref:".",
4282 		width:50,
4283 		valign:_MIDDLE_,
4284 		relevantBehavior:_PARENT_,
4285 		labelLocation:_NONE_,
4286 		choices: Date_XFormItem.prototype.DATE_DAY_CHOICES,
4287 		getDisplayValue:function (newValue) {
4288 			if (!(newValue instanceof Date)) newValue = new Date();
4289 			return "" + newValue.getDate();
4290 		},
4291 		elementChanged: function (dateStr, currentDate, event) {
4292 			if (currentDate == null) currentDate = new Date();	//??? should get values of other field???
4293 		
4294 			var date = parseInt(dateStr);
4295 			if (!isNaN(date)) {
4296 				currentDate.setDate(date);
4297 			}
4298 			this.getForm().itemChanged(this.getParentItem(), currentDate, event);
4299 		}
4300 	},
4301 	{	type:_TEXTFIELD_, 
4302 		ref:".",
4303 		relevantBehavior:_PARENT_,
4304 		width:45,
4305 		labelLocation:_NONE_,
4306 
4307 		getDisplayValue:function (newValue) {
4308 			if (!(newValue instanceof Date)) newValue = new Date();
4309 			return "" + newValue.getFullYear();
4310 		},
4311 		elementChanged: function (yearStr, currentDate, event) {
4312 			if (currentDate == null) currentDate = new Date();	//??? should get values of other field???
4313 		
4314 			var year = parseInt(yearStr);
4315 			if (!isNaN(year)) {
4316 				currentDate.setYear(year);
4317 			}
4318 			this.getForm().itemChanged(this.getParentItem(), currentDate, event);
4319 		}
4320 
4321 	}
4322 ];
4323 
4324 
4325 
4326 /**
4327  * @class defines XFormItem type _TIME_
4328  * @constructor
4329  * 
4330  * @private
4331  */
4332 Time_XFormItem = function() {}
4333 XFormItemFactory.createItemType("_TIME_", "time", Time_XFormItem, Composite_XFormItem)
4334 
4335 //	type defaults
4336 Time_XFormItem.prototype.numCols = 3;
4337 Time_XFormItem.prototype.TIME_HOUR_CHOICES = ["1","2","3","4","5", "6","7","8","9","10","11","12"];
4338 Time_XFormItem.prototype.TIME_MINUTE_CHOICES = ["00","05","10","15","20","25", "30","35","40","45","50","55"];
4339 Time_XFormItem.prototype.TIME_AMPM_CHOICES = [I18nMsg.periodAm,I18nMsg.periodPm];
4340 
4341 
4342 Time_XFormItem.prototype.items = [
4343 	{	
4344 		type:_SELECT1_, 
4345 		ref:".",
4346 		width:50,
4347 		valign:_MIDDLE_,
4348 		choices: Time_XFormItem.prototype.TIME_HOUR_CHOICES,
4349 		labelLocation:_NONE_,
4350 		getDisplayValue:function (newValue) {
4351 			if (!(newValue instanceof Date)) newValue = new Date();
4352 			var hours = "" + (newValue.getHours() % 12);
4353 			if (hours == "0") hours = "12";
4354 			return hours;
4355 		},
4356 		elementChanged:function (hoursStr, currentDate, event) {
4357 			if (currentDate == null) currentDate = new Date();	//??? should get values of other fields???
4358 			if (this.__dummyDate == null) {
4359 				this.__dummyDate = new Date();
4360 			}
4361 			this.__dummyDate.setTime(currentDate.getTime());
4362 			var hours = parseInt(hoursStr);
4363 			if (!isNaN(hours)) {
4364 				if (hours == 12) hours = 0;
4365 				var wasPM = (currentDate.getHours() > 11);
4366 				if (wasPM) hours += 12;
4367 				this.__dummyDate.setHours(hours);
4368 			}
4369 			var parentItem = this.getParentItem();
4370 			var elementChangedMethod = parentItem.getElementChangedMethod();
4371 			if (elementChangedMethod != null) {
4372 				elementChangedMethod.call(this.getParentItem(),this.__dummyDate, currentDate, event);
4373 			} else {
4374 				this.getForm().itemChanged(this.getParentItem(), this.__dummyDate, event);
4375 			}
4376 		}
4377 	},
4378 
4379 	{	
4380 		type:_SELECT1_, 
4381 		ref:".",
4382 		width:50,
4383 		valign:_MIDDLE_,
4384 		choices: Time_XFormItem.prototype.TIME_MINUTE_CHOICES,
4385 		labelLocation:_NONE_,
4386 		getDisplayValue:function (newValue) {
4387 			if (!(newValue instanceof Date)) newValue = new Date();
4388 			var minutes = newValue.getMinutes();
4389 			minutes = Math.round(minutes / 5) * 5;
4390 			minutes = (minutes < 10 ? "0" + minutes : "" + minutes);
4391 			return minutes;
4392 		},
4393 		elementChanged:function (minutesStr, currentDate, event) {
4394 			if (currentDate == null) currentDate = new Date();	//??? should get values of other fields???
4395 			if (this.__dummyDate == null) {
4396 				this.__dummyDate = new Date();
4397 			}
4398 			this.__dummyDate.setTime(currentDate.getTime());
4399 		
4400 			var minutes = parseInt(minutesStr);
4401 			if (!isNaN(minutes)) {
4402 				this.__dummyDate.setMinutes(minutes);
4403 			}
4404 			var parentItem = this.getParentItem();
4405 			var elementChangedMethod = parentItem.getElementChangedMethod();
4406 			if (elementChangedMethod!= null) {
4407 				elementChangedMethod.call(this.getParentItem(), this.__dummyDate, currentDate, event);
4408 			} else {
4409 				this.getForm().itemChanged(this.getParentItem(), this.__dummyDate, event);
4410 			}
4411 		}
4412 	},
4413 	
4414 	{	
4415 		type:_SELECT1_, 
4416 		ref:".",
4417 		choices: Time_XFormItem.prototype.TIME_AMPM_CHOICES,
4418 		width:50,
4419 		valign:_MIDDLE_,
4420 		labelLocation:_NONE_,
4421 		getDisplayValue:function (newValue) {
4422 			if (!(newValue instanceof Date)) newValue = new Date();
4423 			var hours = newValue.getHours();
4424 			if (hours > 11) return I18nMsg.periodPm;
4425 			return I18nMsg.periodAm;
4426 		},
4427 		elementChanged:function (ampmStr, currentDate, event) {
4428 			if (currentDate == null) currentDate = new Date();	//??? should get values of other fields???
4429 			if (this.__dummyDate == null) {
4430 				this.__dummyDate = new Date();
4431 			}
4432 			this.__dummyDate.setTime(currentDate.getTime());
4433 
4434 			var isPM = (ampmStr == I18nMsg.periodPm);
4435 			var hours = currentDate.getHours() % 12;
4436 			
4437 			this.__dummyDate.setHours(hours + (isPM ? 12 : 0));
4438 			var parentItem = this.getParentItem();
4439 			var elementChangedMethod = parentItem.getElementChangedMethod();
4440 			if (elementChangedMethod!= null) {
4441 				elementChangedMethod.call(this.getParentItem(), this.__dummyDate, currentDate, event);
4442 			} else {
4443 				this.getForm().itemChanged(this.getParentItem(), this.__dummyDate, event);
4444 			}
4445 		}
4446 	}
4447 ];
4448 
4449 
4450 
4451 
4452 /**
4453  * @class defines XFormItem type _DATETIME_
4454  * @constructor
4455  * 
4456  * @private
4457  */
4458 Datetime_XFormItem = function() {}
4459 XFormItemFactory.createItemType("_DATETIME_", "datetime", Datetime_XFormItem, Composite_XFormItem)
4460 
4461 Datetime_XFormItem._datetimeFormatToItems = function(format, dateItem, timeItem) {
4462 	var items = [];
4463 	var pattern = /{(\d+),\s*(date|time)}/;
4464 	var index = 0;
4465 	while ((index = format.search(pattern)) != -1) {
4466 		if (index > 0) {
4467 			var item = { type: _OUTPUT_, value: format.substring(0,index), valign: _CENTER_ };
4468 			items.push(item);
4469 			format = format.substring(index);
4470 		}
4471 		var result = pattern.exec(format);
4472 		items.push(result[2] == "date" ? dateItem : timeItem);
4473 		format = format.substring(result[0].length);
4474 	}
4475 	if (format.length > 0) {
4476 		var item = { type:_OUTPUT_, value: format };
4477 		items.push(item);
4478 	}
4479 	return items;
4480 }
4481 
4482 //	type defaults
4483 Datetime_XFormItem.prototype.numCols = 3;
4484 Datetime_XFormItem.prototype.items = Datetime_XFormItem._datetimeFormatToItems(
4485 	AjxMsg.xformDateTimeFormat,
4486 	{type:_DATE_, ref:".", labelLocation:_NONE_},
4487 	{type:_TIME_, ref:".", labelLocation:_NONE_}
4488 );
4489 
4490 
4491 /**
4492  * @class defines XFormItem type _WIDGET_ADAPTOR_
4493  *	An adaptor for using any random (non-DWT) widget in an xform
4494  *	NOTE: the generic implementation assumes:
4495  *			1) you'll create a method called "constructWidget()" which will construct the appropriate widget
4496  *			2) the widget has a function "insertIntoXForm(form, item, element)"
4497  *				(overide "this.insertWidget" to change)
4498  *			3) the widget has a function "updateInXForm(form, item, value, element)"
4499  *				(overide "this.updateWidget" to change)
4500  *
4501  * @constructor
4502  * 
4503  * @private
4504  */
4505 WidgetAdaptor_XFormItem = function() {}
4506 XFormItemFactory.createItemType("_WIDGET_ADAPTOR_", "widget_adaptor", WidgetAdaptor_XFormItem, XFormItem)
4507 
4508 //	type defaults
4509 WidgetAdaptor_XFormItem.prototype.writeElementDiv = true;
4510 WidgetAdaptor_XFormItem.prototype.focusable = false;
4511 //	methods
4512 
4513 // implement the following to actually construct the instance of your widget
4514 WidgetAdaptor_XFormItem.prototype.constructWidget = function () {}
4515 
4516 
4517 //
4518 //	insertElement must guarantee that each element is only inserted ONCE
4519 //
4520 WidgetAdaptor_XFormItem.prototype.insertElement = function () {
4521 	if (!this.__alreadyInserted) {
4522 		this.__alreadyInserted = true;
4523 		
4524 		// try to construct a widget
4525 		var widget = this.constructWidget();
4526 
4527 		// if we didn't get one, there's nothing to do here
4528 		if (widget == null) return;
4529 
4530 		// otherwise insert it into the form!
4531 		this.widget = widget;
4532 		this.insertWidget(this.getForm(), this.widget, this.getElement());
4533 	}
4534 }
4535 
4536 WidgetAdaptor_XFormItem.prototype.showElement = function (id) {
4537 	this.insertElement();
4538 	XForm.prototype.showElement.call(this, id);
4539 }
4540 
4541 WidgetAdaptor_XFormItem.prototype.insertWidget = function (form, widget, element) {
4542 	this.widget.insertIntoXForm(form, this, element);
4543 }
4544 
4545 WidgetAdaptor_XFormItem.prototype.updateElement = function(newValue) {
4546 	if (this.__alreadyInserted) 
4547 		this.updateWidget(newValue);
4548 }
4549 WidgetAdaptor_XFormItem.prototype.updateWidget = function (newValue) {
4550 	this.widget.updateInXForm(this.getForm(), this, newValue, this.getElement());
4551 }
4552 
4553 
4554 
4555 
4556 
4557 /**
4558  * @class defines XFormItem type _DWT_ADAPTOR_"
4559  *
4560  *	An adaptor for using any random DWT widget in an xform
4561  *
4562  *	NOTE: the generic implementation assumes:
4563  *			1) you'll create a method called "constructWidget()" which will construct the appropriate widget
4564  *			2) you'll adapt "insertWidget(form,  widget, element)" to insert the widget properly
4565  *			3) you'll adapt "updateWidget(newValue)" to update the value properly
4566  * @constructor
4567  * 
4568  * @private
4569  */
4570 Dwt_Adaptor_XFormItem = function() {}
4571 XFormItemFactory.createItemType("_DWT_ADAPTOR_", "dwt_adaptor", Dwt_Adaptor_XFormItem, WidgetAdaptor_XFormItem)
4572 
4573 //	type defaults
4574 Dwt_Adaptor_XFormItem.prototype.focusable = false;
4575 //	methods
4576 
4577 Dwt_Adaptor_XFormItem.prototype.setElementEnabled = function(enabled) {
4578 	WidgetAdaptor_XFormItem.prototype.setElementEnabled.call(this, enabled);
4579 	if (this.widget) {
4580 		this.widget.setEnabled(enabled);
4581 	}
4582 	this._enabled = enabled;
4583 }
4584 
4585 // implement the following to actually construct the instance of your widget
4586 Dwt_Adaptor_XFormItem.prototype.constructWidget = function () {}
4587 
4588 
4589 Dwt_Adaptor_XFormItem.prototype.insertWidget = function (form, widget, element) {
4590 	this.getForm()._reparentDwtObject(widget, element);
4591 }
4592 
4593 Dwt_Adaptor_XFormItem.prototype.updateWidget = function (newValue) {}
4594 
4595 Dwt_Adaptor_XFormItem.prototype.getDwtSelectItemChoices = function () {
4596 	if (this.__selOption != null) return this.__selOptions;
4597 	
4598 	var selectOptions = null;
4599 	var choices = this.getChoices();
4600 	if (choices != null) {
4601 		var selectOptions = new Array(choices.length);
4602 		for (var i = 0; i < choices.length; i++) {
4603 			var choice = choices[i];
4604 			var choiceValue = (choice instanceof Object ? choice.value : choice);
4605 			var choiceLabel = (choice instanceof Object ? choice.label : choice);
4606 			selectOptions[i] = new DwtSelectOptionData(choiceValue, choiceLabel);
4607 		}
4608 	}
4609 	this.__selOptions = selectOptions;
4610 	return this.__selOptions;
4611 };
4612 
4613 Dwt_Adaptor_XFormItem.prototype._addCssStylesToDwtWidget = function () {
4614 	var style = this.getCssStyle();
4615 	if (style != null){
4616 		var styleArr = style.split(";");
4617 		var el = this.widget.getHtmlElement();
4618 		var kp;
4619 		for (var i = 0 ; i < styleArr.length ; ++i ){
4620 			kp = styleArr[i].split(":");
4621 			if (kp.length > 0){
4622 				var key = kp[0];
4623 				if (key != null) {
4624 					key = key.replace(/^(\s)*/,"");
4625 				}
4626 				if (key == "float"){
4627 					key = (AjxEnv.isIE)? "styleFloat": "cssFloat";
4628 				}
4629 				var val = kp[1];
4630 				if (val != null) {
4631 					el.style[key] = val.replace(/^(\s)*/,"");
4632 				}
4633 			}
4634 		}
4635 	}
4636 };
4637 
4638 /**
4639  * @class defines XFormItem type  _DWT_BUTTON_
4640  * Adapts a DwtButton to work with the XForm
4641  * @constructor
4642  * 
4643  * @private
4644  */
4645 Dwt_Button_XFormItem = function() {}
4646 XFormItemFactory.createItemType("_DWT_BUTTON_", "dwt_button", Dwt_Button_XFormItem, Dwt_Adaptor_XFormItem)
4647 Dwt_Button_XFormItem.estimateMyWidth = function (label,withIcon,extraMargin) {
4648     var width;
4649     if(ZaZimbraAdmin.LOCALE=="ja"||ZaZimbraAdmin.LOCALE=="ko"||ZaZimbraAdmin.LOCALE=="zh_CN"||ZaZimbraAdmin.LOCALE=="zh_HK")
4650          width = (String(label).length)*XForm.FONT_WIDTH1 + (String(label).length)*XForm.FONT_WIDTH2 + 14;
4651     else
4652 	     width = (String(label).length/2)*XForm.FONT_WIDTH1 + (String(label).length/2)*XForm.FONT_WIDTH2 + 14;
4653 
4654     if(withIcon)
4655 		width = width + 24;
4656 	
4657 	if(extraMargin>0)
4658 		width = width + extraMargin;	
4659 	return [width,"px"].join("");
4660 }
4661 //	type defaults
4662 Dwt_Button_XFormItem.prototype.labelLocation = DwtLabel.IMAGE_LEFT | DwtLabel.ALIGN_CENTER;
4663 Dwt_Button_XFormItem.prototype.writeElementDiv = false;
4664 Dwt_Button_XFormItem.prototype.autoPadding= true;
4665 //	methods
4666 
4667 Dwt_Button_XFormItem.prototype.insertWidget = function (form, widget, element) {
4668 	this.getForm()._reparentDwtObject(widget, this.getContainer());
4669 };
4670 
4671 // implement the following to actually construct the instance of your widget
4672 Dwt_Button_XFormItem.prototype.constructWidget = function () {
4673 	var widget = this.widget = new DwtButton(this.getForm(), this.getLabelLocation(), this.getCssClass());
4674 	var height = this.getHeight();
4675 	var width = this.getWidth();
4676 	
4677 	var el = null;
4678 	if (width != null || height != null){
4679 		el = widget.getHtmlElement();
4680 		if (width != null) el.style.width = width;
4681 		if (height != null) el.style.height = height;
4682 	} 
4683 	this._addCssStylesToDwtWidget();
4684 	
4685 	var icon = this.getInheritedProperty("icon");
4686 	if(icon != null) {
4687 		widget.setImage(icon);
4688 	}
4689 	
4690 	var isToolTip = false;	
4691 	var toolTipContent = this.getInheritedProperty("toolTipContent");
4692 	if(toolTipContent != null) {
4693 		widget.setToolTipContent(toolTipContent);
4694 		isToolTip = true;
4695 	}
4696 	
4697         var labelContent = this.getLabel();
4698 	
4699 	try{
4700 		var size = Dwt.getSize(this.getContainer());
4701 		if(labelContent){
4702 			var totalCharWidth = AjxStringUtil.getWidth(labelContent);
4703 			var textLength;
4704 			if(icon){	
4705 				textLength = size.x - 42; // exclude icons, paddings, margin, borders
4706 			}
4707 			else{
4708 				textLength = size.x - 22; // exclude paddings, margin, borders
4709 			}
4710 			
4711 			if( (textLength > 0) && (totalCharWidth > textLength)){
4712 				if(!isToolTip){
4713                                 	widget.setToolTipContent(labelContent);
4714                                 }
4715 
4716 				var totalNumber = labelContent.length;
4717 				var textLength = textLength - AjxStringUtil.getWidth("..."); // three '.'
4718 				var maxNumberOfLetters= Math.floor(textLength * totalNumber / totalCharWidth);
4719 				if(textLength > 0){
4720 					labelContent = labelContent.substring(0, maxNumberOfLetters) + "...";
4721 				}
4722 			}
4723 			 
4724 			el =  widget.getHtmlElement();
4725             var tableEl = el.firstChild;
4726             var isAutoPadding = this.getInheritedProperty("autoPadding");
4727             if(!tableEl.style.width && isAutoPadding){
4728                  tableEl.style.width = "100%";
4729             }
4730 
4731 		}		
4732 	}catch(ex){
4733 	}
4734 
4735 	widget.setText(labelContent);
4736 
4737 	var onActivateMethod = this.getOnActivateMethod();
4738 	if (onActivateMethod != null) {
4739 		var ls = new AjxListener(this, onActivateMethod);
4740 		widget.addSelectionListener(ls);
4741 	}
4742 
4743 	if (this._enabled !== void 0) {
4744 		//this.widget = widget;
4745 		this.setElementEnabled(this._enabled);
4746 	}
4747 	
4748 	return widget;
4749 }
4750 
4751 Dwt_Button_XFormItem.prototype.getWidget =
4752 function (){
4753 	return this.widget ;
4754 }
4755 
4756 /**
4757  * @class defines XFormItem type _DWT_SELECT_
4758  * Adapts a DwtSelect to work with the XForm
4759  * @constructor
4760  * 
4761  * @private
4762  */
4763 Dwt_Select_XFormItem = function() {}
4764 XFormItemFactory.createItemType("_DWT_SELECT_", "dwt_select", Dwt_Select_XFormItem, Dwt_Adaptor_XFormItem)
4765 
4766 //	type defaults
4767 Dwt_Select_XFormItem.prototype.writeElementDiv = false;
4768 //	methods
4769 
4770 Dwt_Select_XFormItem.prototype.insertWidget = function (form, widget, element) {
4771 	this.getForm()._reparentDwtObject(widget, this.getContainer());
4772 }
4773 
4774 Dwt_Select_XFormItem.prototype.constructWidget = function () {
4775 	var choices = this.getDwtSelectItemChoices(this.getChoices());
4776 
4777 	var widget = this.widget = new DwtSelect(this.getForm(), choices);
4778 	var height = this.getHeight();
4779 	var width = this.getWidth();
4780 	if (width != null || height != null){
4781 		var el = widget.getHtmlElement();
4782 		if (width != null) el.style.width = width;
4783 		if (height != null) el.style.height = height;
4784 	} 
4785 	this._addCssStylesToDwtWidget();
4786 
4787 	var onChangeFunc = new Function("event", 
4788 			"var widget = event._args.selectObj;\r"
4789 		  + "value = event._args.newValue; " + this.getExternalChangeHandler()
4790 	);
4791 	var ls = new AjxListener(this.getForm(), onChangeFunc);
4792 	widget.addChangeListener(ls);
4793 
4794 	if (this._enabled !== void 0) {
4795 		//this.widget = widget;
4796 		this.setElementEnabled(this._enabled);
4797 	}
4798 	return widget;
4799 }
4800 
4801 Dwt_Select_XFormItem.prototype.updateWidget = function (newValue) {
4802 	this.widget.setSelectedValue(newValue);
4803 }
4804 
4805 Dwt_Select_XFormItem.prototype.setElementEnabled = function (enable) {
4806 	this._enabled = enable;
4807 	if (this.widget == null) return;
4808 	if (enable) {
4809 		this.widget.enable();
4810 	} else {
4811 		this.widget.disable();
4812 	}
4813 };
4814 
4815 /**	
4816  * @class defines XFormItem type _DWT_COLORPICKER_
4817  * Adapts a DwtButtonColorPicker to work with the XForm
4818  * @constructor
4819  * 
4820  * @private
4821  */
4822 Dwt_ColorPicker_XFormItem = function() {}
4823 XFormItemFactory.createItemType("_DWT_COLORPICKER_", "dwt_colorpicker", Dwt_ColorPicker_XFormItem, Dwt_Adaptor_XFormItem)
4824 
4825 Dwt_ColorPicker_XFormItem.prototype.cssStyle = "width:80px;";
4826 Dwt_ColorPicker_XFormItem.prototype.nowrap = false;
4827 Dwt_ColorPicker_XFormItem.prototype.labelWrap = true;
4828 Dwt_ColorPicker_XFormItem.prototype.constructWidget = function () {
4829     var params = {
4830         parent: this.getForm(),
4831         allowColorInput: true,
4832         noFillLabel: ZaMsg.bt_reset
4833     };
4834     var widget = new DwtButtonColorPicker (params) ;
4835 	widget.setActionTiming(DwtButton.ACTION_MOUSEDOWN);
4836 
4837     var buttonImage = this.getInheritedProperty("buttonImage") || "FontColor";
4838     widget.setImage(buttonImage);
4839 	widget.showColorDisplay(true);
4840 	widget.setToolTipContent(ZMsg.xformFontColor);
4841 	if (this.getInstanceValue() != null) {
4842 		widget.setColor(this.getInstanceValue());       
4843 	}
4844 //	widget.addSelectionListener(new AjxListener(this, this._colorOnChange)); //it cause the dwt color picker event handller is not invoked correctly
4845     widget.__colorPicker.addSelectionListener(new AjxListener(this, this._colorOnChange)) ;
4846 	return widget;
4847 }
4848 
4849 Dwt_ColorPicker_XFormItem.prototype.updateWidget = function (newValue) {
4850 	if(!this.widget)
4851 		return;
4852 		
4853 	//if(window.console && window.console.log) console.log ("new color = " + newValue) ;
4854 	if (newValue != null) {
4855 		this.widget.setColor(newValue);
4856 	}else { //ensure the empty color can be set in the UI
4857         this.widget.setColor("");            
4858     }
4859 };
4860 
4861 Dwt_ColorPicker_XFormItem.prototype._colorOnChange = function (event) {
4862 	var value = event.detail;
4863     
4864     var elementChanged = this.getElementChangedMethod();
4865 	if (elementChanged) {
4866 		elementChanged.call(this,value, this.getInstanceValue(), event);
4867 	}
4868 	var onChangeFunc = this.getOnChangeMethod();
4869 	if (onChangeFunc) {
4870 		onChangeFunc.call(this, value, event, this.getForm());	
4871 	}
4872 };
4873 
4874 /**	
4875  * @class defines XFormItem type _DWT_DATE_
4876  * Adapts a DwtCalendar to work with the XForm
4877  * @constructor
4878  * 
4879  * @private
4880  */
4881 Dwt_Date_XFormItem = function() {}
4882 XFormItemFactory.createItemType("_DWT_DATE_", "dwt_date", Dwt_Date_XFormItem, Dwt_Adaptor_XFormItem)
4883 
4884 Dwt_Date_XFormItem.prototype.cssClass =  "xform_dwt_date";
4885 
4886 
4887 //	methods
4888 
4889 Dwt_Date_XFormItem.prototype.constructWidget = function () {
4890 	var firstDayOfWeek = this.getInheritedProperty("firstDayOfWeek");
4891 	var widget = new DwtButton(this.getForm());
4892 	widget.setActionTiming(DwtButton.ACTION_MOUSEDOWN);
4893 
4894 	// ONE MENU??
4895 	var menu = this.menu = new DwtMenu(widget, DwtMenu.CALENDAR_PICKER_STYLE, null, null, this.getForm());
4896 	menu.setSize("150");
4897 	menu._table.width = "100%";
4898 	widget.setMenu(menu, true);
4899 	menu.setAssociatedObj(widget);
4900 
4901 	// For now, create a new DwtCalendar for each of the buttons, since on
4902 	// IE, I'm having trouble getting the one calendar to work.
4903 	// TODO: Figure out the IE problem.
4904 	//var cal = new DwtCalendar(menu);
4905 	var cal = new DwtCalendar({parent:menu,firstDayOfWeek:(!AjxUtil.isEmpty(firstDayOfWeek) ? firstDayOfWeek : 0)});
4906 	cal._invokingForm = this.getForm();
4907 	cal._invokingFormItemId = this.getId();
4908 	cal.setDate(new Date(), true);
4909 	cal.addSelectionListener(new AjxListener(this, this._calOnChange));
4910 	widget.__cal = cal;
4911 	return widget; 
4912 }
4913 
4914 Dwt_Date_XFormItem.prototype.updateWidget = function (newValue) {
4915 	if (newValue == null) newValue = new Date();
4916 	this.widget.setText(this.getButtonLabel(newValue));
4917 	this.widget._date = newValue;
4918 	this.widget.__cal.setDate(newValue,true);
4919 };
4920 
4921 
4922 Dwt_Date_XFormItem.prototype._calOnChange = function (event) {
4923 	var value = event.detail;
4924 	var cal = event.item;
4925 	var elemChanged = this.getElementChangedMethod();
4926 	elemChanged.call(this,value, this.getInstanceValue(), event);	
4927 };
4928 
4929 Dwt_Date_XFormItem.prototype.getButtonLabel = function (newValue) {
4930 	if (newValue == null || !(newValue instanceof Date)) return "";
4931         var formatter = AjxDateFormat.getDateInstance(AjxDateFormat.NUMBER);
4932 	return formatter.format(newValue) ;//(newValue.getMonth()+1) + "/" + newValue.getDate() + "/" + (newValue.getFullYear());
4933 };
4934 
4935 
4936 /**
4937  * @class defines XFormItem type _DWT_TIME_
4938  * Adapts a DwtTimeSelect to work with the XForm
4939  * @constructor
4940  *
4941  * @private
4942  */
4943 Dwt_Time_XFormItem = function() {}
4944 XFormItemFactory.createItemType("_DWT_TIME_", "dwt_time", Dwt_Time_XFormItem, Dwt_Adaptor_XFormItem)
4945 
4946 Dwt_Time_XFormItem.prototype.cssClass =  "xform_dwt_time";
4947 
4948 Dwt_Time_XFormItem.prototype.constructWidget = function () {
4949 	var widget = new DwtTimeSelect(this.getForm());
4950     widget.addChangeListener(this._onChange.bind(this));
4951     return widget;
4952 };
4953 
4954 Dwt_Time_XFormItem.prototype.updateWidget = function (newValue) {
4955 	if (newValue == null) {
4956         newValue = new Date();
4957         newValue.setHours(0, 0, 0, 0);
4958     }
4959 	this.widget.set(newValue);
4960 };
4961 
4962 Dwt_Time_XFormItem.prototype._onChange = function (event) {
4963 	var value = this.widget.getValue();
4964 	var elemChanged = this.getElementChangedMethod();
4965 	elemChanged.call(this, value, this.getInstanceValue(), event);
4966 };
4967 
4968 
4969 /**
4970  * @class defines XFormItem type _DWT_DATETIME_
4971  * Composes a _DWT_DATE_ and a (non-DWT) _TIME_ to make a date/time editor, just for kicks.
4972  * @constructor
4973  * 
4974  * @private
4975  */
4976 Dwt_Datetime_XFormItem = function() {}
4977 XFormItemFactory.createItemType("_DWT_DATETIME_", "dwt_datetime", Dwt_Datetime_XFormItem, Composite_XFormItem)
4978 
4979 //	type defaults
4980 Dwt_Datetime_XFormItem.prototype.numCols = 3;
4981 Dwt_Datetime_XFormItem.prototype.useParentTable = false;
4982 Dwt_Datetime_XFormItem.prototype.cssClass =  "xform_dwt_datetime";
4983 Dwt_Datetime_XFormItem.initialize = function(){
4984    Dwt_Datetime_XFormItem.prototype.items = Datetime_XFormItem._datetimeFormatToItems(
4985 	AjxMsg.xformDateTimeFormat,
4986 	{type:_DWT_DATE_, ref:".", labelLocation:_NONE_, errorLocation:_PARENT_,
4987 	 elementChanged:
4988 	 function (newDate, currentDate, event) {
4989 	 	currentDate = currentDate ? currentDate : new Date();
4990 		newDate.setHours(currentDate.getHours(), currentDate.getMinutes(), currentDate.getSeconds(), 0);
4991 		var elementChangedMethod = this.getParentItem().getElementChangedMethod();
4992 		if(elementChangedMethod)
4993 			elementChangedMethod.call(this.getParentItem(),newDate, currentDate, event);
4994 	 }
4995 	},
4996 	{type:_DWT_TIME_, ref:".", labelLocation:_NONE_, errorLocation:_PARENT_,
4997 	 elementChanged:
4998 	 function (newDate, currentDate, event) {
4999 		currentDate = currentDate ? currentDate : new Date();
5000 		//If time is changed set the full year of new date with current date.
5001 		newDate.setFullYear(currentDate.getFullYear(), currentDate.getMonth(), currentDate.getDate());
5002 		var elementChangedMethod = this.getParentItem().getElementChangedMethod();
5003 		if(elementChangedMethod)
5004 			elementChangedMethod.call(this.getParentItem(),newDate, currentDate, event);
5005 	 }
5006 	}
5007 );
5008 }
5009 Dwt_Datetime_XFormItem.initialize();
5010 
5011 
5012 /**
5013  * @class defines XFormItem type _DWT_LIST_
5014  * @constructor
5015  * 
5016  * @private
5017  */
5018 Dwt_List_XFormItem = function() {}
5019 XFormItemFactory.createItemType("_DWT_LIST_", "dwt_list", Dwt_List_XFormItem, Dwt_Adaptor_XFormItem)
5020 
5021 //	type defaults
5022 Dwt_List_XFormItem.prototype.writeElementDiv = false;
5023 Dwt_List_XFormItem.prototype.widgetClass = DwtListView;
5024 Dwt_List_XFormItem.prototype.bmolsnr = true;
5025 Dwt_List_XFormItem.prototype.getOnSelectionMethod = function() {
5026 	return this.cacheInheritedMethod("onSelection","$onSelection","event");
5027 }
5028 
5029 
5030 Dwt_List_XFormItem.prototype.constructWidget = function () {
5031 	var headerList = this.getInheritedProperty("headerList");
5032 	var listClass = this.getInheritedProperty("widgetClass");
5033 	
5034 	var hideHeader = this.getInheritedProperty("hideHeader");
5035 
5036 	var widget = new listClass(this.getForm(), this.getCssClass(), null, ((hideHeader!=undefined && hideHeader==true ) ? null : headerList));
5037 	var emptyText = this.getInheritedProperty("emptyText");
5038 	if(emptyText !=null || emptyText==="")
5039 		widget.emptyText = emptyText;
5040 		
5041 	if(hideHeader != undefined) {
5042 		widget.hideHeader = hideHeader;
5043 		if(hideHeader && headerList) {
5044 			widget._headerList = headerList;
5045 		}
5046 	}	
5047 
5048 	var multiselect = this.getInheritedProperty("multiselect");
5049 	if(multiselect != undefined) {
5050 		widget.setMultiSelect(multiselect);
5051 	}
5052 	if(this.cacheInheritedMethod("getCustomHeight", "$getCustomHeight") && this.cacheInheritedMethod("getCustomWidth", "$getCustomWidth")) {	
5053 		var height = this.cacheInheritedMethod("getCustomHeight", "$getCustomHeight").call(this);
5054 		var width = this.cacheInheritedMethod("getCustomWidth", "$getCustomWidth").call(this);
5055 		if(width && height)
5056 			widget.setSize(width, height);		
5057 	} else {			
5058 		//set the width height here.
5059 		var width = this.getWidth();
5060 		var height = this.getHeight();
5061 		
5062 		if(width && height)
5063 			widget.setSize(width, height);
5064 		
5065 		//set the listDiv height
5066 		if (height && height != Dwt.DEFAULT) {
5067 			widget.setListDivHeight (height) ;
5068 		}
5069 	}		
5070 	
5071 	// make sure the user defined listener is called 
5072 	// before our selection listener.
5073 	var selMethod = this.getOnSelectionMethod();
5074 	if (selMethod) {
5075 		widget.addSelectionListener(new AjxListener(this, selMethod));
5076 	} else {
5077 		var localLs = new AjxListener(this, this._handleSelection);
5078 		widget.addSelectionListener(localLs);
5079 	}
5080 	//check if createPopupMenu method is defined
5081 	var createPopupMenumethod = this.cacheInheritedMethod("createPopupMenu","$createPopupMenu","parent");
5082 	if(createPopupMenumethod != null) {
5083 		createPopupMenumethod.call(this, widget);
5084 	}
5085 	var form=this.getForm();
5086 	var container = (form.parent instanceof DwtControl) ? form.parent : DwtControl.fromElementId(window._dwtShellId);
5087 	if(container) {
5088 		if(this.cacheInheritedMethod("resizeHdlr", "$resizeHdlr") && this.cacheInheritedMethod("getCustomHeight", "$getCustomHeight") && this.cacheInheritedMethod("getCustomWidth", "$getCustomWidth")) {
5089 			container.addControlListener(new AjxListener(this, this.cacheInheritedMethod("resizeHdlr", "$resizeHdlr")));
5090 		}
5091 	}
5092 
5093 	return widget;
5094 };
5095 
5096 Dwt_List_XFormItem.prototype.resizeHdlr = 
5097 function() {
5098 	try {
5099 		var height = this.cacheInheritedMethod("getCustomHeight", "$getCustomHeight").call(this);
5100 		var width = this.cacheInheritedMethod("getCustomWidth", "$getCustomWidth").call(this);		
5101 		this.widget.setSize(width,height);
5102 	} catch (ex) {
5103 		alert(ex);
5104 	}
5105 };
5106 
5107 
5108 Dwt_List_XFormItem.prototype.getSelection = function () {
5109 	return this.widget.getSelection();
5110 };
5111 
5112 Dwt_List_XFormItem.prototype._handleSelection = function (event) {
5113 	var modelItem = this.getModelItem();
5114 	var event = new DwtXModelEvent(this.getInstance(), modelItem, null, null);
5115 	modelItem.notifyListeners(DwtEvent.XFORMS_VALUE_CHANGED, event);
5116 };
5117 
5118 Dwt_List_XFormItem.prototype.insertWidget = function (form, widget, element) {
5119 	this.getForm()._reparentDwtObject(widget, this.getContainer());
5120 };
5121 
5122 Dwt_List_XFormItem.prototype.updateWidget = function (newValue) {
5123 	if (typeof (newValue) != 'undefined') {
5124 		this.setItems(newValue);
5125 	}
5126 };
5127 
5128 //the method used to compare the contents of the list array.
5129 //because object  array  join alwasy return [Object Object]
5130 //we need to compare the property values
5131 //we should return once we find the differences
5132 //Assume that itemArray and existingArr has the same length
5133 Dwt_List_XFormItem.isItemsChanged = function (itemArray, existingArr) {
5134     var isChanged = false ;
5135     if ((itemArray._version !=null && existingArr._version !=null && (itemArray._version != existingArr._version ))
5136 			|| (itemArray.length != existingArr.length)) {
5137         isChanged = true ;
5138     } else {
5139         var rows = [] ;
5140         var existingRows = [] ;
5141         for (var i=0; i < itemArray.length; i ++) {
5142             if (itemArray[i] instanceof Object)  {
5143                 for (var p in itemArray[i]) {
5144                     rows.push (itemArray[i][p]) ;
5145                 }
5146             } else {
5147                 rows.push(itemArray[i]) ;
5148             }
5149 
5150             if (existingArr[i] instanceof Object)  {
5151                 for (var p1 in existingArr[i]) {
5152                     existingRows.push (existingArr[i][p1]) ;
5153                 }
5154             } else {
5155                 existingRows.push(existingArr[i]) ;
5156             }
5157 
5158             if (rows.join() != existingRows.join()) {
5159                 isChanged = true;
5160                 break ;
5161             }else{
5162                 rows = [];
5163                 existingRows = [] ;
5164             }
5165         }
5166     }
5167 
5168     return isChanged ;
5169 }
5170 Dwt_List_XFormItem.prototype.setItems = function (itemArray){
5171 	var list = this.widget.getList();
5172 	var existingArr = new Array();
5173 	var tmpArr = new Array();
5174 	if (list) {
5175 		existingArr = list.getArray();
5176 	} 
5177 	tmpArr = new Array();
5178 	var defaultColumnSort = this.getInheritedProperty("defaultColumnSortable") ;
5179 	if (itemArray && itemArray.length > 0) {	
5180 		//we have to compare the objects, because XForm calls this method every time an item in the list is selected
5181 		if (this.getForceUpdate() || Dwt_List_XFormItem.isItemsChanged(itemArray, existingArr)) {
5182             var preserveSelection = this.getInheritedProperty("preserveSelection");
5183 			var selection = null;
5184 			if(preserveSelection) {
5185 				selection = this.widget.getSelection();
5186 			}		
5187 			var cnt=itemArray.length;
5188 			for(var i = 0; i< cnt; i++) {
5189 				tmpArr.push(itemArray[i]);		
5190 			}
5191 			//add the default sort column
5192 			this.widget.set(AjxVector.fromArray(tmpArr), defaultColumnSort);
5193 			if(itemArray._version != undefined && itemArray._version != null)
5194 				this.widget.getList().getArray()._version = itemArray._version;
5195 				
5196 			if(preserveSelection && selection) {
5197 				this.widget.setSelectedItems(selection);
5198 			}
5199 		}
5200 	}else{
5201 		//display the empty list (no result html)
5202 		this.widget.set(AjxVector.fromArray([]), defaultColumnSort); 
5203 	}
5204 };
5205 
5206 Dwt_List_XFormItem.prototype.appendItems = function (itemArray){ 
5207 	this.widget.addItems(itemArray);
5208 };
5209 
5210 
5211 /**
5212  * @class defines XFormItem type _BUTTON_GRID_
5213  * @constructor
5214  * 
5215  * @private
5216  */
5217 Button_Grid_XFormItem = function() {}
5218 XFormItemFactory.createItemType("_BUTTON_GRID_", "button_grid", Button_Grid_XFormItem, WidgetAdaptor_XFormItem)
5219 
5220 //	type defaults
5221 Button_Grid_XFormItem.prototype.numCols = 5;
5222 Button_Grid_XFormItem.prototype.cssClass = "xform_button_grid_medium";
5223 Button_Grid_XFormItem.prototype.forceUpdate = true;
5224 
5225 
5226 //	methods
5227 Button_Grid_XFormItem.prototype.constructWidget = function () {
5228 	var changeHandler = this.getExternalChangeHandler();
5229 	var attributes = {
5230 		numCols:this.getNumCols(),
5231 		choices:choices.getChoiceObject(),
5232 		cssClass:this.getCssClass(),
5233 		onChange:changeHandler,
5234 		addBracketingCells:(this.getAlign() == _CENTER_)
5235 	}
5236 	var multiple = this.getMultiple();
5237 	if (multiple !== null) attributes.multiple = multiple;
5238 	return new ButtonGrid(attributes);
5239 }
5240 
5241 
5242 
5243 /**
5244  * @class defines XFormItem type _DWT_CHOOSER_
5245  * @constructor
5246  * 
5247  * @private
5248  */
5249 Dwt_Chooser_XFormItem = function() {}
5250 XFormItemFactory.createItemType("_DWT_CHOOSER_", "chooser", Dwt_Chooser_XFormItem, Dwt_Adaptor_XFormItem);
5251 Dwt_Chooser_XFormItem.prototype.widgetClass = DwtChooser;
5252 Dwt_Chooser_XFormItem.prototype.listSize = 100;
5253 /*
5254 NOTE: this won't work because attributes.ref is accessed before this
5255 method is called in XFormItemFactory#createItem.
5256 Dwt_Chooser_XFormItem.prototype._setAttributes = function(attributes) {
5257 	// allows "targetRef" alias for "ref" attribute
5258 	if (!attributes.ref && attributes.targetRef) {
5259 		attributes.ref = attributes.targetRef;
5260 	}
5261 	XFormItem.prototype._setAttributes.call(this, attributes);
5262 }
5263 */
5264 Dwt_Chooser_XFormItem.prototype.getSorted = function() {
5265 	return this.getInheritedProperty("sorted");
5266 }
5267 Dwt_Chooser_XFormItem.prototype.getListCssClass = function() {
5268 	return this.getInheritedProperty("listCssClass");
5269 }
5270 
5271 Dwt_Chooser_XFormItem.prototype.getTargetListCssClass = function() {
5272 	return this.getInheritedProperty("targetListCssClass");
5273 }
5274 
5275 Dwt_Chooser_XFormItem.prototype.getSourceInstanceValue = function() {
5276 	var items = this.getModel().getInstanceValue(this.getInstance(), this.getInheritedProperty("sourceRef"));
5277 	//items must be either array or vector
5278 	if (! items) {
5279 		items = new AjxVector ();
5280 	}else if (typeof items == "string") {
5281 		items = new Array(items);
5282 	}
5283 	return items ;
5284 }
5285 
5286 Dwt_Chooser_XFormItem.prototype.getTargetInstanceValue = function() {
5287 	var items = this.getInstanceValue();
5288 	if (! items) {
5289 		items = new AjxVector ();
5290 	}else if (typeof items == "string") {
5291 		items = new Array(items);
5292 	}
5293 	return items ;
5294 }
5295 
5296 Dwt_Chooser_XFormItem.prototype._handleStateChange = function(event) {
5297 	var form = this.getForm();
5298 	var id = this.getId();
5299 	var widget = this.getWidget();
5300 	var value = widget.getItems();
5301 	this._skipUpdate = true;
5302 	form.itemChanged(id, value);
5303 	this._skipUpdate = false;
5304 }
5305 
5306 Dwt_Chooser_XFormItem.prototype.constructWidget = function() {
5307 	var form = this.getForm();
5308 	var cssClass = this.getCssClass();
5309 	var sourceListCssClass = this.getListCssClass();
5310 	var targetListCssClass = this.getTargetListCssClass();
5311 	var widgetClass = this.getInheritedProperty("widgetClass");
5312 	if (sourceListCssClass && !targetListCssClass) {
5313 		targetListCssClass = sourceListCssClass;
5314 	}
5315 	var listSize = this.getInheritedProperty("listSize");
5316 	var params = {parent: form, 
5317 				className: cssClass, 
5318 				slvClassName: sourceListCssClass,
5319 				tlvClassName: targetListCssClass, 
5320 				layoutStyle: (this.getInheritedProperty("layoutStyle") ? this.getInheritedProperty("layoutStyle") : DwtChooser.HORIZ_STYLE),
5321 				listSize: listSize, 
5322 				sourceEmptyOk: true, 
5323 				allButtons: true,
5324 				listWidth: (this.getInheritedProperty("listWidth") ? this.getInheritedProperty("listWidth") : null),
5325 				listHeight: (this.getInheritedProperty("listHeight") ? this.getInheritedProperty("listHeight") : null),
5326 				tableWidth: (this.getInheritedProperty("tableWidth") ? this.getInheritedProperty("tableWidth") : null),
5327 				labelWidth: (this.getInheritedProperty("labelWidth") ? this.getInheritedProperty("labelWidth") : null),
5328 				splitButtons:this.getInheritedProperty("splitButtons")	
5329 				};
5330 	
5331 	return new widgetClass(params);
5332 }
5333 
5334 Dwt_Chooser_XFormItem.prototype.updateWidget = function(newvalue, dedup, compareFunc) {
5335 	if (this._skipUpdate) {
5336 		return;
5337 	}
5338 
5339 	if (this._stateChangeListener) {
5340 		this.widget.removeStateChangeListener(this._stateChangeListener);
5341 	}
5342 	else {
5343 		this._stateChangeListener = new AjxListener(this, Dwt_Chooser_XFormItem.prototype._handleStateChange)
5344 	}
5345 
5346 	var origSourceItems = this.getSourceInstanceValue();
5347 	var sourceItems;
5348 	
5349 	if(origSourceItems instanceof Array) { 
5350 		var _tmpSrcItems = [];
5351 		var cnt = origSourceItems.length;
5352 		for(var i=0; i<cnt;i++) {
5353 			_tmpSrcItems.push(origSourceItems[i]);
5354 		}
5355 		sourceItems = AjxVector.fromArray(_tmpSrcItems);
5356 	} else {
5357 		sourceItems = origSourceItems.clone();
5358 	}
5359 	
5360 	var targetItems = this.getTargetInstanceValue();
5361 	if(targetItems instanceof Array) targetItems = AjxVector.fromArray(targetItems);	
5362 	if(dedup) {
5363 		var cnt = targetItems.size();
5364 		for(var i=0; i < cnt; i++) {
5365 			if(compareFunc) {
5366 			 	var ix=sourceItems.indexOfLike(targetItems.get(i),compareFunc);
5367 			 	if(ix > -1) {
5368 					sourceItems.removeAt(ix);
5369 			 	}
5370 			} else {
5371 			 	var ix=sourceItems.indexOf(targetItems.get(i));
5372 			 	if(ix > -1) {
5373 					sourceItems.removeAt(ix);
5374 			 	}
5375 			}
5376 		}
5377 	}
5378 	
5379 	var sorted = this.getSorted();
5380 	if (sorted) {
5381 		sourceItems.sort();
5382 		targetItems.sort();
5383 	}
5384 
5385 	this.widget.setItems(sourceItems);
5386 	this.widget.setItems(targetItems, DwtChooserListView.TARGET);
5387 
5388 	this.widget.addStateChangeListener(this._stateChangeListener);
5389 }
5390 
5391 //
5392 // XFormItem class: "alert"
5393 //
5394 
5395 Dwt_Alert_XFormItem = function() {}
5396 XFormItemFactory.createItemType("_DWT_ALERT_", "alert", Dwt_Alert_XFormItem, Dwt_Adaptor_XFormItem);
5397 
5398 Dwt_Alert_XFormItem.prototype.colSpan = "*";
5399 Dwt_Alert_XFormItem.prototype.labelLocation = _NONE_;
5400 
5401 Dwt_Alert_XFormItem.prototype.getStyle = function() {
5402 	return this.getInheritedProperty("style");
5403 }
5404 Dwt_Alert_XFormItem.prototype.getIconVisible = function() {
5405 	return this.getInheritedProperty("iconVisible");
5406 }
5407 Dwt_Alert_XFormItem.prototype.getTitle = function() {
5408 	return this.getInheritedProperty("title");
5409 }
5410 Dwt_Alert_XFormItem.prototype.getContent = function() {
5411 	return this.getInheritedProperty("content");
5412 }
5413 Dwt_Alert_XFormItem.prototype.getAlertCssClass = function() {
5414 	return this.getInheritedProperty("alertCssClass");
5415 }
5416 
5417 Dwt_Alert_XFormItem.prototype.constructWidget = function() {
5418 	var style = this.getStyle();
5419 	var iconVisible = this.getIconVisible();
5420 	var title = this.getTitle();
5421 	var content = this.getContent();
5422 	var alertCssClass = this.getAlertCssClass();
5423 	
5424 	var form = this.getForm();
5425 	var alert = new DwtAlert(form, alertCssClass);
5426 	
5427 	alert.setStyle(style);
5428 	alert.setIconVisible(iconVisible);
5429 	alert.setTitle(title);
5430 	alert.setContent(content);
5431 	
5432 	// bug fix wrong IE box model when conculating the width
5433 	if(AjxEnv.isIE){
5434 		try{	
5435 			var htmlElement = alert.getHtmlElement();
5436                 	var size = Dwt.getSize(htmlElement);
5437 		
5438 			var container = this.getContainer();
5439 			var containerSize =  Dwt.getSize(container);
5440 			
5441 			var style = DwtCssStyle.getComputedStyleObject(htmlElement);	
5442 		        var bl = parseInt(style.borderLeftWidth)     || 1;
5443                         var br = parseInt(style.borderRightWidth)    || 1;
5444                         var pl = parseInt(style.paddingLeft)         || 5;
5445                         var pr = parseInt(style.paddingRight)        || 5;
5446                         var ml = parseInt(style.marginLeft)          || 5;
5447                         var mr = parseInt(style.marginRight)         || 5;
5448                         var extraWidth = bl + br + pl + pr + ml + mr;
5449 			
5450 			if(containerSize.x > extraWidth){
5451 				size.x = containerSize.x - extraWidth;
5452 				Dwt.setSize(htmlElement, size.x, size.y);
5453 			}
5454 		}catch(ex){
5455 		}
5456 	}	
5457 	return alert;
5458 }
5459 
5460 Dwt_Alert_XFormItem.prototype.updateWidget = function(newvalue) {
5461 	// nothing
5462 	var content = this.getContent();
5463 	if(!content && newvalue) {
5464 		this.getWidget().setContent(newvalue);
5465 	}
5466 }
5467 
5468 //
5469 // XFormItem class: "dwt_tab_bar" ("tab_bar")
5470 //
5471 
5472 Dwt_TabBar_XFormItem = function() {}
5473 XFormItemFactory.createItemType("_TAB_BAR_", "tab_bar", Dwt_TabBar_XFormItem, Dwt_Adaptor_XFormItem);
5474 Dwt_TabBar_XFormItem.prototype.colSpan = "*";
5475 Dwt_TabBar_XFormItem.prototype.labelLocation = _NONE_;
5476 Dwt_TabBar_XFormItem.prototype.cssStyle = "margin-right: 5px";
5477 
5478 // NOTE: Overriding the _TAB_BAR_
5479 //XFormItemFactory.registerItemType(_TAB_BAR_, "tab_bar", Dwt_TabBar_XFormItem);
5480 
5481 Dwt_TabBar_XFormItem.prototype._value2tabkey;
5482 Dwt_TabBar_XFormItem.prototype._tabkey2value;
5483 
5484 Dwt_TabBar_XFormItem.prototype._stateChangeListener;
5485 
5486 Dwt_TabBar_XFormItem.prototype.getChoices = function() {
5487 	return this.getInheritedProperty("choices");
5488 }
5489 
5490 Dwt_TabBar_XFormItem.prototype._handleStateChange = function(event) {
5491 	var form = this.getForm();
5492 	var widget = this.getWidget();
5493 	
5494 	var tabKey = widget.getCurrentTab();
5495 	var newvalue = this._tabkey2value[tabKey];
5496 	
5497 	var id = this.getId();
5498 	//release the focus  
5499 	form.releaseFocus() ;
5500 	form.itemChanged(id, newvalue, event, true);
5501 }
5502 
5503 Dwt_TabBar_XFormItem.prototype.constructWidget = function() {
5504 	var form = this.getForm();
5505 	var cssClass = this.getCssClass();
5506 	var btnCssClass = this.getInheritedProperty("buttonCssClass");	
5507 	
5508 	var widget = new DwtTabBarFloat(form, cssClass, btnCssClass);
5509     this._value2tabkey = {};
5510 	this._tabkey2value = {};
5511 	
5512 	var choices = this.getChoices();
5513 	if(choices.constructor == XFormChoices) {
5514 		this.choices = choices;
5515 		var listener = new AjxListener(this, this.dirtyDisplay);
5516 		choices.addListener(DwtEvent.XFORMS_CHOICES_CHANGED, listener);	
5517 		
5518 		var values = this.getNormalizedValues();
5519 		var labels = this.getNormalizedLabels();
5520 		var cnt = values.length;
5521 		for (var i = 0; i < cnt; i++) {
5522 			// NOTE: DwtTabView keeps its own internal keys that are numerical
5523 			this._value2tabkey[values[i]] = i + 1;
5524 			this._tabkey2value[i + 1] = values[i];
5525 			widget.addButton(i+1, labels[i]);
5526             widget.getButton(i+1).getHtmlElement().style ["paddingRight"] = "2px" ;
5527 		}			
5528 	} else {
5529 		var cnt = choices.length;
5530 		for (var i = 0; i < cnt; i++) {
5531 			var choice = choices[i];
5532 			// NOTE: DwtTabView keeps its own internal keys that are numerical
5533 			this._value2tabkey[choice.value] = i + 1;
5534 			this._tabkey2value[i + 1] = choice.value;
5535 			widget.addButton(i+1, choice.label);
5536             widget.getButton(i+1).getHtmlElement().style ["paddingRight"] = "2px" ;
5537 		}
5538 	}
5539 	
5540 	return widget;
5541 }
5542 
5543 Dwt_TabBar_XFormItem.prototype.updateWidget = function(newvalue) {
5544 	if (this.widget.isUpdating) {
5545 		this.widget.isUpdating = false;
5546 		return;
5547 	}
5548 
5549 	if (this._stateChangeListener) {
5550 		this.widget.removeStateChangeListener(this._stateChangeListener);
5551 	}
5552 	else {
5553 		this._stateChangeListener = new AjxListener(this, Dwt_TabBar_XFormItem.prototype._handleStateChange);
5554 	}
5555 	
5556 	var tabKey = this._value2tabkey[newvalue];
5557 	if (tabKey != this.widget.getCurrentTab()) {
5558 		this.widget.openTab(tabKey);
5559 	}
5560 
5561 	this.widget.addStateChangeListener(this._stateChangeListener);
5562 }
5563 
5564 Dwt_TabBar_XFormItem.prototype.dirtyDisplay = function() {
5565 	this.$normalizedChoices = null; //nuke these since they are out of date at this point
5566 	if(this.choices && this.choices.constructor == XFormChoices) {
5567 		var labels = this.getNormalizedLabels();
5568 		var values = this.getNormalizedValues();
5569 		var cnt = labels.length;
5570 		for(var i=0;i<cnt;i++) {
5571 			var tabKey = this._value2tabkey[values[i]];
5572 			if(tabKey) {
5573 				var btn = this.widget.getButton(tabKey);
5574 				if(btn) {
5575 					btn.setText(labels[i]);
5576 				}
5577 			}
5578 		}
5579 	}
5580 	this._choiceDisplayIsDirty = true;
5581 	delete this.$normalizedChoices;	
5582 }
5583 
5584 //
5585 // XFormItem class: "alert"
5586 //
5587 
5588 Dwt_ProgressBar_XFormItem = function() {}
5589 XFormItemFactory.createItemType("_DWT_PROGRESS_BAR_", "dwt_progress_bar", Dwt_ProgressBar_XFormItem, Dwt_Adaptor_XFormItem);
5590 
5591 Dwt_ProgressBar_XFormItem.prototype.constructWidget = function() {
5592 	var form = this.getForm();
5593 	var widget = new DwtProgressBar(form, null);
5594 	var maxvalue = this.getInheritedProperty("maxValue");
5595 	if(!maxvalue) {
5596 		this.maxValueRef = this.getInheritedProperty("maxValueRef");
5597 		maxvalue = this.getModel().getInstanceValue(this.getInstance(), this.maxValueRef)
5598 	}
5599 	widget.setMaxValue(maxvalue);
5600 	
5601 	var progressCssClass = this.getInheritedProperty("progressCssClass");
5602 	if(progressCssClass) {
5603 		widget.setProgressCssClass(progressCssClass);
5604 	}
5605 	
5606 	var wholeCssClass = this.getInheritedProperty("wholeCssClass");
5607 	if(wholeCssClass) {
5608 		widget.setWholeCssClass(wholeCssClass);
5609 	}	
5610 	return widget;
5611 }
5612 
5613 Dwt_ProgressBar_XFormItem.prototype.updateWidget = function(newvalue) {
5614 	// nothing
5615 	if(!newvalue)
5616 		newvalue=0;
5617 	if(this.maxValueRef) {
5618 		maxvalue = this.getModel().getInstanceValue(this.getInstance(), this.maxValueRef)
5619 		this.getWidget().setMaxValue(maxvalue);	
5620 	}
5621 	this.getWidget().setValue(newvalue);
5622 }
5623