1 /* 2 * ***** BEGIN LICENSE BLOCK ***** 3 * Zimbra Collaboration Suite Web Client 4 * Copyright (C) 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) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016 Synacor, Inc. All Rights Reserved. 21 * ***** END LICENSE BLOCK ***** 22 */ 23 24 /** 25 * @overview 26 * This file contains the edit task view classes. 27 */ 28 29 /** 30 * Creates the edit task view. 31 * @class 32 * This class represents the edit task view. 33 * 34 * @param {DwtComposite} parent the parent 35 * @param {ZmTaskController} controller the controller 36 * 37 * @extends ZmCalItemEditView 38 */ 39 ZmTaskEditView = function(parent, controller) { 40 41 this._view = controller.getCurrentViewId(); 42 this._sessionId = controller.getSessionId(); 43 44 var idParams = { 45 skinComponent: ZmId.SKIN_APP_MAIN, 46 app: ZmId.APP_TASKS, 47 componentType: ZmId.WIDGET_VIEW, 48 componentName: ZmId.VIEW_TASKEDIT 49 }; 50 51 var domId = ZmId.create(idParams, "A task editing view"); 52 ZmCalItemEditView.call(this, parent, null, controller, null, DwtControl.ABSOLUTE_STYLE, "ZmTaskEditView", domId); 53 }; 54 55 ZmTaskEditView.prototype = new ZmCalItemEditView; 56 ZmTaskEditView.prototype.constructor = ZmTaskEditView; 57 58 59 // Consts 60 61 /** 62 * Defines the priority values. 63 * 64 * @see ZmCalItem 65 */ 66 ZmTaskEditView.PRIORITY_VALUES = [ 67 ZmCalItem.PRIORITY_LOW, 68 ZmCalItem.PRIORITY_NORMAL, 69 ZmCalItem.PRIORITY_HIGH ]; 70 71 /** 72 * Defines the status values. 73 * 74 * @see ZmCalendarApp 75 */ 76 ZmTaskEditView.STATUS_VALUES = [ 77 ZmCalendarApp.STATUS_NEED, 78 ZmCalendarApp.STATUS_COMP, 79 ZmCalendarApp.STATUS_INPR, 80 ZmCalendarApp.STATUS_WAIT, 81 ZmCalendarApp.STATUS_DEFR ]; 82 83 // Message dialog placement 84 ZmTaskEditView.DIALOG_X = 50; 85 ZmTaskEditView.DIALOG_Y = 100; 86 87 // Public Methods 88 89 /** 90 * Returns a string representation of the object. 91 * 92 * @return {String} a string representation of the object 93 */ 94 ZmTaskEditView.prototype.toString = 95 function() { 96 return "ZmTaskEditView"; 97 }; 98 99 /** 100 * @private 101 */ 102 ZmTaskEditView.prototype.set = 103 function(calItem, mode, isDirty) { 104 this.initialize(calItem, mode, isDirty); 105 106 // HACK: TEV takes too long to init so design mode never gets set properly 107 if (AjxEnv.isGeckoBased) { 108 var ta = new AjxTimedAction(this, this.reEnableDesignMode); 109 AjxTimedAction.scheduleAction(ta, 500); 110 } 111 }; 112 113 /** 114 * Gets the controller. 115 * 116 * @return {ZmTaskController} the controller 117 */ 118 ZmTaskEditView.prototype.getController = 119 function() { 120 return this._controller; 121 }; 122 123 ZmTaskEditView.prototype._getClone = 124 function() { 125 return ZmTask.quickClone(this._calItem); 126 }; 127 128 ZmTaskEditView.prototype._populateForEdit = 129 function(calItem, mode) { 130 ZmCalItemEditView.prototype._populateForEdit.call(this, calItem, mode); 131 132 if (calItem.startDate) { 133 var sd = new Date(calItem.startDate.getTime()); 134 this._startDateField.value = AjxDateUtil.simpleComputeDateStr(sd); 135 } 136 if (calItem.endDate) { 137 var ed = new Date(calItem.endDate.getTime()); 138 this._endDateField.value = AjxDateUtil.simpleComputeDateStr(ed); 139 } 140 141 142 var rd = new Date(calItem.remindDate.getTime()); 143 144 if (calItem.alarm) { 145 if (calItem.remindDate && calItem._reminderAbs) { 146 this._remindTimeSelect.set(calItem.remindDate); 147 } 148 } else { 149 var now = AjxDateUtil.roundTimeMins(new Date(), 30); 150 this._remindTimeSelect.set(now); 151 } 152 153 if (this._hasReminderSupport) { 154 this._remindDateField.value = AjxDateUtil.simpleComputeDateStr(rd); 155 this._reminderCheckbox.setSelected(calItem.alarm); 156 this._setRemindersEnabled(calItem.alarm); 157 158 if (calItem.alarmActions.contains(ZmCalItem.ALARM_EMAIL)) { 159 this._reminderEmailCheckbox.setSelected(true); 160 } 161 if (calItem.alarmActions.contains(ZmCalItem.ALARM_DEVICE_EMAIL)) { 162 this._reminderDeviceEmailCheckbox.setSelected(true); 163 } 164 } 165 166 this._location.setValue(calItem.getLocation()); 167 this._setPriority(calItem.priority); 168 this._statusSelect.setSelectedValue(calItem.status); 169 this._pCompleteSelectInput.setValue(this.formatPercentComplete(calItem.pComplete)); 170 if (!this._notesHtmlEditor.getContent() && calItem.message){ 171 this._notesHtmlEditor.setContent(calItem.message.getInviteDescriptionContentValue(ZmMimeTable.TEXT_PLAIN) || ""); 172 } 173 this._setEmailReminderControls(); 174 }; 175 176 ZmTaskEditView.prototype._populateForSave = 177 function(calItem) { 178 179 ZmCalItemEditView.prototype._populateForSave.call(this, calItem); 180 181 calItem.location = this._location.getValue(); 182 // TODO - normalize 183 var startDate = AjxDateUtil.simpleParseDateStr(this._startDateField.value); 184 var endDate = AjxDateUtil.simpleParseDateStr(this._endDateField.value); 185 186 if (startDate) { 187 calItem.setStartDate(startDate, true); 188 } else { 189 calItem.startDate = null; // explicitly null out in case item has old data 190 } 191 192 if (endDate) { 193 calItem.setEndDate(endDate, true); 194 } else { 195 calItem.endDate = null; // explicitly null out in case item has old data 196 } 197 198 //set reminder 199 var reminders = [ 200 { control: this._reminderEmailCheckbox, action: ZmCalItem.ALARM_EMAIL }, 201 { control: this._reminderDeviceEmailCheckbox, action: ZmCalItem.ALARM_DEVICE_EMAIL } 202 ]; 203 if (this._hasReminderSupport && this._reminderCheckbox.isSelected()) { 204 var remindDate = AjxDateUtil.simpleParseDateStr(this._remindDateField.value); 205 calItem.alarm = true; 206 calItem.remindDate = remindDate; 207 remindDate = this._remindTimeSelect.getValue(remindDate); 208 var remindFmtStr = AjxDateUtil.getServerDateTime(remindDate,true); 209 calItem.setTaskReminder(remindFmtStr); 210 for (var i = 0; i < reminders.length; i++) { 211 var reminder = reminders[i]; 212 if (reminder.control && reminder.control.isSelected()) { 213 calItem.addReminderAction(reminder.action); 214 } 215 else { 216 calItem.removeReminderAction(reminder.action); 217 } 218 } 219 } else { 220 calItem.alarm = false; 221 calItem.remindDate = new Date(); 222 calItem.setTaskReminder(null); 223 } 224 225 calItem.setAllDayEvent(true); 226 var completion = this.getpCompleteInputValue(); 227 // Should always be valid at this point - made it past isValid 228 calItem.pComplete = completion.valid ? completion.percent : 0; 229 calItem.priority = this._getPriority(); 230 calItem.status = this._statusSelect.getValue(); 231 232 //bug:51913 disable alarm when stats is completed 233 if (calItem.pComplete === 100 && this._statusSelect.getValue() === ZmCalendarApp.STATUS_COMP) { 234 calItem.alarm = false; 235 calItem.remindDate = new Date(); 236 calItem.setTaskReminder(null); 237 for (var i = 0; i < reminders.length; i++) { 238 var reminder = reminders[i]; 239 if (reminder.control && reminder.control.isSelected()) { 240 calItem.removeReminderAction(reminder.action); 241 } 242 } 243 } 244 245 // XXX: uncomment when supported 246 // this._getRecurrence(calItem); // set any recurrence rules LAST 247 248 return calItem; 249 }; 250 251 ZmTaskEditView.prototype.isValid = 252 function() { 253 var errorMsg; 254 var subj = AjxStringUtil.trim(this._subjectField.getValue()); 255 if (subj && subj.length) { 256 var startDate = AjxStringUtil.trim(this._startDateField.value); 257 var endDate = AjxStringUtil.trim(this._endDateField.value); 258 if (startDate.length > 0 && (!DwtTimeSelect.validStartEnd(this._startDateField, this._endDateField))) { 259 if(endDate.length <= 0) { 260 errorMsg = ZmMsg.errorEmptyTaskDueDate; 261 } else { 262 errorMsg = ZmMsg.errorInvalidDates; 263 } 264 } 265 var remindTime = DwtTimeSelect.parse(this._remindTimeSelect.getInputField().getValue()); 266 if (!remindTime) { 267 errorMsg = AjxMsg.invalidTimeString; 268 } 269 var completion = this.getpCompleteInputValue(); 270 if (!completion.valid) { 271 errorMsg = ZmMsg.errorInvalidPercentage; 272 } else if ((completion.percent < 0) || (completion.percent > 100)) { 273 errorMsg = ZmMsg.errorInvalidPercentage; 274 } 275 } else { 276 errorMsg = ZmMsg.errorMissingSubject; 277 } 278 279 if (errorMsg) { 280 throw errorMsg; 281 } 282 283 return true; 284 }; 285 286 ZmTaskEditView.prototype.cleanup = 287 function() { 288 ZmCalItemEditView.prototype.cleanup.call(this); 289 290 this._startDateField.value = ""; 291 this._endDateField.value = ""; 292 }; 293 294 295 // Private/protected Methods 296 297 ZmTaskEditView.prototype._createHTML = 298 function() { 299 //this._repeatDescId = this._htmlElId + "_repeatDesc"; 300 this._isAppt = false; 301 var subs = { 302 id: this._htmlElId, 303 height: (this.parent.getSize().y - 30), 304 locationId: (this._htmlElId + "_location"), 305 isGalEnabled: appCtxt.get(ZmSetting.GAL_ENABLED), 306 isAppt: false 307 }; 308 309 // XXX: rename template name to CalItem#CalItemEdit 310 this.getHtmlElement().innerHTML = AjxTemplate.expand("calendar.Appointment#EditView", subs); 311 }; 312 313 ZmTaskEditView.prototype._getPriorityImage = 314 function(flag) { 315 if (ZmCalItem.isPriorityHigh(flag)) { return "PriorityHigh_list"; } 316 if (ZmCalItem.isPriorityLow(flag)) { return "PriorityLow_list"; } 317 return "PriorityNormal_list"; 318 }; 319 320 ZmTaskEditView.prototype._getPriorityText = 321 function(flag) { 322 if (ZmCalItem.isPriorityHigh(flag)) { return ZmMsg.high; } 323 if (ZmCalItem.isPriorityLow(flag)) { return ZmMsg.low; } 324 return ZmMsg.normal; 325 }; 326 327 ZmTaskEditView.prototype._createPriorityMenuItem = 328 function(menu, text, flag) { 329 // I prefer a readable ID part for the priority, over the 1, 5 and 9 that those constants are set to. 330 var priorityId = ZmCalItem.isPriorityHigh(flag) ? "high" : ZmCalItem.isPriorityLow(flag) ? "low" : "normal"; 331 var item = DwtMenuItem.create({parent: menu, imageInfo: this._getPriorityImage(flag), text: text, id: Dwt.getNextId("EditTaskPriorityMenu_" + priorityId + "_")}); 332 item._priorityFlag = flag; 333 item.addSelectionListener(this._priorityMenuListnerObj); 334 }; 335 336 ZmTaskEditView.prototype._priorityButtonMenuCallback = 337 function() { 338 var menu = new DwtMenu({parent: this._prioritySelect, id: Dwt.getNextId("EditTaskPriorityMenu_")}); 339 this._priorityMenuListnerObj = new AjxListener(this, this._priorityMenuListner); 340 this._createPriorityMenuItem(menu, ZmMsg.high, ZmCalItem.PRIORITY_HIGH); 341 this._createPriorityMenuItem(menu, ZmMsg.normal, ZmCalItem.PRIORITY_NORMAL); 342 this._createPriorityMenuItem(menu, ZmMsg.low, ZmCalItem.PRIORITY_LOW); 343 return menu; 344 }; 345 346 ZmTaskEditView.prototype._priorityMenuListner = 347 function(ev) { 348 this._setPriority(ev.dwtObj._priorityFlag); 349 }; 350 351 ZmTaskEditView.prototype._getPriority = 352 function() { 353 return (this._prioritySelect) 354 ? (this._prioritySelect._priorityFlag || "") : ""; 355 }; 356 357 ZmTaskEditView.prototype._setPriority = 358 function(flag) { 359 if (this._prioritySelect) { 360 flag = flag || ""; 361 this._prioritySelect.setImage(this._getPriorityImage(flag)); 362 this._prioritySelect.setText(this._getPriorityText(flag)) 363 this._prioritySelect._priorityFlag = flag; 364 } 365 }; 366 367 ZmTaskEditView.prototype.getpCompleteInputValue = function() { 368 var pValue = this._pCompleteSelectInput.getValue(); 369 pValue = pValue.replace(/[%\u066A]/g,""); // also check for Arabic % character 370 pValue = pValue.trim(); 371 var valid = /^\d*$/.test(pValue); 372 var percent = 0; 373 if (valid) { 374 percent = Math.round(pValue); 375 } 376 377 return { valid: valid, percent: percent}; 378 }; 379 380 ZmTaskEditView.prototype._unSelectRemindersCheckbox = function() { 381 var reminders = [ 382 { control: this._reminderEmailCheckbox}, 383 { control: this._reminderDeviceEmailCheckbox}, 384 { control: this._reminderCheckbox} 385 ]; 386 for (var i = 0; i < reminders.length; i++) { 387 var reminder = reminders[i]; 388 if (reminder.control) { 389 reminder.control.setSelected(false); 390 } 391 } 392 }; 393 394 ZmTaskEditView.prototype.formatPercentComplete = function(pValue) { 395 396 var formatter = new AjxMessageFormat(AjxMsg.percentageString); 397 if(AjxUtil.isString(pValue) && pValue.indexOf("%") != -1) { 398 return formatter.format(Math.round(pValue.replace(/[%\u066A]/g,""))); // also check for Arabic % character 399 } else { 400 return formatter.format(Math.round(pValue)); 401 } 402 }; 403 404 ZmTaskEditView.prototype._createWidgets = 405 function(width) { 406 ZmCalItemEditView.prototype._createWidgets.call(this, width); 407 408 // add location 409 var params = {parent: this, type: DwtInputField.STRING}; 410 this._location = new DwtInputField(params); 411 Dwt.setSize(this._location.getInputElement(), width, "2rem"); 412 this._location.reparentHtmlElement(this._htmlElId + "_location"); 413 414 // add priority DwtButton 415 this._prioritySelect = new DwtButton({parent:this}); 416 this._prioritySelect.setSize(60, Dwt.DEFAULT); 417 this._prioritySelect.setMenu(new AjxCallback(this, this._priorityButtonMenuCallback)); 418 this._prioritySelect.reparentHtmlElement(this._htmlElId + "_priority"); 419 420 var listener = new AjxListener(this, this._selectListener); 421 // add status DwtSelect 422 this._statusSelect = new DwtSelect({parent:this}); 423 for (var i = 0; i < ZmTaskEditView.STATUS_VALUES.length; i++) { 424 var v = ZmTaskEditView.STATUS_VALUES[i]; 425 this._statusSelect.addOption(ZmCalItem.getLabelForStatus(v), i==0, v); 426 } 427 this._statusSelect.addChangeListener(listener); 428 this._statusSelect.reparentHtmlElement(this._htmlElId + "_status"); 429 430 var params = { 431 parent: this, 432 parentElement: (this._htmlElId + "_pCompleteSelectInput"), 433 type: DwtInputField.STRING, 434 errorIconStyle: DwtInputField.ERROR_ICON_NONE, 435 validationStyle: DwtInputField.CONTINUAL_VALIDATION 436 }; 437 this._pCompleteSelectInput = new DwtInputField(params); 438 var pCompleteInputEl = this._pCompleteSelectInput.getInputElement(); 439 Dwt.setSize(pCompleteInputEl, Dwt.DEFAULT, "2rem"); 440 pCompleteInputEl.onblur = AjxCallback.simpleClosure(this._handleCompleteOnBlur, this, pCompleteInputEl); 441 442 var pCompleteButtonListener = new AjxListener(this, this._pCompleteButtonListener); 443 var pCompleteSelectListener = new AjxListener(this, this._pCompleteSelectListener); 444 this._pCompleteButton = ZmTasksApp.createpCompleteButton(this, this._htmlElId + "_pCompleteSelect", pCompleteButtonListener, pCompleteSelectListener); 445 446 this._hasReminderSupport = Dwt.byId(this._htmlElId + "_reminderCheckbox") != null; 447 448 if (this._hasReminderSupport) { 449 // reminder date DwtButton's 450 var remindDateBtnListener = new AjxListener(this, this._remindDateBtnListener); 451 var remindDateCalSelectionListener = new AjxListener(this, this._dateCalSelectionListener); 452 453 this._reminderLabel = Dwt.byId(this._htmlElId+"_reminderLabel"); 454 455 this._reminderCheckbox = new DwtCheckbox({parent:this}); 456 this._reminderCheckbox.replaceElement(this._htmlElId+"_reminderCheckbox"); 457 this._reminderCheckbox.addSelectionListener(new AjxListener(this, this._setEmailReminderControls)); 458 459 this._remindDateField = document.getElementById(this._htmlElId + "_remindDateField"); 460 this._remindDateButton = ZmCalendarApp.createMiniCalButton(this, this._htmlElId + "_remindMiniCalBtn", remindDateBtnListener, remindDateCalSelectionListener); 461 this._remindDateButton.reparentHtmlElement(this._htmlElId + "_remindMiniCalBtn"); 462 463 // time DwtTimeSelect 464 this._remindTimeSelect = new DwtTimeInput(this, DwtTimeInput.START); 465 this._remindTimeSelect.reparentHtmlElement(this._htmlElId + "_remindTimeSelect"); 466 467 this._reminderEmailCheckbox = new DwtCheckbox({parent: this}); 468 this._reminderEmailCheckbox.replaceElement(document.getElementById(this._htmlElId + "_reminderEmailCheckbox")); 469 this._reminderEmailCheckbox.setText(ZmMsg.email); 470 this._reminderDeviceEmailCheckbox = new DwtCheckbox({parent: this}); 471 this._reminderDeviceEmailCheckbox.replaceElement(document.getElementById(this._htmlElId + "_reminderDeviceEmailCheckbox")); 472 this._reminderDeviceEmailCheckbox.setText(ZmMsg.deviceEmail); 473 this._reminderConfigure = new DwtText({parent:this,className:"FakeAnchor"}); 474 this._reminderConfigure.setText(ZmMsg.remindersConfigure); 475 this._reminderConfigure.replaceElement(document.getElementById(this._htmlElId+"_reminderConfigure")); 476 this._setEmailReminderControls(); 477 478 var settings = appCtxt.getSettings(); 479 var listener = new AjxListener(this, this._settingChangeListener); 480 settings.getSetting(ZmSetting.CAL_EMAIL_REMINDERS_ADDRESS).addChangeListener(listener); 481 settings.getSetting(ZmSetting.CAL_DEVICE_EMAIL_REMINDERS_ADDRESS).addChangeListener(listener); 482 } 483 }; 484 485 ZmTaskEditView.prototype._remindDateBtnListener = 486 function(ev) { 487 var calDate = ev.item == this._remindDateButton 488 ? AjxDateUtil.simpleParseDateStr(this._remindDateField.value) 489 : null; 490 491 // if date was input by user and its foobar, reset to today's date 492 if (calDate == null || isNaN(calDate)) { 493 calDate = new Date(); 494 var field = ev.item == this._remindDateButton ? this._remindDateField : null; 495 496 var calEndDate = AjxDateUtil.simpleParseDateStr(this._endDateField.value); 497 if (calEndDate != null || isNaN(calEndDate)) { 498 calDate = calEndDate; 499 } 500 501 field.value = AjxDateUtil.simpleComputeDateStr(calDate); 502 } 503 504 // always reset the date to current field's date 505 var menu = ev.item.getMenu(); 506 var cal = menu.getItem(0); 507 cal.setDate(calDate, true); 508 ev.item.popup(); 509 }; 510 511 ZmTaskEditView.prototype._checkReminderDate = 512 function(){ 513 var currDate = new Date(); 514 var rd = AjxDateUtil.simpleParseDateStr(this._remindDateField.value); 515 if (rd.valueOf() < currDate.valueOf()){ 516 this._remindDateField.value = AjxDateFormat.getDateInstance(AjxDateFormat.SHORT).format(currDate); 517 } 518 }; 519 520 ZmTaskEditView.prototype._dateCalSelectionListener = function(ev) { 521 522 ZmCalItemEditView.prototype._dateCalSelectionListener.call(this,ev); 523 524 var parentButton = ev.item.parent.parent; 525 var newDate = AjxDateUtil.simpleComputeDateStr(ev.detail); 526 527 var ed = AjxDateUtil.simpleParseDateStr(this._endDateField.value); 528 var sd = AjxDateUtil.simpleParseDateStr(this._startDateField.value); 529 var rd = AjxDateUtil.simpleParseDateStr(this._remindDateField.value); 530 531 // change the start/end date if they mismatch 532 if (parentButton == this._endDateButton) { 533 if(rd && (rd.valueOf() > ev.detail.valueOf())) { 534 this._remindDateField.value = newDate; 535 } 536 //this._endDateField.value = newDate; 537 } else if(parentButton == this._remindDateButton) { 538 if (ed && (ed.valueOf() < ev.detail.valueOf())) { 539 this._endDateField.value = newDate; 540 } 541 if (ed == null && sd && (sd.valueOf() < ev.detail.valueOf())) { 542 this._startDateField.value = newDate; 543 } 544 this._remindDateField.value = newDate; 545 } else if(parentButton == this._startDateButton) { 546 if (ed == null && rd && (rd.valueOf() > ev.detail.valueOf())) { 547 this._remindDateField.value = newDate; 548 } 549 } 550 this._checkReminderDate(); 551 }; 552 553 554 ZmTaskEditView.prototype._addEventHandlers = 555 function() { 556 var edvId = AjxCore.assignId(this); 557 558 // add event listeners where necessary 559 //Dwt.setHandler(this._repeatDescField, DwtEvent.ONCLICK, ZmCalItemEditView._onClick); 560 //Dwt.setHandler(this._repeatDescField, DwtEvent.ONMOUSEOVER, ZmCalItemEditView._onMouseOver); 561 //Dwt.setHandler(this._repeatDescField, DwtEvent.ONMOUSEOUT, ZmCalItemEditView._onMouseOut); 562 563 //this._repeatDescField._editViewId = 564 if (this._hasReminderSupport) { 565 // TODO: What is this for? 566 this._reminderCheckbox._editViewId = edvId; 567 } 568 }; 569 570 // cache all input fields so we dont waste time traversing DOM each time 571 ZmTaskEditView.prototype._cacheFields = 572 function() { 573 ZmCalItemEditView.prototype._cacheFields.call(this); 574 // HACK: hide all recurrence-related fields until tasks supports it 575 //this._repeatSelect.setVisibility(false); 576 //var repeatLabel = document.getElementById(this._htmlElId + "_repeatLabel"); 577 //Dwt.setVisibility(repeatLabel, false); 578 //Dwt.setVisibility(this._repeatDescField, false); 579 this._setRemindersEnabled(false); 580 }; 581 582 // Returns a string representing the form content 583 ZmTaskEditView.prototype._formValue = 584 function(excludeAttendees) { 585 var vals = []; 586 587 vals.push(this._subjectField.getValue()); 588 vals.push(this._location.getValue()); 589 vals.push(this._getPriority()); 590 vals.push(this._folderSelect.getValue()); 591 var completion = this.getpCompleteInputValue(); 592 vals.push(completion.valid ? completion.percent : 0); 593 vals.push(this._statusSelect.getValue()); 594 var startDate = AjxDateUtil.simpleParseDateStr(this._startDateField.value); 595 if (startDate) vals.push(AjxDateUtil.getServerDateTime(startDate)); 596 var endDate = AjxDateUtil.simpleParseDateStr(this._endDateField.value); 597 if (endDate) vals.push(AjxDateUtil.getServerDateTime(endDate)); 598 599 if (this._hasReminderSupport) { 600 var hasReminder = this._reminderCheckbox.isSelected(); 601 vals.push(hasReminder); 602 if (hasReminder) { 603 var remindDate = AjxDateUtil.simpleParseDateStr(this._remindDateField.value); 604 remindDate = this._remindTimeSelect.getValue(remindDate); 605 if(remindDate) { 606 vals.push( 607 AjxDateUtil.getServerDateTime(remindDate) 608 ); 609 } 610 vals.push(this._reminderEmailCheckbox.isSelected()); 611 vals.push(this._reminderDeviceEmailCheckbox.isSelected()); 612 } 613 } 614 615 //vals.push(this._repeatSelect.getValue()); 616 vals.push(this._notesHtmlEditor.getContent()); 617 618 var str = vals.join("|"); 619 str = str.replace(/\|+/, "|"); 620 return str; 621 }; 622 623 ZmTaskEditView.prototype._addTabGroupMembers = 624 function(tabGroup) { 625 tabGroup.addMember(this._subjectField); 626 tabGroup.addMember(this._location); 627 628 var bodyFieldId = this._notesHtmlEditor.getBodyFieldId(); 629 tabGroup.addMember(document.getElementById(bodyFieldId)); 630 }; 631 632 // Consistent spot to locate various dialogs 633 ZmTaskEditView.prototype._getDialogXY = 634 function() { 635 var loc = Dwt.toWindow(this.getHtmlElement(), 0, 0); 636 return new DwtPoint(loc.x + ZmTaskEditView.DIALOG_X, loc.y + ZmTaskEditView.DIALOG_Y); 637 }; 638 639 ZmTaskEditView.prototype._setPercentCompleteFields = 640 function(isComplete) { 641 var val = isComplete 642 ? ZmTaskEditView.STATUS_VALUES[1] 643 : ZmTaskEditView.STATUS_VALUES[0]; 644 this._statusSelect.setSelectedValue(val); 645 this._pCompleteSelectInput.setValue(this.formatPercentComplete(isComplete ? 100 : 0)); 646 }; 647 648 // Listeners 649 ZmTaskEditView.prototype._handleCompleteOnBlur = 650 function(inputEl) { 651 var pCompleteString = inputEl.value; 652 if (!pCompleteString) { 653 inputEl.value = this.formatPercentComplete(0); 654 return; 655 } 656 var newVal = this.getpCompleteInputValue(); 657 if (newVal.valid) { 658 if (newVal.percent == 100) { 659 this._statusSelect.setSelectedValue(ZmCalendarApp.STATUS_COMP); 660 this._unSelectRemindersCheckbox(); //bug:51913 disable alarm when stats is completed 661 } else if (newVal.percent == 0) { 662 this._statusSelect.setSelectedValue(ZmCalendarApp.STATUS_NEED); 663 } else if ((newVal.percent > 0 || newVal.percent < 100) && (this._statusSelect.getValue() != ZmCalendarApp.STATUS_COMP || 664 this._statusSelect.getValue() != ZmCalendarApp.STATUS_NEED)) { 665 this._statusSelect.setSelectedValue(ZmCalendarApp.STATUS_INPR); 666 } 667 inputEl.value = this.formatPercentComplete(pCompleteString); 668 } 669 }; 670 671 ZmTaskEditView.prototype._pCompleteButtonListener = 672 function(ev) { 673 var menu = ev.item.getMenu(); 674 ev.item.popup(); 675 }; 676 677 ZmTaskEditView.prototype._pCompleteSelectListener = 678 function(ev) { 679 if(ev.item && ev.item instanceof DwtMenuItem){ 680 var newVal = ev.item.getData("value"); 681 this._pCompleteSelectInput.setValue(ev.item.getText()); 682 683 if (newVal == 100) { 684 this._statusSelect.setSelectedValue(ZmCalendarApp.STATUS_COMP); 685 this._unSelectRemindersCheckbox(); //bug:51913 disable alarm when stats is completed 686 } else if (newVal == 0) { 687 this._statusSelect.setSelectedValue(ZmCalendarApp.STATUS_NEED); 688 } else if ((newVal > 0 || newVal < 100) && (this._statusSelect.getValue() != ZmCalendarApp.STATUS_COMP || this._statusSelect.getValue() != ZmCalendarApp.STATUS_NEED)) 689 { 690 this._statusSelect.setSelectedValue(ZmCalendarApp.STATUS_INPR); 691 } 692 this._setEmailReminderControls(); 693 return; 694 } 695 }; 696 697 ZmTaskEditView.prototype._selectListener = 698 function(ev) { 699 var newVal = ev._args.newValue; 700 var oldVal = ev._args.oldValue; 701 702 if (newVal == oldVal) { return; } 703 704 var selObj = ev._args.selectObj; 705 706 if (selObj == this._statusSelect) { 707 if (newVal == ZmCalendarApp.STATUS_COMP) { 708 this._pCompleteSelectInput.setValue(this.formatPercentComplete(100)); 709 this._unSelectRemindersCheckbox(); //bug:51913 disable alarm when stats is completed 710 } else if (newVal == ZmCalendarApp.STATUS_NEED) { 711 this._pCompleteSelectInput.setValue(this.formatPercentComplete(0)); 712 } else if (newVal == ZmCalendarApp.STATUS_INPR) { 713 var completion = this.getpCompleteInputValue(); 714 if (completion.valid && (completion.percent == 100)) { 715 this._pCompleteSelectInput.setValue(this.formatPercentComplete(0)); 716 } 717 } 718 } else { 719 if (newVal == 100) { 720 this._statusSelect.setSelectedValue(ZmCalendarApp.STATUS_COMP); 721 this._unSelectRemindersCheckbox(); 722 } else if (newVal == 0) { 723 this._statusSelect.setSelectedValue(ZmCalendarApp.STATUS_NEED); 724 } else if ((oldVal == 0 || oldVal == 100) && 725 (newVal > 0 || newVal < 100) && 726 (this._statusSelect.getValue() == ZmCalendarApp.STATUS_COMP || 727 this._statusSelect.getValue() == ZmCalendarApp.STATUS_NEED)) 728 { 729 this._statusSelect.setSelectedValue(ZmCalendarApp.STATUS_INPR); 730 } 731 } 732 this._setEmailReminderControls(); 733 }; 734 735 736 // Callbacks 737 738 ZmTaskEditView.prototype._handleOnClick = 739 function(el) { 740 ZmCalItemEditView.prototype._handleOnClick.call(this, el); 741 }; 742 743 744 ZmTaskEditView.prototype._setRemindersEnabled = 745 function(isEnabled) { 746 if (this._hasReminderSupport) { 747 this._remindDateButton.setEnabled(isEnabled); 748 this._remindTimeSelect.setEnabled(isEnabled); 749 Dwt.addClass(this._remindDateField.parentNode, !isEnabled ? 'DWTInputField-disabled' : 'DWTInputField', !isEnabled ? 'DWTInputField' : 'DWTInputField-disabled'); 750 this._remindDateField.disabled = !isEnabled; 751 } 752 }; 753 754 ZmTaskEditView.prototype._setRemindersConfigureEnabled = function(enabled) { 755 this._reminderConfigure.setEnabled(enabled); 756 this._reminderConfigure.getHtmlElement().onclick = enabled ? AjxCallback.simpleClosure(skin.gotoPrefs, skin, "NOTIFICATIONS") : null; 757 }; 758 759 // 760 // ZmCalItemEditView methods 761 // 762 763 ZmTaskEditView.prototype._setEmailReminderControls = function() { 764 if (this._hasReminderSupport) { 765 766 ZmCalItemEditView.prototype._setEmailReminderControls.apply(this, arguments); 767 768 // Bug 55392: Disable reminders altogether when task is completed 769 var remindersEnabled = (this._statusSelect.getValue() != ZmCalendarApp.STATUS_COMP); 770 Dwt.condClass(this._reminderLabel, remindersEnabled, "", "ZDisabled"); 771 this._reminderCheckbox.setEnabled(remindersEnabled); 772 773 // primary reminder checkbox overrides other values 774 var isSelected = this._reminderCheckbox.isSelected(); 775 this._setRemindersEnabled(isSelected); 776 if (!isSelected) { 777 this._reminderEmailCheckbox.setEnabled(false); 778 this._reminderDeviceEmailCheckbox.setEnabled(false); 779 } 780 this._setRemindersConfigureEnabled(isSelected); 781 this._reminderDeviceEmailCheckbox.setVisible(appCtxt.get(ZmSetting.CAL_DEVICE_EMAIL_REMINDERS_ENABLED)); 782 } 783 }; 784 785 ZmTaskEditView.prototype.adjustReminderValue = function(calItem) { 786 // no-op 787 }; 788 789 ZmTaskEditView.prototype._resetReminders = function() { 790 // no-op 791 }; 792