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 new wizard dialog. 27 * @constructor 28 * @class 29 * This class represents a reusable wizard dialog. 30 * 31 * @param {DwtControl} parent the parent control 32 * @param {string} className the CSS class name 33 * @param {string} title the dialog title 34 * @param {number} w the content area width 35 * @param {number} h the content area height 36 * 37 * @extends DwtDialog 38 * 39 * @private 40 */ 41 DwtWizardDialog = function(parent, className, title, w, h) { 42 if (arguments.length == 0) { return; } 43 className = className || "DwtDialog"; 44 45 var nextButton = new DwtDialog_ButtonDescriptor(DwtWizardDialog.NEXT_BUTTON, AjxMsg._next, DwtDialog.ALIGN_RIGHT, new AjxCallback(this, this.goNext)); 46 var prevButton = new DwtDialog_ButtonDescriptor(DwtWizardDialog.PREV_BUTTON, AjxMsg._prev, DwtDialog.ALIGN_RIGHT, new AjxCallback(this, this.goPrev)); 47 var finishButton = new DwtDialog_ButtonDescriptor(DwtWizardDialog.FINISH_BUTTON, AjxMsg._finish, DwtDialog.ALIGN_RIGHT, new AjxCallback(this, this.finishWizard)); 48 DwtDialog.call(this, {parent:parent, className:className, standardButtons:[DwtDialog.CANCEL_BUTTON], 49 extraButtons:[prevButton, nextButton, finishButton]}); 50 51 if (!w) { 52 this._contentW = "80ex"; 53 } else { 54 this._contentW = w; 55 } 56 57 if(!h) { 58 this._contentH = "100ex"; 59 } else { 60 this._contentH = h; 61 } 62 63 this._pages = new Array(); 64 this._pageIx = 1; 65 this._currentPage = 1; 66 this._progressDiv = document.createElement("div"); 67 this._progressDiv.style.position = DwtControl.STATIC_STYLE; 68 this._pageDiv = document.createElement("div"); 69 this._pageDiv.className = "DwtWizardDialogPageDiv"; 70 this._pageDiv.style.width = this._contentW; 71 this._pageDiv.style.height = this._contentH; 72 this._progressBar = new DwtWizProgressBar(this); 73 this._createContentHtml(); 74 this.setTitle(title); 75 } 76 77 DwtWizardDialog.prototype = new DwtDialog; 78 DwtWizardDialog.prototype.constructor = DwtWizardDialog; 79 80 //Z-index contants for the tabbed view contents are based on Dwt z-index constants 81 DwtWizardDialog.Z_ACTIVE_PAGE = Dwt.Z_VIEW+10; 82 DwtWizardDialog.Z_HIDDEN_PAGE = Dwt.Z_HIDDEN; 83 DwtWizardDialog.Z_TAB_PANEL = Dwt.Z_VIEW+20; 84 DwtWizardDialog.Z_CURTAIN = Dwt.Z_CURTAIN; 85 86 DwtWizardDialog.NEXT_BUTTON = 12; 87 DwtWizardDialog.PREV_BUTTON = 11; 88 DwtWizardDialog.FINISH_BUTTON = 13; 89 90 //public methods 91 DwtWizardDialog.prototype.toString = 92 function () { 93 return "DwtWizardDialog"; 94 } 95 96 DwtWizardDialog.prototype.popdown = 97 function () { 98 DwtDialog.prototype.popdown.call(this); 99 this._hideAllPages(); 100 } 101 102 /* 103 * Makes the dialog visible, and places it. Everything under the dialog will become veiled 104 * if we are modal. 105 * 106 * @param loc the desired location 107 *//* 108 DwtWizardDialog.prototype.popup = 109 function(loc) { 110 111 var thisZ = this._zIndex; 112 if (this._mode == DwtDialog.MODAL) { 113 // place veil under this dialog 114 var dialogZ = this._shell._veilOverlay.dialogZ; 115 var currentDialogZ = null; 116 var veilZ; 117 if (dialogZ.length) 118 currentDialogZ = dialogZ[dialogZ.length - 1]; 119 if (currentDialogZ) { 120 thisZ = currentDialogZ + 2; 121 veilZ = currentDialogZ + 1; 122 } else { 123 thisZ = this._zIndex; 124 veilZ = Dwt.Z_VEIL; 125 } 126 this._shell._veilOverlay.veilZ.push(veilZ); 127 this._shell._veilOverlay.dialogZ.push(thisZ); 128 Dwt.setZIndex(this._shell._veilOverlay, veilZ); 129 } 130 loc = this._loc = loc || this._loc; // use whichever has a value, local has precedence 131 var sizeShell = this._shell.getSize(); 132 var sizeThis = this.getSize(); 133 var x, y; 134 if (loc == null) { 135 // if no location, go for the middle 136 x = Math.round((sizeShell.x - sizeThis.x) / 2); 137 y = Math.round((sizeShell.y - sizeThis.y) / 2); 138 } else { 139 x = loc.x; 140 y = loc.y; 141 } 142 // try to stay within shell boundaries 143 if ((x + sizeThis.x) > sizeShell.x) 144 x = sizeShell.x - sizeThis.x; 145 if ((y + sizeThis.y) > sizeShell.y) 146 y = sizeShell.y - sizeThis.y; 147 this.setLocation(x, y); 148 149 this.setZIndex(thisZ); 150 } 151 */ 152 153 /* 154 * @param pageKey - key to the page to be shown. 155 * pageKey is the value returned from @link DwtWizardDialog.prototype.addPage method 156 * This method is called by 157 * @link DwtWizardPage.prototype.switchToNextPage 158 * and 159 * @link DwtWizardPage.prototype.switchToPrevPage 160 */ 161 DwtWizardDialog.prototype.goPage = 162 function(pageKey) { 163 if(this._pages && this._pages[pageKey]) { 164 this._currentPage = pageKey; 165 this._showPage(pageKey); 166 this._progressBar.showStep(pageKey); 167 this._pages[pageKey].setActive(); 168 } 169 } 170 171 DwtWizardDialog.prototype.goNext = 172 function() { 173 var nextPageKey = this._currentPage + 1; 174 if(this._pages && this._pages[this._currentPage]) { 175 this._pages[this._currentPage].switchToNextPage(nextPageKey); 176 } 177 178 } 179 180 DwtWizardDialog.prototype.goPrev = 181 function() { 182 var prevPageKey = this._currentPage - 1; 183 if(this._pages && this._pages[this._currentPage]) { 184 this._pages[this._currentPage].switchToPrevPage(prevPageKey); 185 } 186 } 187 188 DwtWizardDialog.prototype.finishWizard = 189 function() { 190 this.popdown(); 191 } 192 193 /** 194 * 195 * @param pageKey the key for the page, returned from {@link #addPage} 196 * @return {DwtPropertyPage} the view tab 197 * 198 * @private 199 */ 200 DwtWizardDialog.prototype.getPage = 201 function (pageKey) { 202 if(this._pages && this._pages[pageKey]) 203 return this._pages[pageKey]; 204 else 205 return null; 206 } 207 208 /** 209 * @param {DwtPropertyPage} wizPage the wizard page 210 * @return - the key for the added page. This key can be used to retrieve the tab using {@link #getPage} 211 * 212 * @private 213 */ 214 DwtWizardDialog.prototype.addPage = 215 function (wizPage, stepTitle) { 216 var pageKey = this._pageIx++; 217 this._pages[pageKey] = wizPage; 218 //add a step to the progress bar 219 /* if(stepTitle == null) 220 stepTitle = pageKey;*/ 221 this._progressBar.addStep(pageKey, stepTitle); 222 //add the page 223 this._pageDiv.appendChild(this._pages[pageKey].getHtmlElement()); 224 225 if(pageKey==1) //show the first tab 226 this._pages[pageKey].setZIndex(DwtWizardDialog.Z_ACTIVE_PAGE); 227 else { 228 //hide all the other tabs 229 this._pages[pageKey].setZIndex(DwtWizardDialog.Z_HIDDEN_PAGE); 230 Dwt.setVisible(this._pages[pageKey].getHtmlElement(), false); 231 } 232 return pageKey; 233 } 234 235 //private and protected methods 236 237 /** 238 * method _createHtm 239 * 240 * @private 241 */ 242 DwtWizardDialog.prototype._createContentHtml = 243 function () { 244 245 this._table = document.createElement("table"); 246 this._table.border = 0; 247 this._table.width = this._contentW; 248 this._table.cellPadding = this._table.cellSpacing = 0; 249 250 this._table.backgroundColor = DwtCssStyle.getProperty(this.parent.getHtmlElement(), "background-color"); 251 252 var row1; //_progressBar 253 var col1; 254 row1 = this._table.insertRow(0); 255 row1.align = "left"; 256 row1.vAlign = "middle"; 257 258 col1 = row1.insertCell(row1.cells.length); 259 col1.align = "left"; 260 col1.vAlign = "middle"; 261 col1.noWrap = true; 262 col1.width="100%"; 263 col1.className="DwtTabTable"; 264 col1.appendChild(this._progressBar.getHtmlElement()); 265 266 var rowSep;//separator 267 var colSep; 268 rowSep = this._table.insertRow(1); 269 rowSep.align = "center"; 270 rowSep.vAlign = "middle"; 271 272 colSep = rowSep.insertCell(rowSep.cells.length); 273 colSep.align = "left"; 274 colSep.vAlign = "middle"; 275 colSep.noWrap = true; 276 colSep.style.width = this._contentW; 277 var sepDiv = document.createElement("div"); 278 sepDiv.className = "horizSep"; 279 sepDiv.style.width = this._contentW; 280 sepDiv.style.height = "5px"; 281 colSep.appendChild(sepDiv); 282 283 var row2; //page 284 var col2; 285 row2 = this._table.insertRow(2); 286 row2.align = "left"; 287 row2.vAlign = "middle"; 288 289 col2 = row2.insertCell(row2.cells.length); 290 col2.align = "left"; 291 col2.vAlign = "middle"; 292 col2.noWrap = true; 293 col2.width = this._contentW; 294 col2.appendChild(this._pageDiv); 295 296 this._getContentDiv().appendChild(this._table); 297 } 298 299 /** 300 * Override addChild method. We need internal control over layout of the children in this class. 301 * Child elements are added to this control in the _createHTML method. 302 * @param child 303 * 304 * @private 305 */ 306 DwtWizardDialog.prototype.addChild = 307 function(child) { 308 this._children.add(child); 309 } 310 311 DwtWizardDialog.prototype._showPage = 312 function(pageKey) { 313 if(this._pages && this._pages[pageKey]) { 314 //hide all the tabs 315 this._hideAllPages(); 316 //make this tab visible 317 this._pages[pageKey].showMe(); 318 //this._pages[pageKey].setZIndex(DwtWizardDialog.Z_ACTIVE_PAGE); 319 Dwt.setVisible(this._pages[pageKey].getHtmlElement(), true); 320 } 321 } 322 323 DwtWizardDialog.prototype._hideAllPages = 324 function() { 325 if(this._pages && this._pages.length) { 326 for(var curPageKey in this._pages) { 327 if(this._pages[curPageKey]) { 328 this._pages[curPageKey].hideMe(); 329 //this._pages[curPageKey].setZIndex(DwtWizardDialog.Z_HIDDEN_PAGE); 330 Dwt.setVisible(this._pages[curPageKey].getHtmlElement(), false); 331 } 332 } 333 } 334 } 335 336 337 /** 338 * @class 339 * @constructor 340 * DwtWizardpage abstract class for a page in a wizard dialog 341 * tab pages are responsible for creating there own HTML and populating/collecting 342 * data to/from any form fields that they display 343 * 344 * @private 345 */ 346 DwtWizardPage = function(parent, className) { 347 if (arguments.length == 0) return; 348 var clsName = className || "DwtDialog"; 349 DwtPropertyPage.call(this, parent, className, DwtControl.ABSOLUTE_STYLE); 350 } 351 352 DwtWizardPage.prototype = new DwtTabViewPage; 353 DwtWizardPage.prototype.constructor = DwtWizardPage; 354 355 DwtWizardPage.prototype.toString = 356 function() { 357 return "DwtWizardPage"; 358 } 359 360 /** 361 * setActive is called when the page is activated. 362 **/ 363 DwtWizardPage.prototype.setActive = 364 function () { 365 366 } 367 368 /** 369 * @param pageKey - key for the next page 370 * Checks if it is ok to leave go to the next page. 371 * Default implementation does not check anything. 372 **/ 373 DwtWizardPage.prototype.switchToNextPage = 374 function (pageKey) { 375 this.parent.goPage(pageKey); 376 } 377 378 /** 379 * @param pageKey - key for the previous page 380 * Checks if it is ok to leave go to the previous page. 381 * Default implementation does not check anything. 382 **/ 383 DwtWizardPage.prototype.switchToPrevPage = 384 function (pageKey) { 385 this.parent.goPage(pageKey); 386 } 387 388 DwtWizardPage.prototype.showMe = 389 function() { 390 this.setZIndex(DwtTabView.Z_ACTIVE_TAB); 391 /* 392 DBG.println(AjxDebug.DBG3, "DwtWizardPage.prototype.showMe"); 393 DBG.println(AjxDebug.DBG3, "this.parent.getHtmlElement().offsetHeight: " + this.parent.getHtmlElement().offsetHeight); 394 DBG.println(AjxDebug.DBG3, "this.parent.getHtmlElement().clientHeight: " + this.parent.getHtmlElement().clientHeight); 395 DBG.println(AjxDebug.DBG3, "this.parent.getHtmlElement().offsetWidth: " + this.parent.getHtmlElement().offsetWidth); 396 DBG.println(AjxDebug.DBG3, "this.parent.getHtmlElement().clientWidth: " + this.parent.getHtmlElement().clientWidth); 397 DBG.println(AjxDebug.DBG3, "this.parent._contentH: " + this.parent._contentH); 398 DBG.println(AjxDebug.DBG3, "this.parent._contentW: " + this.parent._contentW); 399 */ 400 this.getHtmlElement().style.height = this.parent._contentH; 401 this.getHtmlElement().style.width = this.parent._contentW; 402 403 } 404 /** 405 * @class DwtWizProgressBar 406 * @constructor 407 * 408 * @param parent 409 * 410 * @private 411 */ 412 DwtWizProgressBar = function(parent) { 413 if (arguments.length == 0) return; 414 DwtComposite.call(this, {parent:parent, className:"DwtWizProgressBar", posStyle:DwtControl.STATIC_STYLE}); 415 this._table = document.createElement("table"); 416 this._table.border = 0; 417 this._table.cellPadding = 0; 418 this._table.cellSpacing = 0; 419 this.getHtmlElement().appendChild(this._table); 420 this._table.backgroundColor = DwtCssStyle.getProperty(this.parent.getHtmlElement(), "background-color"); 421 this._stepsNumber = 0; //number of steps 422 this._steps = new Array(); 423 this._lblHeader = new DwtStepLabel(this); 424 this._lblHeader.setText("Step 0 of 0"); 425 this._lblHeader.setActive(true); 426 } 427 428 429 DwtWizProgressBar.prototype = new DwtComposite; 430 DwtWizProgressBar.prototype.constructor = DwtWizProgressBar; 431 432 DwtWizProgressBar.prototype.toString = 433 function() { 434 return "DwtWizProgressBar"; 435 } 436 437 /** 438 * @param stepKey 439 **/ 440 DwtWizProgressBar.prototype.showStep = 441 function(stepKey) { 442 var szLabelTxt = "Step " + stepKey + " of " + this._stepsNumber; 443 if(this._steps[stepKey]) { 444 szLabelTxt = szLabelTxt + ": " + this._steps[stepKey]; 445 } 446 this._lblHeader.setText(szLabelTxt); 447 } 448 449 /** 450 * @param stepKey 451 * @param stepNumber 452 **/ 453 DwtWizProgressBar.prototype.addStep = 454 function (stepKey, stepTitle) { 455 this._steps[stepKey] = stepTitle; 456 return (++this._stepsNumber); 457 } 458 459 DwtWizProgressBar.prototype.addChild = 460 function(child) { 461 this._children.add(child); 462 var row; 463 var col; 464 this._table.width = "100%"; 465 row = (this._table.rows.length != 0) ? this._table.rows[0]: this._table.insertRow(0); 466 row.align = "center"; 467 row.vAlign = "middle"; 468 469 col = row.insertCell(row.cells.length); 470 col.align = "center"; 471 col.vAlign = "middle"; 472 col.noWrap = true; 473 col.appendChild(child.getHtmlElement()); 474 } 475 476 477 /** 478 * @class DwtStepLabel 479 * @constructor 480 * 481 * @param parent 482 * 483 * @private 484 */ 485 DwtStepLabel = function(parent) { 486 DwtLabel.call(this, {parent:parent, style:DwtLabel.ALIGN_CENTER, className:"DwtStepLabel"}); 487 } 488 489 DwtStepLabel.prototype = new DwtLabel; 490 DwtStepLabel.prototype.constructor = DwtStepLabel; 491 492 DwtStepLabel.prototype.toString = 493 function() { 494 return "DwtStepLabel"; 495 } 496 497 DwtStepLabel.prototype.setActive = 498 function(isActive) { 499 if (isActive) { 500 this._textCell.className="DwtStepLabelActive"; 501 } else { 502 this._textCell.className="DwtStepLabelInactive"; 503 } 504 } 505 506