1 /*
  2  * ***** BEGIN LICENSE BLOCK *****
  3  * Zimbra Collaboration Suite Web Client
  4  * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2013, 2014, 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, 2013, 2014, 2016 Synacor, Inc. All Rights Reserved.
 21  * ***** END LICENSE BLOCK *****
 22  */
 23 
 24 
 25 /**
 26  * Creates a property page.
 27  * @class
 28  * @constructor
 29  * This class represents a page (view) for working with properties. It provides ability to
 30  * keep track of any changes in the form fields on the page.
 31  * 
 32  * @author Greg Solovyev
 33  * 
 34  * @param	{hash}	params		a hash of parameters
 35  * 
 36  * @extends		DwtComposite
 37  */
 38 DwtPropertyPage = function(params) {
 39 	if (arguments.length == 0) return;
 40 	params = Dwt.getParams(arguments, DwtPropertyPage.PARAMS);
 41 	params.className = params.className || "DwtPropertyPage";
 42 	DwtComposite.call(this, params);
 43 	this._fieldIds = new Object();
 44 	this._fildDivIds = new Object();
 45 	this._isDirty = false;
 46 	this._tabGroup = new DwtTabGroup(this.toString());
 47 };
 48 
 49 DwtPropertyPage.prototype = new DwtComposite;
 50 DwtPropertyPage.prototype.constructor = DwtPropertyPage;
 51 
 52 DwtPropertyPage.prototype.toString = function() {
 53 	return "DwtPropertyPage";
 54 };
 55 
 56 DwtPropertyPage.PARAMS = DwtComposite.PARAMS;
 57 
 58 /**
 59  * Sets the value of the dirty flag.
 60  * 
 61  * @param {boolean}	isD	
 62  * 
 63  * @private
 64  */
 65 DwtPropertyPage.prototype.setDirty = 
 66 function (isD) {
 67 	this._isDirty = isD;
 68 }
 69 
 70 /**
 71  * @return boolean _isDirty flag
 72  * isDirty indicates whether the user changed any data on the page after the page was initialized
 73  * 
 74  * @private
 75  */
 76 DwtPropertyPage.prototype.isDirty = 
 77 function () {
 78 	return this._isDirty;
 79 }
 80 
 81 DwtPropertyPage.prototype.getTabGroupMember =
 82 function (){
 83 	return this._tabGroup;
 84 };
 85 
 86 /**
 87  * @param field either key to the field ID in the _fieldIds or reference to the field
 88  * 
 89  * @private
 90  */
 91 DwtPropertyPage.prototype._installOnKeyUpHandler = 
 92 function(field, func) {
 93 	if (!field)	return;
 94 	
 95 	var e = null;
 96 	e = document.getElementById(this._fieldIds[field]);
 97 	if (e) {
 98 		Dwt.setHandler(e, DwtEvent.ONKEYUP, func ? func : this._onKeyUp);
 99 		e._view = this;
100 		e._field = field;
101 	}
102 }
103 
104 /**
105  * @param field either key to the field ID in the _fieldIds or reference to the field
106  * 
107  * @private
108  */
109 DwtPropertyPage.prototype._installOnClickHandler = 
110 function(field, func) {
111 	if (!field) return;
112 	
113 	var e = document.getElementById(this._fieldIds[field]);
114 	if (e) {
115 		Dwt.setHandler(e, DwtEvent.ONCLICK, func ? func : this._onClick);
116 		e._view = this;
117 		e._field = field;
118 	}
119 }
120 
121 DwtPropertyPage.prototype._onClick =
122 function(ev) {
123 	this._view.setDirty(true);
124 	return true;
125 }
126 
127 DwtPropertyPage.prototype._onKeyUp =
128 function(ev) {
129 	this._view.setDirty(true);
130 	return true;
131 }
132 
133 /**
134  * @param field either key to the field ID in the _fieldIds or reference to the field
135  * 
136  * @private
137  */
138 DwtPropertyPage.prototype._installOnChangeHandler = 
139 function(field, func) {
140 	if (!field) return;
141 	
142 	var e = null;
143 	e = document.getElementById(this._fieldIds[field]);
144 	if(e) {
145 		Dwt.setHandler(e, DwtEvent.ONCHANGE, func ? func : this._onChange);
146 		e._view = this;
147 		e._field = field;
148 	}
149 }
150 
151 DwtPropertyPage._onChange =
152 function(ev) {
153 	this._view.setDirty(true);
154 	return true;
155 }
156 
157 DwtPropertyPage.prototype._onChange2 =
158 function(ev) {
159 	this.setDirty(true);
160 	return true;
161 }
162 
163 DwtPropertyPage.prototype._addDwtSelectEntryRow =
164 function(field, title, html, idx, titleSize) {
165 	var tSize = "30ex";
166 	if(titleSize)
167 		tSize = titleSize;
168 		
169 	html[idx++] = "<tr valign='center'>";
170 	idx = this._addDwtSelectEntryCell(field, title, html, idx, tSize);
171 	html[idx++] = "</tr>";
172 	return idx;
173 }
174 
175 DwtPropertyPage.prototype._addDwtSelectEntryCell =
176 function(field, title, html, idx, titleWidth) {
177 	var id = Dwt.getNextId();
178 	this._fieldIds[field] = id;
179 	if(title) {
180 		html[idx++] = "<td align='left' style='width:" + titleWidth + "'>";
181 		html[idx++] = AjxStringUtil.htmlEncode(title) + ":";
182 		html[idx++] = "</td>";
183 	}
184 	html[idx++] = "<td align='left'>";
185 	html[idx++] = "<div id='" + id + "'></div></td>";
186 	return idx;
187 }
188 
189 DwtPropertyPage.prototype._addBoolEntryRow =
190 function(field, title, html, idx, titleWidth) {
191 	html[idx++] = "<tr valign='center'>";
192 	idx = this._addBoolEntryCell(field, title, html, idx, titleWidth);
193 	html[idx++] = "</tr>";
194 	return idx;
195 }
196 
197 DwtPropertyPage.prototype._addBoolEntryCell =
198 function(field, title, html, idx, titleWidth) {
199 	var id = Dwt.getNextId();
200 	this._fieldIds[field] = id;
201 	var tWidth = "20ex";
202 	if(titleWidth)
203 		tWidth = titleWidth;	
204 		
205 	if(title) {
206 		html[idx++] = "<td style='width:" + tWidth + ";' align='left'>";
207 		html[idx++] = AjxStringUtil.htmlEncode(title) + ":";
208 		html[idx++] = "</td>";
209 	}
210 	html[idx++] = "<td align='left'>";
211 	html[idx++] = "<input type='checkbox' id='"+id+"'>";
212 	html[idx++] = "</td>";
213 	return idx;
214 }
215 
216 DwtPropertyPage.prototype._addTextAreaEntryRow =
217 function(field, title, html, idx, noWrap) {
218 	var myWrap = "on";
219 	if(noWrap)
220 		myWrap = "off";
221 		
222 	var id = Dwt.getNextId();
223 	this._fieldIds[field] = id;
224 	html[idx++] = "<tr valign='center'>";
225 	html[idx++] = "<td align='left' style='width:60ex;'>";
226 	html[idx++] = AjxStringUtil.htmlEncode(title) + ":";
227 	html[idx++] = "</td></tr>";
228 	html[idx++] = "<tr valign='center'><td align='left' style='width:60ex;'><textarea wrap='" + myWrap + "' rows='8' cols ='60' id='";	
229 	html[idx++] = id;
230 	html[idx++] = "'/></textarea></td></tr>";
231 	return idx;
232 }
233 
234 /**
235  * _addEntryRow
236  *	@param field - key of the field id in this._fieldIds
237  *	@param title - title string. If title is specified a separate cell will be appended before the form field
238  * title will be rendered within that cell
239  *	@param html - reference to html array
240  *	@param idx - current counter inside the html array
241  *	@param type - type of the form field to create (<input type= )
242  *	@param fldsize - size of the input field (this value will be assigned to the size property
243  *	@param tailTitle - string that will be placed behind the form field
244  *	@param titleWidth - width of the title cell
245  * 
246  * @private
247  */
248 DwtPropertyPage.prototype._addEntryRow =
249 function(field, title, html, idx, type, fldsize, tailTitle, titleWidth, withAsteric) {
250 	html[idx++] = "<tr valign='center'>";
251 	idx = this._addEntryCell(field, title, html, idx, type, fldsize, tailTitle, titleWidth, withAsteric);
252 	html[idx++] = "</tr>";
253 	return idx;
254 }
255 
256 /**
257  * _addEntryCell
258  *	@param field - key of the field id in this._fieldIds
259  *	@param title - title string. If title is specified a separate cell will be appended before the form field
260  * title will be rendered within that cell
261  *	@param html - reference to html array
262  *	@param idx - current counter inside the html array
263  *	@param type - type of the form field to create (<input type= )
264  *	@param fldsize - size of the input field (this value will be assigned to the size property
265  *	@param tailTitle - string that will be placed behind the form field
266  *	@param titleWidth - width of the title cell
267  * 
268  * @private
269  */
270 DwtPropertyPage.prototype._addEntryCell =
271 function(field, title, html, idx, type, fldsize, tailTitle, titleWidth, withAsteric) {
272 	if (type == null) type = "text";
273 	if(fldsize == null) fldsize = 35;
274 	var tWidth = "20ex";
275 	if(titleWidth) 
276 		tWidth = titleWidth;
277 		
278 	var id = Dwt.getNextId();
279 	this._fieldIds[field] = id;
280 	if(title) {
281 		html[idx++] = "<td align='left' style='width:" + tWidth + ";'>";
282 		html[idx++] = AjxStringUtil.htmlEncode(title) + ":";
283 		html[idx++] = "</td>";
284 	}
285 	html[idx++] = "<td ";
286 	if(withAsteric) {
287 		html[idx++] = "class='redAsteric' ";		
288 	}
289 	html[idx++] = "	align='left'><input autocomplete='off' size='"+fldsize+"' type='"+type+"' id='";	
290 	html[idx++] = id;
291 	html[idx++] = "'";
292 	if(withAsteric) {
293 		html[idx++] = "/>*";		
294 	} else {
295 		html[idx++] = "/> ";
296 	}
297 	if(tailTitle != null) {
298 		html[idx++]	= tailTitle;
299 	}
300 	html[idx++] = "</td>";
301 	return idx;
302 }
303 
304 /**
305  * Use this method to render HTML form
306  * call all other rendering methods from this method.
307  * 
308  * @private
309  */
310 DwtPropertyPage.prototype._createHTML = 
311 function () {
312  //abstract method
313 }
314