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 * Creates a new appointment recurrence dialog. The view displays itself on construction. 26 * @constructor 27 * @class 28 * This class provides a dialog for creating/editing recurrences for an appointment 29 * 30 * @author Parag Shah 31 * 32 * @param {ZmControl} parent the element that created this view 33 * @param {String} className optional class name for this view 34 * 35 * @extends DwtDialog 36 */ 37 ZmApptRecurDialog = function(parent, uid, className) { 38 DwtDialog.call(this, {parent:parent, className:className, title:ZmMsg.customRepeat}); 39 40 // set html content once (hence, in ctor) 41 this.setContent(this._setHtml(uid)); 42 this._createRepeatSections(uid); 43 this._createDwtObjects(uid); 44 this._cacheFields(); 45 this._addEventHandlers(); 46 this._createTabGroup(); 47 48 this.setButtonListener(DwtDialog.OK_BUTTON, new AjxListener(this, this._okListener)); 49 this.addSelectionListener(DwtDialog.CANCEL_BUTTON, new AjxListener(this, this._cancelListener)); 50 }; 51 52 ZmApptRecurDialog.prototype = new DwtDialog; 53 ZmApptRecurDialog.prototype.constructor = ZmApptRecurDialog; 54 55 56 // Consts 57 58 ZmApptRecurDialog.REPEAT_OPTIONS = [ 59 { label: ZmMsg.none, value: ZmRecurrence.NONE, selected: true }, 60 { label: ZmMsg.daily, value: ZmRecurrence.DAILY, selected: false }, 61 { label: ZmMsg.weekly, value: ZmRecurrence.WEEKLY, selected: false }, 62 { label: ZmMsg.monthly, value: ZmRecurrence.MONTHLY, selected: false }, 63 { label: ZmMsg.yearly, value: ZmRecurrence.YEARLY, selected: false }]; 64 65 66 // Public methods 67 68 ZmApptRecurDialog.prototype.toString = 69 function() { 70 return "ZmApptRecurDialog"; 71 }; 72 73 ZmApptRecurDialog.prototype.getTabGroupMember = function() { 74 return this._tabGroup; 75 }; 76 77 ZmApptRecurDialog.prototype.initialize = 78 function(startDate, endDate, repeatType, appt) { 79 this._startDate = new Date(startDate.getTime()); 80 this._endDate = new Date(endDate.getTime()); 81 this._origRefDate = startDate; 82 // based on repeat type, setup the repeat type values 83 var repeatType = repeatType || ZmRecurrence.DAILY; 84 this._repeatSelect.setSelectedValue(repeatType); 85 this._setRepeatSection(repeatType); 86 87 // dont bother initializing if user is still mucking around 88 if (this._saveState) 89 return; 90 91 var startDay = this._startDate.getDay(); 92 var startDate = this._startDate.getDate(); 93 var startMonth = this._startDate.getMonth(); 94 95 // reset time based fields 96 this._endByField.setValue(AjxDateUtil.simpleComputeDateStr(this._startDate)); 97 this._weeklySelectButton._selected = startDay; 98 this._weeklySelectButton.setDisplayState(DwtControl.SELECTED); 99 100 var formatter = new AjxMessageFormat(ZmMsg.recurWeeklyEveryWeekday); 101 var dayFormatter = formatter.getFormatsByArgumentIndex()[0]; 102 this._weeklySelectButton.setText(dayFormatter.format(this._origRefDate)); 103 104 this._weeklyCheckboxes[startDay].checked = true; 105 this._monthlyDayField.setValue(startDate); 106 this._monthlyWeekdaySelect.setSelected(startDay); 107 this._yearlyDayField.setValue(startDate); 108 this._yearlyMonthSelect.setSelected(startMonth); 109 this._yearlyWeekdaySelect.setSelected(startDay); 110 this._yearlyMonthSelectEx.setSelected(startMonth); 111 112 this._isDirty = false; 113 114 // if given appt object, means user is editing existing appointment's recur rules 115 if (appt) { 116 this._populateForEdit(appt); 117 } 118 }; 119 120 ZmApptRecurDialog.prototype.isDirty = 121 function() { 122 return this._isDirty; 123 }; 124 125 /** 126 * Gets the selected repeat value. 127 * 128 * @return {constant} the repeat value 129 */ 130 ZmApptRecurDialog.prototype.getSelectedRepeatValue = 131 function() { 132 return this._repeatSelect.getValue(); 133 }; 134 135 /** 136 * Sets repeat end values. 137 * 138 * @param {ZmAppt} appt the appointment 139 */ 140 ZmApptRecurDialog.prototype.setRepeatEndValues = 141 function(appt) { 142 var recur = appt._recurrence; 143 recur.repeatEndType = this._getRadioOptionValue(this._repeatEndName); 144 145 // add any details for the select option 146 if (recur.repeatEndType == "A") 147 recur.repeatEndCount = this._endIntervalField.getValue(); 148 else if (recur.repeatEndType == "D") 149 recur.repeatEndDate = AjxDateUtil.simpleParseDateStr(this._endByField.getValue()); 150 }; 151 152 /** 153 * Sets custom daily values. 154 * 155 * @param {ZmAppt} appt the appointment 156 */ 157 ZmApptRecurDialog.prototype.setCustomDailyValues = 158 function(appt) { 159 var recur = appt._recurrence; 160 var value = this._getRadioOptionValue(this._dailyRadioName); 161 recur._startDate = new Date(this._origRefDate); 162 recur.repeatCustom = "1"; 163 recur.repeatWeekday = false; 164 165 if (value == "2") { 166 recur.repeatWeekday = true; 167 //Let's check if it is sat/sunday today 168 var d = new Date(this._origRefDate); //Using the start date specified...can be in the past 169 if(d.getDay()==AjxDateUtil.SUNDAY || d.getDay()==AjxDateUtil.SATURDAY){ 170 recur._startDate = AjxDateUtil.getDateForNextDay(d,AjxDateUtil.MONDAY); // get subsequent monday, weekday 171 } 172 recur.repeatCustomCount = 1; 173 } else { 174 recur.repeatCustomCount = value == "3" ? (Number(this._dailyField.getValue())) : 1; 175 } 176 }; 177 178 /** 179 * Sets custom weekly values. 180 * 181 * @param {ZmAppt} appt the appointment 182 */ 183 ZmApptRecurDialog.prototype.setCustomWeeklyValues = 184 function(appt) { 185 var recur = appt._recurrence; 186 recur.repeatWeeklyDays = [] 187 recur.repeatCustom = "1"; 188 recur._startDate = new Date(this._origRefDate); 189 var value = this._getRadioOptionValue(this._weeklyRadioName); 190 var currentDay = recur._startDate.getDay(); 191 if (value == "1") { 192 recur.repeatCustomCount = 1; 193 var startDay = this._weeklySelectButton._selected; 194 switch(startDay){ 195 case 7: //Separator 196 break; 197 case 8: //Mon, wed, Fri 198 recur.repeatWeeklyDays.push(ZmCalItem.SERVER_WEEK_DAYS[AjxDateUtil.MONDAY]); 199 recur.repeatWeeklyDays.push(ZmCalItem.SERVER_WEEK_DAYS[AjxDateUtil.WEDNESDAY]); 200 recur.repeatWeeklyDays.push(ZmCalItem.SERVER_WEEK_DAYS[AjxDateUtil.FRIDAY]); 201 startDay = AjxDateUtil.MONDAY; 202 while(startDay < currentDay){ 203 startDay += 2; 204 } 205 break; 206 case 9: //Tue, Thu 207 recur.repeatWeeklyDays.push(ZmCalItem.SERVER_WEEK_DAYS[AjxDateUtil.TUESDAY]); 208 recur.repeatWeeklyDays.push(ZmCalItem.SERVER_WEEK_DAYS[AjxDateUtil.THURSDAY]); 209 startDay = AjxDateUtil.TUESDAY; 210 while(startDay < currentDay){ 211 startDay += 2; 212 } 213 break; 214 case 10: //Sat, Sunday 215 recur.repeatWeeklyDays.push(ZmCalItem.SERVER_WEEK_DAYS[AjxDateUtil.SATURDAY]); 216 recur.repeatWeeklyDays.push(ZmCalItem.SERVER_WEEK_DAYS[AjxDateUtil.SUNDAY]); 217 startDay = currentDay == AjxDateUtil.SUNDAY? currentDay:AjxDateUtil.SATURDAY; 218 break; 219 default: 220 recur.repeatWeeklyDays.push(ZmCalItem.SERVER_WEEK_DAYS[this._weeklySelectButton._selected/*getValue()*/]); 221 break; 222 } 223 recur._startDate = AjxDateUtil.getDateForNextDay(new Date(this._origRefDate),startDay); 224 //recur._endDate = recur._startDate; 225 } else { 226 recur.repeatCustomCount = Number(this._weeklyField.getValue()); 227 var selectedDays = []; 228 for (var i = 0; i < this._weeklyCheckboxes.length; i++) { 229 if (this._weeklyCheckboxes[i].checked){ 230 selectedDays.push(i); 231 recur.repeatWeeklyDays.push(ZmCalItem.SERVER_WEEK_DAYS[i]); 232 } 233 } 234 var startDay = currentDay; 235 for(var i =0; i < selectedDays.length;i++){ 236 var startDay = selectedDays[i]; 237 if(startDay >= currentDay) { //In past 238 break; 239 } 240 } 241 recur._startDate = AjxDateUtil.getDateForNextDay(new Date(this._origRefDate),startDay); 242 } 243 }; 244 245 /** 246 * Sets custom monthly values. 247 * 248 * @param {ZmAppt} appt the appointment 249 */ 250 ZmApptRecurDialog.prototype.setCustomMonthlyValues = 251 function(appt) { 252 var recur = appt._recurrence; 253 recur.repeatCustom = "1"; 254 var value = this._getRadioOptionValue(this._monthlyRadioName); 255 recur._startDate = new Date(this._origRefDate); 256 if (value == "1") { 257 recur.repeatCustomType = "S"; 258 recur.repeatCustomCount = this._monthlyMonthField.getValue(); 259 recur.repeatMonthlyDayList = [this._monthlyDayField.getValue()]; 260 recur.repeatCustomMonthDay = this._monthlyDayField.getValue(); 261 recur._startDate.setDate(recur.repeatCustomMonthDay); 262 var today = new Date(this._origRefDate); //Reference date... 263 var diff = (today - recur._startDate); 264 if(diff >= AjxDateUtil.MSEC_PER_DAY || today.getDate() > recur._startDate.getDate()){ // was in the past, so let's use the next date 265 recur._startDate.setMonth(recur._startDate.getMonth()+1); 266 } 267 268 } else { 269 recur.repeatCustomType = "O"; 270 recur.repeatCustomCount = this._monthlyMonthFieldEx.getValue(); 271 recur.repeatBySetPos = this._monthlyDaySelect.getValue(); 272 recur.repeatCustomDayOfWeek = ZmCalItem.SERVER_WEEK_DAYS[this._monthlyWeekdaySelect.getValue()]; 273 recur.repeatCustomDays = this.getWeekdaySelectValue(this._monthlyWeekdaySelect); 274 275 if(recur.repeatBySetPos==-1){ // Last day 276 var lastDate = new Date(this._origRefDate); 277 lastDate.setDate(AjxDateUtil.daysInMonth(lastDate.getFullYear(),lastDate.getMonth())); //Date is now last date of this month 278 var lastDayDate = this.getPossibleStartDate(this._monthlyWeekdaySelect.getValue(), lastDate, recur.repeatBySetPos); 279 280 //Check if it is already paased 281 var today = new Date(this._origRefDate); 282 var diff = (today - lastDayDate); 283 var isInPast = today.getTime() > lastDayDate.getTime(); 284 if(diff >= AjxDateUtil.MSEC_PER_DAY || isInPast ){ //In the past 285 // Go for next month 286 lastDate.setMonth(lastDate.getMonth()+1); 287 recur._startDate = this.getPossibleStartDate(this._monthlyWeekdaySelect.getValue(), lastDate, recur.repeatBySetPos); 288 }else{ 289 recur._startDate = lastDayDate; 290 } 291 }else{ 292 var first = new Date(this._origRefDate); 293 first.setDate(1); 294 recur._startDate = this.getPossibleStartDate(this._monthlyWeekdaySelect.getValue(), first, recur.repeatBySetPos); //AjxDateUtil.getDateForNextDay(first,this.getFirstWeekDayOffset(this._monthlyWeekdaySelect),recur.repeatBySetPos); 295 //Check if it is already paased 296 var today = new Date(this._origRefDate); 297 var diff = (today - recur._startDate); 298 var isInPast = today.getTime() > recur._startDate.getTime(); 299 if(diff >= AjxDateUtil.MSEC_PER_DAY || isInPast){ //In the past 300 // Go for next month, find the date as per rule 301 first.setMonth(first.getMonth() + 1);//Next month 302 recur._startDate = this.getPossibleStartDate(this._monthlyWeekdaySelect.getValue(), first, recur.repeatBySetPos); 303 } 304 } 305 } 306 }; 307 308 /** 309 * Sets custom yearly values. 310 * 311 * @param {ZmAppt} appt the appointment 312 */ 313 ZmApptRecurDialog.prototype.setCustomYearlyValues = 314 function(appt) { 315 appt._recurrence.repeatCustom = "1"; 316 var recur = appt._recurrence; 317 recur._startDate = new Date(this._origRefDate); 318 var value = this._getRadioOptionValue(this._yearlyRadioName); 319 320 if (value == "1") { 321 appt._recurrence.repeatCustomType = "S"; 322 appt._recurrence.repeatCustomMonthDay = this._yearlyDayField.getValue(); 323 appt._recurrence.repeatYearlyMonthsList = this._yearlyMonthSelect.getValue() + 1; 324 //Create date out of it 325 var d = new Date(this._origRefDate); 326 d.setDate(appt._recurrence.repeatCustomMonthDay); 327 d.setMonth(this._yearlyMonthSelect.getValue()); 328 //Try to judge, if this date is in future 329 var today = new Date(this._origRefDate); 330 var diff = (today - d); 331 var isInPast = today.getTime() > d.getTime(); 332 if( diff >= AjxDateUtil.MSEC_PER_DAY || isInPast){ //In the past 333 d.setFullYear(d.getFullYear()+1); 334 } 335 appt._recurrence._startDate = d; 336 appt._recurrence._endDate = d; 337 } else { 338 appt._recurrence.repeatCustomType = "O"; 339 appt._recurrence.repeatBySetPos = this._yearlyDaySelect.getValue(); 340 appt._recurrence.repeatCustomDayOfWeek = ZmCalItem.SERVER_WEEK_DAYS[this._yearlyWeekdaySelect.getValue()]; 341 appt._recurrence.repeatCustomDays = this.getWeekdaySelectValue(this._yearlyWeekdaySelect); 342 343 appt._recurrence.repeatYearlyMonthsList = this._yearlyMonthSelectEx.getValue() + 1; 344 var d = new Date(this._origRefDate); 345 d.setMonth(this._yearlyMonthSelectEx.getValue()); 346 //Check if date is in past 347 if(appt._recurrence.repeatBySetPos < 0){ // we want last day 348 d.setDate(AjxDateUtil.daysInMonth(d.getFullYear(),d.getMonth())); 349 }else{ 350 d.setDate(1); 351 } 352 var dt = this.getPossibleStartDate(this._yearlyWeekdaySelect.getValue(), d, appt._recurrence.repeatBySetPos); 353 354 var today = new Date(this._origRefDate); 355 var diff = (today -dt); 356 var isInPast = today.getTime() > dt.getTime(); 357 if(diff >= AjxDateUtil.MSEC_PER_DAY || isInPast){ // In the past 358 d.setFullYear(d.getFullYear()+1); 359 if(appt._recurrence.repeatBySetPos < 0){ // we want last day 360 d.setDate(AjxDateUtil.daysInMonth(d.getFullYear(),d.getMonth())); 361 }else{ 362 d.setDate(1); 363 } 364 } 365 appt._recurrence._startDate = this.getPossibleStartDate(this._yearlyWeekdaySelect.getValue(), d, appt._recurrence.repeatBySetPos); 366 appt._recurrence._endDate = appt._recurrence._startDate; 367 } 368 }; 369 370 ZmApptRecurDialog.prototype.addSelectionListener = 371 function(buttonId, listener) { 372 this._button[buttonId].addSelectionListener(listener); 373 }; 374 375 ZmApptRecurDialog.prototype.clearState = 376 function() { 377 this._saveState = false; 378 this._cleanup(); 379 }; 380 381 ZmApptRecurDialog.prototype.isValid = 382 function() { 383 var valid = true; 384 385 // ONLY for the selected options, check if their fields are valid 386 var repeatValue = this._repeatSelect.getValue(); 387 388 if (repeatValue == ZmRecurrence.DAILY) { 389 if (this._dailyFieldRadio.checked) 390 valid = this._dailyField.isValid(); 391 if (!valid) 392 this._dailyField.blur(); 393 } else if (repeatValue == ZmRecurrence.WEEKLY) { 394 if (this._weeklyFieldRadio.checked) { 395 valid = this._weeklyField.isValid(); 396 if (valid) { 397 valid = false; 398 for (var i=0; i<this._weeklyCheckboxes.length; i++) { 399 if (this._weeklyCheckboxes[i].checked) { 400 valid = true; 401 break; 402 } 403 } 404 } 405 // weekly section is special - force a focus if valid to clear out error 406 this._weeklyField.focus(); 407 this._weeklyField.blur(); 408 } 409 } else if (repeatValue == ZmRecurrence.MONTHLY) { 410 if (this._monthlyDefaultRadio.checked) { 411 valid = this._monthlyMonthField.isValid() && this._monthlyDayField.isValid(); 412 if (!valid) { 413 this._monthlyMonthField.blur(); 414 this._monthlyDayField.blur(); 415 } 416 } else { 417 valid = this._monthlyMonthFieldEx.isValid(); 418 if (!valid) 419 this._monthlyMonthFieldEx.blur(); 420 } 421 } else if (repeatValue == ZmRecurrence.YEARLY) { 422 if (this._yearlyDefaultRadio.checked) 423 valid = this._yearlyDayField.isValid(); 424 if (!valid) 425 this._yearlyDayField.blur(); 426 } 427 428 // check end section 429 if (valid) { 430 if (this._endAfterRadio.checked) { 431 valid = this._endIntervalField.isValid(); 432 if (!valid) 433 this._endIntervalField.blur(); 434 } else if (this._endByRadio.checked) { 435 valid = this._endByField.isValid(); 436 if (!valid) 437 this._endByField.blur(); 438 } 439 } 440 441 return valid; 442 }; 443 444 445 // Private / protected methods 446 447 ZmApptRecurDialog.prototype._setHtml = 448 function(uid) { 449 this._repeatSelectId = Dwt.getNextId(); 450 this._repeatSectionId = Dwt.getNextId(); 451 this._repeatEndDivId = Dwt.getNextId(); 452 var html = new Array(); 453 var i = 0; 454 455 html[i++] = "<table width=450>"; 456 html[i++] = "<tr><td><fieldset"; 457 if (AjxEnv.isMozilla) 458 html[i++] = " style='border:1px dotted #555'"; 459 html[i++] = "><legend style='color:#555555'>"; 460 html[i++] = ZmMsg.repeat; 461 html[i++] = "</legend><div style='height:110px'>"; 462 html[i++] = "<div id='"; 463 html[i++] = this._repeatSelectId; 464 html[i++] = "' style='margin-bottom:.25em;'></div><div id='"; 465 html[i++] = this._repeatSectionId; 466 html[i++] = "'></div>"; 467 html[i++] = "</div></fieldset></td></tr>"; 468 html[i++] = "<tr><td><div id='"; 469 html[i++] = this._repeatEndDivId; 470 html[i++] = "'><fieldset"; 471 if (AjxEnv.isMozilla) 472 html[i++] = " style='border:1px dotted #555'"; 473 html[i++] = "><legend style='color:#555'>"; 474 html[i++] = ZmMsg.end; 475 html[i++] = "</legend>"; 476 html[i++] = this._getEndHtml(uid); 477 html[i++] = "</fieldset></div></td></tr>"; 478 html[i++] = "</table>"; 479 480 return html.join(""); 481 }; 482 483 ZmApptRecurDialog.prototype._getEndHtml = 484 function(uid) { 485 this._repeatEndName = Dwt.getNextId(); 486 this._noEndDateRadioId = "NO_END_DATE_RADIO_" + uid; // Dwt.getNextId(); 487 this._endByRadioId = "END_BY_RADIO_" + uid; // Dwt.getNextId(); 488 this._endAfterRadioId = "END_AFTER_RADIO_" + uid; // Dwt.getNextId(); 489 // unique ids for endIntervalFieldId and endByField 490 this._endIntervalFieldId = "END_INTERVAL_FIELD_" + uid; // Dwt.getNextId(); 491 this._endByFieldId = "END_BY_FIELD_" + uid; // Dwt.getNextId(); 492 this._endByButtonId = "END_BY_BUTTON_" + uid; // Dwt.getNextId(); 493 494 var html = new Array(); 495 var i = 0; 496 497 // start table 498 html[i++] = "<table class='ZRadioButtonTable'>"; 499 // no end date 500 html[i++] = "<tr><td width=1%><input checked value='N' type='radio' name='"; 501 html[i++] = this._repeatEndName; 502 html[i++] = "' id='"; 503 html[i++] = this._noEndDateRadioId; 504 html[i++] = "'></td><td colspan=2>"; 505 html[i++] = "<label for='"; 506 html[i++] = this._noEndDateRadioId; 507 html[i++] = "'>" 508 html[i++] = ZmMsg.recurEndNone; 509 html[i++] = "</label>" 510 html[i++] = "</td></tr>"; 511 // end after <num> occurrences 512 html[i++] = "<tr><td><input type='radio' value='A' name='"; 513 html[i++] = this._repeatEndName; 514 html[i++] = "' id='"; 515 html[i++] = this._endAfterRadioId; 516 html[i++] = "'></td><td colspan=2>"; 517 html[i++] = "<table><tr>"; 518 var formatter = new AjxMessageFormat(ZmMsg.recurEndNumber); 519 var segments = formatter.getSegments(); 520 for (var s = 0; s < segments.length; s++) { 521 html[i++] = "<td>"; 522 var segment = segments[s]; 523 if (segment instanceof AjxMessageFormat.MessageSegment && 524 segment.getIndex() == 0) { 525 html[i++] = "<span id='"; 526 html[i++] = this._endIntervalFieldId; 527 html[i++] = "' class='ZInlineInput'></span>"; 528 } 529 else { 530 html[i++] = "<label for='"; 531 html[i++] = this._endAfterRadioId; 532 html[i++] = "'>"; 533 html[i++] = segment.toSubPattern(); 534 html[i++] = "</label>"; 535 } 536 html[i++] = "</td>"; 537 } 538 html[i++] = "</tr></table>"; 539 html[i++] = "</td></tr>"; 540 // end by <date> 541 html[i++] = "<tr><td><input type='radio' value='D' name='"; 542 html[i++] = this._repeatEndName; 543 html[i++] = "' id='"; 544 html[i++] = this._endByRadioId; 545 html[i++] = "'></td><td>"; 546 html[i++] = "<table><tr>"; 547 var formatter = new AjxMessageFormat(ZmMsg.recurEndByDate); 548 var segments = formatter.getSegments(); 549 for (var s = 0; s < segments.length; s++) { 550 var segment = segments[s]; 551 if (segment instanceof AjxMessageFormat.MessageSegment && 552 segment.getIndex() == 0) { 553 html[i++] = "<td id='"; 554 html[i++] = this._endByFieldId; 555 html[i++] = "' style='padding:0 0 0 .5em'></td><td id='"; 556 html[i++] = this._endByButtonId; 557 html[i++] = "' style='padding:0 .5em 0 0'></td>"; 558 } 559 else { 560 html[i++] = "<td style='padding-left:2px;padding-right:2px'>"; 561 html[i++] = "<label for='"; 562 html[i++] = this._endByRadioId; 563 html[i++] = "'>"; 564 html[i++] = segment.toSubPattern(); 565 html[i++] = "</label>"; 566 } 567 html[i++] = "</td>"; 568 } 569 html[i++] = "</tr></table>"; 570 html[i++] = "</td></tr>"; 571 // end table 572 html[i++] = "</table>"; 573 return html.join(""); 574 }; 575 576 ZmApptRecurDialog.prototype._createRepeatSections = 577 function(uid) { 578 var sectionDiv = document.getElementById(this._repeatSectionId); 579 if (sectionDiv) { 580 var div = document.createElement("div"); 581 div.style.position = "relative"; 582 div.style.display = "none"; 583 div.id = this._repeatDailyId = "REPEAT_DAILY_DIV_" + uid; //Dwt.getNextId(); 584 div.innerHTML = this._createRepeatDaily(uid); 585 sectionDiv.appendChild(div); 586 587 var div = document.createElement("div"); 588 div.style.position = "relative"; 589 div.style.display = "none"; 590 div.id = this._repeatWeeklyId = "REPEAT_WEEKLY_DIV_" + uid; // Dwt.getNextId(); 591 div.innerHTML = this._createRepeatWeekly(uid); 592 sectionDiv.appendChild(div); 593 594 var div = document.createElement("div"); 595 div.style.position = "relative"; 596 div.style.display = "none"; 597 div.id = this._repeatMonthlyId = "REPEAT_MONTHLY_DIV_" + uid; // Dwt.getNextId(); 598 div.innerHTML = this._createRepeatMonthly(uid); 599 sectionDiv.appendChild(div); 600 601 var div = document.createElement("div"); 602 div.style.position = "relative"; 603 div.style.display = "none"; 604 div.id = this._repeatYearlyId = "REPEAT_YEARLY_DIV_" + uid; // Dwt.getNextId(); 605 div.innerHTML = this._createRepeatYearly(uid); 606 sectionDiv.appendChild(div); 607 } 608 }; 609 610 ZmApptRecurDialog.prototype._createRepeatDaily = 611 function(uid) { 612 this._dailyRadioName = "DAILY_RADIO_" + uid; // Dwt.getNextId(); 613 this._dailyDefaultId = "DAILY_DEFAULT_" + uid; // Dwt.getNextId(); 614 this._dailyWeekdayId = "DAILY_WEEKDAY_" + uid; // Dwt.getNextId(); 615 this._dailyFieldRadioId = "DAILY_FIELD_RADIO_" + uid; // Dwt.getNextId(); 616 this._dailyFieldId = "DAILY_FIELD_" + uid; // Dwt.getNextId(); 617 618 var html = new Array(); 619 var i = 0; 620 621 // start table 622 html[i++] = "<table class='ZRadioButtonTable'>"; 623 // every day 624 html[i++] = "<tr><td><input checked value='1' type='radio' name='"; 625 html[i++] = this._dailyRadioName; 626 html[i++] = "' id='"; 627 html[i++] = this._dailyDefaultId; 628 html[i++] = "'></td>"; 629 html[i++] = "<td>"; 630 html[i++] = "<label for='"; 631 html[i++] = this._dailyDefaultId; 632 html[i++] = "'>"; 633 html[i++] = ZmMsg.recurDailyEveryDay; 634 html[i++] = "</label>" 635 html[i++] = "</td></tr>"; 636 // every weekday 637 html[i++] = "<tr><td><input value='2' type='radio' name='"; 638 html[i++] = this._dailyRadioName; 639 html[i++] = "' id='"; 640 html[i++] = this._dailyWeekdayId; 641 html[i++] = "'></td>"; 642 html[i++] = "<td>"; 643 html[i++] = "<label for='"; 644 html[i++] = this._dailyWeekdayId; 645 html[i++] = "'>"; 646 html[i++] = ZmMsg.recurDailyEveryWeekday; 647 html[i++] = "</label>"; 648 html[i++] = "</td></tr>"; 649 // every <num> days 650 html[i++] = "<tr><td><input value='3' type='radio' name='"; 651 html[i++] = this._dailyRadioName; 652 html[i++] = "' id='"; 653 html[i++] = this._dailyFieldRadioId; 654 html[i++] = "'></td><td>"; 655 html[i++] = "<table><tr>"; 656 var formatter = new AjxMessageFormat(ZmMsg.recurDailyEveryNumDays); 657 var segments = formatter.getSegments(); 658 for (var s = 0; s < segments.length; s++) { 659 html[i++] = "<td>"; 660 var segment = segments[s]; 661 if (segment instanceof AjxMessageFormat.MessageSegment && 662 segment.getIndex() == 0) { 663 html[i++] = "<span id='"; 664 html[i++] = this._dailyFieldId; 665 html[i++] = "' class='ZInlineInput'></span>"; 666 } 667 else { 668 html[i++] = "<label for='"; 669 html[i++] = this._dailyFieldRadioId; 670 html[i++] = "'>"; 671 html[i++] = segment.toSubPattern(); 672 html[i++] = "</label>"; 673 } 674 html[i++] = "</td>"; 675 } 676 html[i++] = "</tr></table>"; 677 html[i++] = "</td></tr>"; 678 // end table 679 html[i++] = "</table>"; 680 return html.join(""); 681 }; 682 683 ZmApptRecurDialog.prototype._createRepeatWeekly = 684 function(uid) { 685 this._weeklyRadioName = "WEEKLY_RADIO_" + uid; //Dwt.getNextId(); 686 this._weeklyCheckboxName = "WEEKLY_CHECKBOX_NAME_" + uid ;//Dwt.getNextId(); 687 this._weeklyDefaultId = "WEEKLY_DEFAULT_" + uid ; //Dwt.getNextId(); 688 this._weeklySelectId = "WEEKLY_SELECT_" + uid ;//Dwt.getNextId(); 689 this._weeklyFieldRadioId = "WEEKLY_FIELD_RADIO_" + uid //Dwt.getNextId(); 690 this._weeklyFieldId = "WEEKLY_FIELD_" + uid ;//Dwt.getNextId(); 691 692 var html = new Array(); 693 var i = 0; 694 695 // start table 696 html[i++] = "<table class='ZRadioButtonTable'>"; 697 // every <weekday> 698 html[i++] = "<tr><td><input checked value='1' type='radio' name='"; 699 html[i++] = this._weeklyRadioName; 700 html[i++] = "' id='"; 701 html[i++] = this._weeklyDefaultId; 702 html[i++] = "'></td><td>"; 703 html[i++] = "<table><tr>"; 704 var formatter = new AjxMessageFormat(ZmMsg.recurWeeklyEveryWeekday); 705 var segments = formatter.getSegments(); 706 for (var s = 0; s < segments.length; s++) { 707 var segment = segments[s]; 708 var index = segment instanceof AjxMessageFormat.MessageSegment 709 ? segment.getIndex() : -1; 710 if (index == 0) { 711 html[i++] = "<td id='"; 712 html[i++] = this._weeklySelectId; 713 html[i++] = "' style='padding:0 .5em'>"; 714 } 715 else { 716 html[i++] = "<td>"; 717 html[i++] = "<label for='"; 718 html[i++] = this._weeklyDefaultId; 719 html[i++] = "'>"; 720 html[i++] = segment.toSubPattern(); 721 html[i++] = "</label>"; 722 } 723 html[i++] = "</td>"; 724 } 725 html[i++] = "</tr></table>"; 726 html[i++] = "</td></tr>"; 727 // every <num> weeks on <days of week> 728 html[i++] = "<tr valign='top'><td><input value='2' type='radio' name='"; 729 html[i++] = this._weeklyRadioName; 730 html[i++] = "' id='"; 731 html[i++] = this._weeklyFieldRadioId; 732 html[i++] = "'></td>"; 733 html[i++] = "<td>"; 734 html[i++] = "<table><tr>"; 735 var formatter = new AjxMessageFormat(ZmMsg.recurWeeklyEveryNumWeeksDate); 736 var segments = formatter.getSegments(); 737 for (var s = 0; s < segments.length; s++) { 738 var segment = segments[s]; 739 var index = segment instanceof AjxMessageFormat.MessageSegment 740 ? segment.getIndex() : -1; 741 if (index == 0) { 742 html[i++] = "<td id='"; 743 html[i++] = this._weeklyFieldId; 744 html[i++] = "' style='padding:0 .5em'>"; 745 } 746 else if (index == 1) { 747 html[i++] = "<td>"; 748 html[i++] = "<table style='margin-top:.25em;'><tr>"; 749 for (var j = 0; j < AjxDateUtil.WEEKDAY_MEDIUM.length; j++) { 750 var checkBoxId = Dwt.getNextId(this._weeklyCheckboxName + "_"); 751 html[i++] = "<td><input type='checkbox' name='"; 752 html[i++] = this._weeklyCheckboxName; 753 html[i++] = "' id='" 754 html[i++] = checkBoxId; 755 html[i++] = "'></td><td style='padding-right:.75em;'>"; 756 html[i++] = "<label for='"; 757 html[i++] = checkBoxId; 758 html[i++] = "'>"; 759 html[i++] = AjxDateUtil.WEEKDAY_MEDIUM[j]; 760 html[i++] = "</label>"; 761 html[i++] = "</td>"; 762 } 763 html[i++] = "</tr></table>"; 764 } 765 else if (index == 2) { 766 html[i++] = "</td></tr></table>"; 767 html[i++] = "<table><tr>"; 768 continue; 769 } 770 else { 771 html[i++] = "<td>"; 772 html[i++] = "<label for='"; 773 html[i++] = this._weeklyFieldRadioId; 774 html[i++] = "'>"; 775 html[i++] = segment.toSubPattern(); 776 html[i++] = "</label>"; 777 } 778 html[i++] = "</td>"; 779 } 780 html[i++] = "</tr></table>"; 781 html[i++] = "</td></tr>"; 782 // end table 783 html[i++] = "</table>"; 784 785 return html.join(""); 786 }; 787 788 ZmApptRecurDialog.prototype._createRepeatMonthly = 789 function(uid) { 790 this._monthlyRadioName = "MONTHLY_RADIO_" + uid ;//Dwt.getNextId(); 791 this._monthlyDefaultId = "MONTHLY_DEFAULT_" + uid;// Dwt.getNextId(); 792 this._monthlyDayFieldId = "MONTHLY_DAY_FIELD_ID_" + uid; // Dwt.getNextId(); 793 this._monthlyMonthFieldId = "MONTHLY_MONTH_FIELD_" + uid; //Dwt.getNextId(); 794 this._monthlyFieldRadioId = "MONTHLY_FIELD_RADIO_" + uid; //Dwt.getNextId(); 795 this._monthlyDaySelectId = "MONTHLY_DAY_SELECT_" + uid; // Dwt.getNextId(); 796 this._monthlyWeekdaySelectId = "MONTHLY_WEEKDAY_SELECT_" + uid;// Dwt.getNextId(); 797 this._monthlyMonthFieldExId = "MONTHLY_MONTH_FIELD_EX_" + uid; // Dwt.getNextId(); 798 799 var html = new Array(); 800 var i = 0; 801 802 // start table 803 html[i++] = "<table class='ZRadioButtonTable'>"; 804 // every <num> months on the <day> 805 html[i++] = "<tr><td><input checked value='1' type='radio' name='"; 806 html[i++] = this._monthlyRadioName; 807 html[i++] = "' id='"; 808 html[i++] = this._monthlyDefaultId; 809 html[i++] = "'></td>"; 810 html[i++] = "<td>"; 811 html[i++] = "<table class='ZPropertySheet' cellspacing='6'><tr>"; 812 var formatter = new AjxMessageFormat(ZmMsg.recurMonthlyEveryNumMonthsDate); 813 var segments = formatter.getSegments(); 814 for (var s = 0; s < segments.length; s++) { 815 html[i++] = "<td>"; 816 var segment = segments[s]; 817 var index = segment instanceof AjxMessageFormat.MessageSegment 818 ? segment.getIndex() : -1; 819 if (index == 0) { 820 html[i++] = "<span id='"; 821 html[i++] = this._monthlyDayFieldId; 822 html[i++] = "' class='ZInlineInput'></span>"; 823 } 824 else if (index == 1) { 825 html[i++] = "<span id='"; 826 html[i++] = this._monthlyMonthFieldId; 827 html[i++] = "' class='ZInlineInput'></span>"; 828 } 829 else { 830 html[i++] = "<label for='"; 831 html[i++] = this._monthlyDefaultId; 832 html[i++] = "'>"; 833 html[i++] = segment.toSubPattern(); 834 html[i++] = "</label>"; 835 } 836 html[i++] = "</td>"; 837 } 838 html[i++] = "</tr></table>"; 839 html[i++] = "</td></tr>"; 840 // every <num> months on the <ordinal> <weekday> 841 html[i++] = "<tr><td><input value='2' type='radio' name='"; 842 html[i++] = this._monthlyRadioName; 843 html[i++] = "' id='"; 844 html[i++] = this._monthlyFieldRadioId; 845 html[i++] = "'></td>"; 846 html[i++] = "<td>"; 847 html[i++] = "<table class='ZPropertySheet' cellspacing='6'><tr>"; 848 var formatter = new AjxMessageFormat(ZmMsg.recurMonthlyEveryNumMonthsNumDay); 849 var segments = formatter.getSegments(); 850 for (var s = 0; s < segments.length; s++) { 851 var segment = segments[s]; 852 var index = segment instanceof AjxMessageFormat.MessageSegment 853 ? segment.getIndex() : -1; 854 if (index == 0) { 855 html[i++] = "<td id='"; 856 html[i++] = this._monthlyDaySelectId; 857 html[i++] = "' style='overflow:hidden;'>"; 858 } 859 else if (index == 1) { 860 html[i++] = "<td id='"; 861 html[i++] = this._monthlyWeekdaySelectId; 862 html[i++] = "' style='overflow:hidden;'>"; 863 } 864 else if (index == 2) { 865 html[i++] = "<td><span id='"; 866 html[i++] = this._monthlyMonthFieldExId; 867 html[i++] = "' class='ZInlineInput'></span>"; 868 } 869 else { 870 html[i++] = "<td>"; 871 html[i++] = "<label for='"; 872 html[i++] = this._monthlyFieldRadioId; 873 html[i++] = "'>"; 874 html[i++] = segment.toSubPattern(); 875 html[i++] = "</label>"; 876 } 877 html[i++] = "</td>"; 878 } 879 html[i++] = "</tr></table>"; 880 html[i++] = "</td></tr>"; 881 // end table 882 html[i++] = "</table>"; 883 884 return html.join(""); 885 }; 886 887 ZmApptRecurDialog.prototype._createRepeatYearly = 888 function(uid) { 889 this._yearlyDefaultId = "YEALY_DEFAULT_" + uid ; //Dwt.getNextId(); 890 this._yearlyRadioName = "YEARLY_RADIO_" + uid; //Dwt.getNextId(); 891 this._yearlyMonthSelectId = "YEARLY_MONTH_SELECT_" + uid; // Dwt.getNextId(); 892 this._yearlyDayFieldId = "YEARLY_DAY_FIELD_" + uid; // Dwt.getNextId(); 893 this._yearlyDaySelectId = "YEARLY_DAY_SELECT_" + uid; // Dwt.getNextId(); 894 this._yearlyWeekdaySelectId ="YEARLY_WEEKDAY_SELECT_" + uid; //Dwt.getNextId(); 895 this._yearlyMonthSelectExId ="YEARLY_MONTH_SELECT_EX_" + uid; // Dwt.getNextId(); 896 this._yearlyFieldRadioId = "YEARLY_FIELD_RADIO_" + uid;// Dwt.getNextId(); 897 898 var html = new Array(); 899 var i = 0; 900 901 // start table 902 html[i++] = "<table class='ZRadioButtonTable'>"; 903 // every year on <month> <day> 904 html[i++] = "<tr><td><input checked value='1' type='radio' name='"; 905 html[i++] = this._yearlyRadioName; 906 html[i++] = "' id='"; 907 html[i++] = this._yearlyDefaultId; 908 html[i++] = "'></td><td>"; 909 html[i++] = "<table class='ZPropertySheet' cellspacing='6'><tr>"; 910 var formatter = new AjxMessageFormat(ZmMsg.recurYearlyEveryDate); 911 var segments = formatter.getSegments(); 912 for (var s = 0; s < segments.length; s++) { 913 var segment = segments[s]; 914 var index = segment instanceof AjxMessageFormat.MessageSegment 915 ? segment.getIndex() : -1; 916 if (index == 0) { 917 html[i++] = "<td id='"; 918 html[i++] = this._yearlyMonthSelectId; 919 html[i++] = "' style='overflow:hidden;'>"; 920 } 921 else if (index == 1) { 922 html[i++] = "<td><span id='"; 923 html[i++] = this._yearlyDayFieldId; 924 html[i++] = "' class='ZInlineInput'></span>"; 925 } 926 else { 927 html[i++] = "<td>"; 928 html[i++] = "<label for='"; 929 html[i++] = this._yearlyDefaultId; 930 html[i++] = "'>"; 931 html[i++] = segment.toSubPattern(); 932 html[i++] = "</label>"; 933 } 934 html[i++] = "</td>"; 935 } 936 html[i++] = "</tr></table>"; 937 html[i++] = "</td></tr>"; 938 // every year on <ordinal> <weekday> of <month> 939 html[i++] = "<tr><td><input value='2' type='radio' name='"; 940 html[i++] = this._yearlyRadioName; 941 html[i++] = "' id='"; 942 html[i++] = this._yearlyFieldRadioId; 943 html[i++] = "'></td><td>"; 944 html[i++] = "<table class='ZPropertySheet' cellspacing='6'><tr>"; 945 var formatter = new AjxMessageFormat(ZmMsg.recurYearlyEveryMonthNumDay); 946 var segments = formatter.getSegments(); 947 for (var s = 0; s < segments.length; s++) { 948 var segment = segments[s]; 949 var index = segment instanceof AjxMessageFormat.MessageSegment 950 ? segment.getIndex() : -1; 951 if (index == 0) { 952 html[i++] = "<td id='"; 953 html[i++] = this._yearlyDaySelectId; 954 html[i++] = "' style='overflow:hidden;'>"; 955 } 956 else if (index == 1) { 957 html[i++] = "<td id='"; 958 html[i++] = this._yearlyWeekdaySelectId; 959 html[i++] = "' style='overflow:hidden;'>"; 960 } 961 else if (index == 2) { 962 html[i++] = "<td id='"; 963 html[i++] = this._yearlyMonthSelectExId; 964 html[i++] = "' style='overflow:hidden;'>"; 965 } 966 else { 967 html[i++] = "<td>"; 968 html[i++] = "<label for='"; 969 html[i++] = this._yearlyFieldRadioId; 970 html[i++] = "'>"; 971 html[i++] = segment.toSubPattern(); 972 html[i++] = "</label>"; 973 } 974 html[i++] = "</td>"; 975 } 976 html[i++] = "</tr></table>"; 977 html[i++] = "</td></tr>"; 978 // end table 979 html[i++] = "</table>"; 980 return html.join(""); 981 }; 982 983 ZmApptRecurDialog.prototype._createDwtObjects = 984 function(uid) { 985 // create all DwtSelect's 986 this._createSelects(); 987 988 // create mini calendar button for end by field 989 var dateButtonListener = new AjxListener(this, this._endByButtonListener); 990 var dateCalSelectionListener = new AjxListener(this, this._dateCalSelectionListener); 991 ZmCalendarApp.createMiniCalButton(this, this._endByButtonId, dateButtonListener, dateCalSelectionListener); 992 993 // create all DwtInputField's 994 this._createInputs(uid); 995 }; 996 997 ZmApptRecurDialog.prototype._createSelects = 998 function() { 999 this._repeatSelect = new DwtSelect({parent:this}); 1000 this._repeatSelect.addChangeListener(new AjxListener(this, this._repeatChangeListener)); 1001 for (var i = 0; i < ZmApptRecurDialog.REPEAT_OPTIONS.length; i++) { 1002 var option = ZmApptRecurDialog.REPEAT_OPTIONS[i]; 1003 this._repeatSelect.addOption(option.label, option.selected, option.value); 1004 } 1005 this._repeatSelect.reparentHtmlElement(this._repeatSelectId); 1006 delete this._repeatSelectId; 1007 1008 var selectChangeListener = new AjxListener(this, this._selectChangeListener); 1009 this._weeklySelectButton = new DwtButton({parent:this});//new DwtSelect({parent:this}); 1010 var wMenu = new ZmPopupMenu(this._weeklySelectButton); 1011 this._weeklySelectButton.setMenu(wMenu); 1012 //this._weeklySelect.addChangeListener(selectChangeListener); 1013 var formatter = new AjxMessageFormat(ZmMsg.recurWeeklyEveryWeekday); 1014 var dayFormatter = formatter.getFormatsByArgumentIndex()[0]; 1015 var day = new Date(); 1016 day.setDate(day.getDate() - day.getDay()); 1017 var monwedfri = new Array(); 1018 var tuethu = new Array(); 1019 var satsun = new Array(); 1020 for (var i = 0; i < 7; i++) { 1021 //this._weeklySelect.addOption(dayFormatter.format(day), false, i); 1022 var mi = new DwtMenuItem({parent:wMenu, style:DwtMenuItem.CHECK_STYLE, radioGroupId:i}); 1023 mi.setText(dayFormatter.format(day)); 1024 mi.addSelectionListener(selectChangeListener); 1025 mi.setData("index",i); 1026 switch(day.getDay()){ 1027 case AjxDateUtil.SUNDAY: 1028 case AjxDateUtil.SATURDAY: satsun.push(dayFormatter.format(day)); break; 1029 1030 case AjxDateUtil.MONDAY: 1031 case AjxDateUtil.WEDNESDAY: 1032 case AjxDateUtil.FRIDAY: monwedfri.push(dayFormatter.format(day)); break; 1033 1034 case AjxDateUtil.TUESDAY: 1035 case AjxDateUtil.THURSDAY: tuethu.push(dayFormatter.format(day)); break; 1036 } 1037 day.setDate(day.getDate() + 1); 1038 } 1039 //Separator 1040 new DwtMenuItem({parent:wMenu, style:DwtMenuItem.SEPARATOR_STYLE, radioGroupId:i++}); //Pos 7 is separator 1041 //Add some custom pattern options too 1042 //this._weeklySelect.addOption(monwedfri.join(", "), false, i++); 1043 var mi = new DwtMenuItem({parent:wMenu, radioGroupId:i}); 1044 mi.setText(monwedfri.join(", ")); 1045 mi.addSelectionListener(selectChangeListener); 1046 mi.setData("index",i++); 1047 //this._weeklySelect.addOption(tuethu.join(", "), false, i++); 1048 mi = new DwtMenuItem({parent:wMenu, radioGroupId:i}); 1049 mi.setText(tuethu.join(", ")); 1050 mi.addSelectionListener(selectChangeListener); 1051 mi.setData("index",i++); 1052 //Let's correct the sequence 1053 var satsun1 = [satsun[1],satsun[0]]; 1054 //this._weeklySelect.addOption(satsun1.join(", "), false, i++); 1055 mi = new DwtMenuItem({parent:wMenu, radioGroupId:i}); 1056 mi.setText(satsun1.join(", ")); 1057 mi.addSelectionListener(selectChangeListener); 1058 mi.setData("index",i++); 1059 wMenu.setSelectedItem(new Date().getDay()); 1060 this._weeklySelectButton.setText(wMenu.getItem(new Date().getDay()).getText()); 1061 1062 //this._weeklySelect.setv 1063 this._weeklySelectButton.reparentHtmlElement(this._weeklySelectId); 1064 delete this._weeklySelectId; 1065 1066 this._monthlyDaySelect = new DwtSelect({parent:this}); 1067 this._monthlyDaySelect.addChangeListener(selectChangeListener); 1068 var formatter = new AjxMessageFormat(ZmMsg.recurMonthlyEveryNumMonthsNumDay); 1069 var ordinalFormatter = formatter.getFormatsByArgumentIndex()[0]; 1070 var limits = ordinalFormatter.getLimits(); 1071 var formats = ordinalFormatter.getFormats(); 1072 for (var i = 0; i < limits.length; i++) { 1073 var index = (i + 1) % limits.length; 1074 var label = formats[index].format(); 1075 var value = Math.floor(limits[index]); 1076 this._monthlyDaySelect.addOption(label, false, value); 1077 } 1078 this._monthlyDaySelect.reparentHtmlElement(this._monthlyDaySelectId); 1079 delete this._monthlyDaySelectId; 1080 1081 this._monthlyWeekdaySelect = new DwtSelect({parent:this}); 1082 this._monthlyWeekdaySelect.addChangeListener(selectChangeListener); 1083 var formatter = new AjxMessageFormat(ZmMsg.recurMonthlyEveryNumMonthsNumDay); 1084 var dayFormatter = formatter.getFormatsByArgumentIndex()[1]; 1085 var day = new Date(); 1086 day.setDate(day.getDate() - day.getDay()); 1087 1088 this._monthlyWeekdaySelect.addOption(ZmMsg.recurrenceRuleDay, false, ZmRecurrence.RECURRENCE_DAY); 1089 this._monthlyWeekdaySelect.addOption(ZmMsg.recurrenceRuleWeekend, false, ZmRecurrence.RECURRENCE_WEEKEND); 1090 this._monthlyWeekdaySelect.addOption(ZmMsg.recurrenceRuleWeekday, false, ZmRecurrence.RECURRENCE_WEEKDAY); 1091 1092 for (var i = 0; i < 7; i++) { 1093 this._monthlyWeekdaySelect.addOption(dayFormatter.format(day), false, i); 1094 day.setDate(day.getDate() + 1); 1095 } 1096 this._monthlyWeekdaySelect.reparentHtmlElement(this._monthlyWeekdaySelectId); 1097 delete this._monthlyWeekdaySelectId; 1098 1099 this._yearlyMonthSelect = new DwtSelect({parent:this}); 1100 this._yearlyMonthSelect.addChangeListener(selectChangeListener); 1101 var formatter = new AjxMessageFormat(ZmMsg.recurYearlyEveryDate); 1102 var monthFormatter = formatter.getFormatsByArgumentIndex()[0]; 1103 var month = new Date(); 1104 month.setDate(1); 1105 for (var i = 0; i < 12; i++) { 1106 month.setMonth(i); 1107 this._yearlyMonthSelect.addOption(monthFormatter.format(month), false, i); 1108 } 1109 this._yearlyMonthSelect.reparentHtmlElement(this._yearlyMonthSelectId); 1110 delete this._yearlyMonthSelectId; 1111 1112 this._yearlyDaySelect = new DwtSelect({parent:this}); 1113 this._yearlyDaySelect.addChangeListener(selectChangeListener); 1114 var formatter = new AjxMessageFormat(ZmMsg.recurYearlyEveryMonthNumDay); 1115 var ordinalFormatter = formatter.getFormatsByArgumentIndex()[0]; 1116 var limits = ordinalFormatter.getLimits(); 1117 var formats = ordinalFormatter.getFormats(); 1118 for (var i = 0; i < limits.length; i++) { 1119 var index = (i + 1) % limits.length; 1120 var label = formats[index].format(); 1121 var value = Math.floor(limits[index]); 1122 this._yearlyDaySelect.addOption(label, false, value); 1123 } 1124 this._yearlyDaySelect.reparentHtmlElement(this._yearlyDaySelectId); 1125 delete this._yearlyDaySelectId; 1126 1127 this._yearlyWeekdaySelect = new DwtSelect({parent:this}); 1128 this._yearlyWeekdaySelect.addChangeListener(selectChangeListener); 1129 var formatter = new AjxMessageFormat(ZmMsg.recurYearlyEveryMonthNumDay); 1130 var dayFormatter = formatter.getFormatsByArgumentIndex()[1]; 1131 var day = new Date(); 1132 day.setDate(day.getDate() - day.getDay()); 1133 1134 this._yearlyWeekdaySelect.addOption(ZmMsg.recurrenceRuleDay, false, ZmRecurrence.RECURRENCE_DAY); 1135 this._yearlyWeekdaySelect.addOption(ZmMsg.recurrenceRuleWeekend, false, ZmRecurrence.RECURRENCE_WEEKEND); 1136 this._yearlyWeekdaySelect.addOption(ZmMsg.recurrenceRuleWeekday, false, ZmRecurrence.RECURRENCE_WEEKDAY); 1137 1138 for (var i = 0; i < 7; i++) { 1139 this._yearlyWeekdaySelect.addOption(dayFormatter.format(day), false, i); 1140 day.setDate(day.getDate() + 1); 1141 } 1142 this._yearlyWeekdaySelect.reparentHtmlElement(this._yearlyWeekdaySelectId); 1143 delete this._yearlyWeekdaySelectId; 1144 1145 this._yearlyMonthSelectEx = new DwtSelect({parent:this}); 1146 this._yearlyMonthSelectEx.addChangeListener(selectChangeListener); 1147 for (var i = 0; i < AjxDateUtil.MONTH_LONG.length; i++) 1148 this._yearlyMonthSelectEx.addOption(AjxDateUtil.MONTH_LONG[i], false, i); 1149 this._yearlyMonthSelectEx.reparentHtmlElement(this._yearlyMonthSelectExId); 1150 delete this._yearlyMonthSelectExId; 1151 }; 1152 1153 ZmApptRecurDialog.prototype._createInputs = 1154 function(uid) { 1155 // create inputs for end fields 1156 this._endIntervalField = new DwtInputField({parent: this, type: DwtInputField.INTEGER, 1157 initialValue: "1", size: 3, maxLen: 3, 1158 errorIconStyle: DwtInputField.ERROR_ICON_NONE, 1159 validationStyle: DwtInputField.ONEXIT_VALIDATION, 1160 validator: this._positiveIntValidator, 1161 validatorCtxtObj: this, inputId:"RECUR_END_INTERVAL_FIELD_" + uid}); 1162 this._endIntervalField.setDisplay(Dwt.DISPLAY_INLINE); 1163 this._endIntervalField.reparentHtmlElement(this._endIntervalFieldId); 1164 delete this._endIntervalFieldId; 1165 1166 this._endByField = new DwtInputField({parent: this, type: DwtInputField.DATE, 1167 size: 10, maxLen: 10, 1168 errorIconStyle: DwtInputField.ERROR_ICON_NONE, 1169 validationStyle: DwtInputField.ONEXIT_VALIDATION, 1170 validator: this._endByDateValidator, 1171 validatorCtxtObj: this, inputId:"RECUR_END_BY_FIELD_" + uid}); 1172 this._endByField.setDisplay(Dwt.DISPLAY_INLINE); 1173 this._endByField.reparentHtmlElement(this._endByFieldId); 1174 Dwt.setSize(this._endByField.getInputElement(), Dwt.DEFAULT, "22"); 1175 delete this._endByFieldId; 1176 1177 // create inputs for day fields 1178 this._dailyField = new DwtInputField({parent: this, type: DwtInputField.INTEGER, 1179 initialValue: "2", size: 3, maxLen: 2, 1180 errorIconStyle: DwtInputField.ERROR_ICON_NONE, 1181 validationStyle: DwtInputField.ONEXIT_VALIDATION, 1182 validator: this._positiveIntValidator, 1183 validatorCtxtObj: this, inputId: "RECUR_DAILY_FIELD_" + uid}); 1184 this._dailyField.setDisplay(Dwt.DISPLAY_INLINE); 1185 this._dailyField.reparentHtmlElement(this._dailyFieldId); 1186 delete this._dailyFieldId; 1187 1188 // create inputs for week fields 1189 this._weeklyField = new DwtInputField({parent: this, type: DwtInputField.INTEGER, 1190 initialValue: "1", size: 2, maxLen: 2, 1191 errorIconStyle: DwtInputField.ERROR_ICON_NONE, 1192 validationStyle: DwtInputField.ONEXIT_VALIDATION, 1193 validator: this._weeklyValidator, 1194 validatorCtxtObj: this, inputId:"RECUR_WEEKLY_FIELD_" + uid}); 1195 this._weeklyField.setDisplay(Dwt.DISPLAY_INLINE); 1196 this._weeklyField.reparentHtmlElement(this._weeklyFieldId); 1197 delete this._weeklyFieldId; 1198 1199 // create inputs for month fields 1200 this._monthlyDayField = new DwtInputField({parent: this, type: DwtInputField.INTEGER, 1201 initialValue: "1", size: 2, maxLen: 2, 1202 errorIconStyle: DwtInputField.ERROR_ICON_NONE, 1203 validationStyle: DwtInputField.ONEXIT_VALIDATION, 1204 validatorCtxtObj: this, inputId:"RECUR_MONTHLY_DAY_FIELD_" + uid}); 1205 this._monthlyDayField.setDisplay(Dwt.DISPLAY_INLINE); 1206 this._monthlyDayField.reparentHtmlElement(this._monthlyDayFieldId); 1207 this._monthlyDayField.setValidNumberRange(1, 31); 1208 delete this._monthlyDayFieldId; 1209 1210 this._monthlyMonthField = new DwtInputField({parent: this, type: DwtInputField.INTEGER, 1211 initialValue: "1", size: 2, maxLen: 2, 1212 errorIconStyle: DwtInputField.ERROR_ICON_NONE, 1213 validationStyle: DwtInputField.ONEXIT_VALIDATION, 1214 validator: this._positiveIntValidator, 1215 validatorCtxtObj: this, inputId:"RECUR_MONTHLY_MONTH_FIELD_" + uid}); 1216 this._monthlyMonthField.setDisplay(Dwt.DISPLAY_INLINE); 1217 this._monthlyMonthField.reparentHtmlElement(this._monthlyMonthFieldId); 1218 delete this._monthlyMonthFieldId; 1219 1220 this._monthlyMonthFieldEx = new DwtInputField({parent: this, type: DwtInputField.INTEGER, 1221 initialValue: "1", size: 2, maxLen: 2, 1222 errorIconStyle: DwtInputField.ERROR_ICON_NONE, 1223 validationStyle: DwtInputField.ONEXIT_VALIDATION, 1224 validator: this._positiveIntValidator, 1225 validatorCtxtObj: this, inputId:"RECUR_MONTHLY_MONTH_FIELD_EX_" + uid}); 1226 this._monthlyMonthFieldEx.setDisplay(Dwt.DISPLAY_INLINE); 1227 this._monthlyMonthFieldEx.reparentHtmlElement(this._monthlyMonthFieldExId); 1228 delete this._monthlyMonthFieldExId; 1229 1230 // create inputs for year fields 1231 this._yearlyDayField = new DwtInputField({parent: this, type: DwtInputField.INTEGER, 1232 initialValue: "1", size: 2, maxLen: 2, 1233 errorIconStyle: DwtInputField.ERROR_ICON_NONE, 1234 validationStyle: DwtInputField.ONEXIT_VALIDATION, 1235 validator: this._yearlyDayValidator, 1236 validatorCtxtObj: this, inputId:"RECUR_YEARLY_DAY_FIELD_" + uid}); 1237 this._yearlyDayField.setDisplay(Dwt.DISPLAY_INLINE); 1238 this._yearlyDayField.reparentHtmlElement(this._yearlyDayFieldId); 1239 delete this._yearlyDayFieldId; 1240 }; 1241 1242 ZmApptRecurDialog.prototype._cacheFields = 1243 function() { 1244 this._noEndDateRadio = document.getElementById(this._noEndDateRadioId); delete this._noEndDateRadioId; 1245 this._endByRadio = document.getElementById(this._endByRadioId); delete this._endByRadioId; 1246 this._endAfterRadio = document.getElementById(this._endAfterRadioId); delete this._endAfterRadioId; 1247 this._repeatSectionDiv = document.getElementById(this._repeatSectionId); delete this._repeatSectionId; 1248 this._repeatEndDiv = document.getElementById(this._repeatEndDivId); delete this._repeatEndDivId; 1249 this._repeatDailyDiv = document.getElementById(this._repeatDailyId); delete this._repeatDailyId; 1250 this._repeatWeeklyDiv = document.getElementById(this._repeatWeeklyId); delete this._repeatWeeklyId; 1251 this._repeatMonthlyDiv = document.getElementById(this._repeatMonthlyId); delete this._repeatMonthlyId; 1252 this._repeatYearlyDiv = document.getElementById(this._repeatYearlyId); delete this._repeatYearlyId; 1253 this._dailyDefaultRadio = document.getElementById(this._dailyDefaultId); delete this._dailyDefaultId; 1254 this._dailyWeekdayRadio = document.getElementById(this._dailyWeekdayId); delete this._dailyWeekdayId; 1255 this._dailyFieldRadio = document.getElementById(this._dailyFieldRadioId); delete this._dailyFieldRadioId; 1256 this._weeklyDefaultRadio = document.getElementById(this._weeklyDefaultId); delete this._weeklyDefaultId; 1257 this._weeklyFieldRadio = document.getElementById(this._weeklyFieldRadioId); delete this._weeklyFieldRadioId; 1258 this._weeklyCheckboxes = document.getElementsByName(this._weeklyCheckboxName); 1259 this._monthlyDefaultRadio = document.getElementById(this._monthlyDefaultId); delete this._monthlyDefaultId; 1260 this._monthlyFieldRadio = document.getElementById(this._monthlyFieldRadioId); delete this._monthlyFieldRadioId; 1261 this._yearlyDefaultRadio = document.getElementById(this._yearlyDefaultId); delete this._yearlyDefaultId; 1262 this._yearlyFieldRadio = document.getElementById(this._yearlyFieldRadioId); delete this._yearlyFieldRadioId; 1263 }; 1264 1265 ZmApptRecurDialog.prototype._addEventHandlers = 1266 function() { 1267 var ardId = AjxCore.assignId(this); 1268 1269 // add event listeners where necessary 1270 this._setFocusHandler(this._endIntervalField, ardId); 1271 this._setFocusHandler(this._endByField, ardId); 1272 this._setFocusHandler(this._dailyField, ardId); 1273 this._setFocusHandler(this._weeklyField, ardId); 1274 this._setFocusHandler(this._monthlyDayField, ardId); 1275 this._setFocusHandler(this._monthlyMonthField, ardId); 1276 this._setFocusHandler(this._monthlyMonthFieldEx, ardId); 1277 this._setFocusHandler(this._yearlyDayField, ardId); 1278 1279 var cboxCount = this._weeklyCheckboxes.length; 1280 for (var i = 0; i < cboxCount; i++) { 1281 var checkbox = this._weeklyCheckboxes[i]; 1282 Dwt.setHandler(checkbox, DwtEvent.ONFOCUS, ZmApptRecurDialog._onCheckboxFocus); 1283 checkbox._recurDialogId = ardId; 1284 } 1285 }; 1286 1287 ZmApptRecurDialog.prototype._createTabGroup = function() { 1288 var allId = this._htmlElId; 1289 var repeatId = allId+"_repeat"; 1290 var endId = allId+"_end"; 1291 var controlsId = allId+"_controls"; 1292 1293 // section tab groups 1294 this._sectionTabGroups = {}; 1295 for (var i = 0; i < ZmApptRecurDialog.REPEAT_OPTIONS.length; i++) { 1296 var type = ZmApptRecurDialog.REPEAT_OPTIONS[i].value; 1297 this._sectionTabGroups[type] = new DwtTabGroup(repeatId+"_"+type); 1298 } 1299 1300 // section: daily 1301 var daily = this._sectionTabGroups[ZmRecurrence.DAILY]; 1302 daily.addMember(this._dailyDefaultRadio); // radio: every day 1303 daily.addMember(this._dailyWeekdayRadio); // radio: every weekday 1304 daily.addMember(this._dailyFieldRadio); // radio: every {# days} 1305 daily.addMember(this._dailyField); // input: # days 1306 // section: weekly 1307 var weekly = this._sectionTabGroups[ZmRecurrence.WEEKLY]; 1308 weekly.addMember(this._weeklyDefaultRadio); // radio: every {day} 1309 weekly.addMember(this._weeklySelectButton); // select: day 1310 weekly.addMember(this._weeklyFieldRadio); // radio: every {# weeks} on {days} 1311 var checkboxes = new Array(this._weeklyCheckboxes.length); 1312 for (var i = 0; i < checkboxes.length; i++) { 1313 checkboxes[i] = this._weeklyCheckboxes[i]; 1314 } 1315 this.__addTabMembers( 1316 weekly, ZmMsg.recurWeeklyEveryNumWeeksDate, 1317 this._weeklyField, // input: # weeks 1318 checkboxes // checkboxes: weekdays 1319 ); 1320 1321 // section: monthly 1322 var monthly = this._sectionTabGroups[ZmRecurrence.MONTHLY]; 1323 monthly.addMember(this._monthlyDefaultRadio); // radio: day {date} of every {# months} 1324 this.__addTabMembers( 1325 monthly, ZmMsg.recurMonthlyEveryNumMonthsDate, 1326 this._monthlyDayField, // input: date 1327 this._monthlyMonthField // input: # months 1328 ); 1329 monthly.addMember(this._monthlyFieldRadio); // radio: {ordinal} {weekday} of every {# months} 1330 this.__addTabMembers( 1331 monthly, ZmMsg.recurMonthlyEveryNumMonthsNumDay, 1332 this._monthlyDaySelect, // select: ordinal 1333 this._monthlyWeekdaySelect, // select: weekday 1334 this._monthlyMonthFieldEx // input: # months 1335 ); 1336 1337 // section: yearly 1338 var yearly = this._sectionTabGroups[ZmRecurrence.YEARLY]; 1339 yearly.addMember(this._yearlyDefaultRadio); // radio: every year on {month} {date} 1340 this.__addTabMembers( 1341 yearly, ZmMsg.recurYearlyEveryDate, 1342 this._yearlyMonthSelect, // select: month 1343 this._yearlyDayField // input: date 1344 ); 1345 yearly.addMember(this._yearlyFieldRadio); // radio: {ordinal} {weekday} of every {month} 1346 this.__addTabMembers( 1347 yearly, ZmMsg.recurYearlyEveryMonthNumDay, 1348 this._yearlyDaySelect, // select: ordinal 1349 this._yearlyWeekdaySelect, // select: weekday 1350 this._yearlyMonthSelectEx // select: month 1351 ); 1352 1353 // misc. tab groups 1354 this._repeatTabGroup = new DwtTabGroup(repeatId); 1355 this._endTabGroup = new DwtTabGroup(endId); 1356 this._endTabGroup.addMember(this._noEndDateRadio); // radio: none 1357 this._endTabGroup.addMember(this._endAfterRadio); // radio: after {# occurrences} 1358 this._endTabGroup.addMember(this._endIntervalField); // input: # occurrences 1359 this._endTabGroup.addMember(this._endByRadio); // radio: end by {date} 1360 this._endTabGroup.addMember(this._endByField); // input: date 1361 this._endTabGroup.addMember(); // button: date picker 1362 1363 this._controlsTabGroup = new DwtTabGroup(controlsId); 1364 1365 // primary tab group 1366 this._tabGroup = new DwtTabGroup(allId); 1367 this._tabGroup.addMember(this._repeatSelect); 1368 this._tabGroup.addMember(this._controlsTabGroup); 1369 this._tabGroup.addMember(this.getButton(DwtDialog.OK_BUTTON)); 1370 this._tabGroup.addMember(this.getButton(DwtDialog.CANCEL_BUTTON)); 1371 }; 1372 1373 ZmApptRecurDialog.prototype.__addTabMembers = 1374 function(tabGroup, pattern, member1 /*, ..., memberN */) { 1375 var segments = new AjxMessageFormat(pattern).getSegments(); 1376 for (var s = 0; s < segments.length; s++) { 1377 var segment = segments[s]; 1378 var index = segment instanceof AjxMessageFormat.MessageSegment 1379 ? segment.getIndex() : -1; 1380 if (index != -1) { 1381 var member = arguments[2 + index]; 1382 if (member instanceof Array) { 1383 for (var i = 0; i < member.length; i++) { 1384 tabGroup.addMember(member[i]); 1385 } 1386 } 1387 else { 1388 tabGroup.addMember(member); 1389 } 1390 } 1391 } 1392 }; 1393 1394 ZmApptRecurDialog.prototype._setFocusHandler = 1395 function(dwtObj, ardId) { 1396 var inputEl = dwtObj.getInputElement(); 1397 Dwt.setHandler(inputEl, DwtEvent.ONFOCUS, ZmApptRecurDialog._onFocus); 1398 inputEl._recurDialogId = ardId; 1399 } 1400 1401 ZmApptRecurDialog.prototype._setRepeatSection = 1402 function(repeatType) { 1403 var isNone = repeatType == ZmRecurrence.NONE; 1404 1405 Dwt.setVisible(this._repeatSectionDiv, !isNone); 1406 Dwt.setVisible(this._repeatEndDiv, !isNone); 1407 1408 var newSection = null; 1409 switch (repeatType) { 1410 case ZmRecurrence.DAILY: newSection = this._repeatDailyDiv; break; 1411 case ZmRecurrence.WEEKLY: newSection = this._repeatWeeklyDiv; break; 1412 case ZmRecurrence.MONTHLY: newSection = this._repeatMonthlyDiv; break; 1413 case ZmRecurrence.YEARLY: newSection = this._repeatYearlyDiv; break; 1414 } 1415 1416 this._controlsTabGroup.removeAllMembers(); 1417 if (newSection) { 1418 if (this._currentSection) { 1419 Dwt.setVisible(this._currentSection, false); 1420 } 1421 Dwt.setVisible(newSection, true); 1422 this._currentSection = newSection; 1423 1424 this._repeatTabGroup.removeAllMembers(); 1425 this._repeatTabGroup.addMember(this._sectionTabGroups[repeatType]); 1426 1427 this._controlsTabGroup.addMember(this._repeatTabGroup); 1428 this._controlsTabGroup.addMember(this._endTabGroup); 1429 1430 this.resizeSelect(repeatType); 1431 } 1432 }; 1433 1434 ZmApptRecurDialog.prototype.resizeSelect = 1435 function(repeatType) { 1436 if(repeatType = ZmRecurrence.MONTHLY) { 1437 this._resizeSelect(this._monthlyDaySelect); 1438 this._resizeSelect(this._monthlyWeekdaySelect); 1439 } 1440 1441 if(repeatType = ZmRecurrence.YEARLY) { 1442 this._resizeSelect(this._yearlyMonthSelect); 1443 this._resizeSelect(this._yearlyDaySelect); 1444 this._resizeSelect(this._yearlyWeekdaySelect); 1445 this._resizeSelect(this._yearlyMonthSelectEx); 1446 } 1447 }; 1448 1449 ZmApptRecurDialog.prototype._resizeSelect = 1450 function(selectObj) { 1451 if(!selectObj) return; 1452 selectObj.autoResize(); 1453 }; 1454 1455 1456 ZmApptRecurDialog.prototype._cleanup = 1457 function() { 1458 // dont bother cleaning up if user is still mucking around 1459 if (this._saveState) return; 1460 1461 // TODO: 1462 // - dont cleanup for section that was picked if user clicks OK 1463 1464 // reset end section 1465 this._noEndDateRadio.checked = true; 1466 this._endIntervalField.setValue("1"); 1467 // reset daily section 1468 this._dailyDefaultRadio.checked = true; 1469 this._dailyField.setValue("2"); 1470 // reset weekly section 1471 this._weeklyDefaultRadio.checked = true; 1472 this._weeklyField.setValue("2"); 1473 for (var i = 0; i < this._weeklyCheckboxes.length; i++) 1474 this._weeklyCheckboxes[i].checked = false; 1475 // reset monthly section 1476 this._monthlyDefaultRadio.checked = true; 1477 this._monthlyMonthField.setValue("1"); 1478 this._monthlyMonthFieldEx.setValue("1"); 1479 this._monthlyDaySelect.setSelected(0); 1480 // reset yearly section 1481 this._yearlyDefaultRadio.checked = true; 1482 this._yearlyDaySelect.setSelected(0); 1483 }; 1484 1485 ZmApptRecurDialog.prototype._getRadioOptionValue = 1486 function(radioName) { 1487 var options = document.getElementsByName(radioName); 1488 if (options) { 1489 for (var i = 0; i < options.length; i++) { 1490 if (options[i].checked) 1491 return options[i].value; 1492 } 1493 } 1494 return null; 1495 }; 1496 1497 // depending on the repeat type, populates repeat section as necessary 1498 ZmApptRecurDialog.prototype._populateForEdit = 1499 function(appt) { 1500 var recur = appt._recurrence; 1501 if (recur.repeatType == ZmRecurrence.NONE) return; 1502 1503 if (recur.repeatType == ZmRecurrence.DAILY) { 1504 var dailyRadioOptions = document.getElementsByName(this._dailyRadioName); 1505 if (recur.repeatWeekday) { 1506 dailyRadioOptions[1].checked = true; 1507 } else if (recur.repeatCustomCount > 1) { 1508 this._dailyField.setValue(recur.repeatCustomCount); 1509 dailyRadioOptions[2].checked = true; 1510 } 1511 } else if (recur.repeatType == ZmRecurrence.WEEKLY) { 1512 var weeklyRadioOptions = document.getElementsByName(this._weeklyRadioName); 1513 if (recur.repeatCustomCount == 1 && recur.repeatWeeklyDays.length == 1) { 1514 weeklyRadioOptions[0].checked = true; 1515 //Do not check the custom checkboxes if every weekday option is selected 1516 this._weeklyCheckboxes[this._startDate.getDay()].checked = false; 1517 for (var j = 0; j < ZmCalItem.SERVER_WEEK_DAYS.length; j++) { 1518 if (recur.repeatWeeklyDays[0] == ZmCalItem.SERVER_WEEK_DAYS[j]) { 1519 this._weeklySelectButton._selected = j; 1520 this._weeklySelectButton.setDisplayState(DwtControl.SELECTED); 1521 1522 var formatter = new AjxMessageFormat(ZmMsg.recurWeeklyEveryWeekday); 1523 var dayFormatter = formatter.getFormatsByArgumentIndex()[0]; 1524 this._weeklySelectButton.setText(dayFormatter.format(this._startDate)); 1525 1526 break; 1527 } 1528 } 1529 } else { 1530 weeklyRadioOptions[1].checked = true; 1531 this._weeklyField.setValue(recur.repeatCustomCount); 1532 // xxx: minor hack-- uncheck this since we init'd it earlier 1533 // Check if we have repeatWeeklyDays set 1534 if (recur.repeatWeeklyDays.length) { 1535 this._weeklyCheckboxes[this._startDate.getDay()].checked = false; 1536 } 1537 for (var i = 0; i < recur.repeatWeeklyDays.length; i++) { 1538 for (var j = 0; j < ZmCalItem.SERVER_WEEK_DAYS.length; j++) { 1539 if (recur.repeatWeeklyDays[i] == ZmCalItem.SERVER_WEEK_DAYS[j]) { 1540 this._weeklyCheckboxes[j].checked = true; 1541 break; 1542 } 1543 } 1544 } 1545 } 1546 } else if (recur.repeatType == ZmRecurrence.MONTHLY) { 1547 var monthlyRadioOptions = document.getElementsByName(this._monthlyRadioName); 1548 if (recur.repeatCustomType == "S") { 1549 monthlyRadioOptions[0].checked = true; 1550 this._monthlyDayField.setValue(recur.repeatMonthlyDayList[0]); 1551 this._monthlyMonthField.setValue(recur.repeatCustomCount); 1552 } else { 1553 monthlyRadioOptions[1].checked = true; 1554 this._monthlyDaySelect.setSelectedValue(recur.repeatBySetPos); 1555 1556 if(recur.repeatCustomDays) { 1557 var monthlyDay = this.getRecurrenceWeekDaySelection(recur.repeatCustomDays); 1558 this._monthlyWeekdaySelect.setSelectedValue(monthlyDay); 1559 } 1560 this._monthlyMonthFieldEx.setValue(recur.repeatCustomCount); 1561 } 1562 } else if (recur.repeatType == ZmRecurrence.YEARLY) { 1563 var yearlyRadioOptions = document.getElementsByName(this._yearlyRadioName); 1564 if (recur.repeatCustomType == "S") { 1565 yearlyRadioOptions[0].checked = true; 1566 this._yearlyDayField.setValue(recur.repeatCustomMonthDay); 1567 this._yearlyMonthSelect.setSelectedValue(Number(recur.repeatYearlyMonthsList)-1); 1568 } else { 1569 yearlyRadioOptions[1].checked = true; 1570 this._yearlyDaySelect.setSelectedValue(recur.repeatBySetPos); 1571 1572 if(recur.repeatCustomDays) { 1573 var weekDayVal = this.getRecurrenceWeekDaySelection(recur.repeatCustomDays); 1574 this._yearlyWeekdaySelect.setSelectedValue(weekDayVal); 1575 } 1576 this._yearlyMonthSelectEx.setSelectedValue(Number(recur.repeatYearlyMonthsList)-1); 1577 } 1578 } 1579 1580 // populate recurrence ending rules 1581 if (recur.repeatEndType != "N") { 1582 var endRadioOptions = document.getElementsByName(this._repeatEndName); 1583 if (recur.repeatEndType == "A") { 1584 endRadioOptions[1].checked = true; 1585 this._endIntervalField.setValue(recur.repeatEndCount); 1586 } else { 1587 endRadioOptions[2].checked = true; 1588 this._endByField.setValue(AjxDateUtil.simpleComputeDateStr(recur.repeatEndDate)); 1589 } 1590 } 1591 }; 1592 1593 /** 1594 * Gets the week day selection. 1595 * 1596 * @param {String} repeatCustomDays the repeat custom days 1597 * 1598 * @return {constant} the week day selection (see <code>ZmRecurrence.RECURRENCE_</code> constants 1599 * @see ZmRecurrence 1600 */ 1601 ZmApptRecurDialog.prototype.getRecurrenceWeekDaySelection = 1602 function(repeatCustomDays) { 1603 1604 if(repeatCustomDays instanceof Array) { 1605 repeatCustomDays = repeatCustomDays.join(","); 1606 } 1607 1608 if(repeatCustomDays == ZmCalItem.SERVER_WEEK_DAYS.join(",")) { 1609 return ZmRecurrence.RECURRENCE_DAY; 1610 } 1611 1612 var weekDays = ZmCalItem.SERVER_WEEK_DAYS.slice(1,6); 1613 if(repeatCustomDays == weekDays.join(",")) { 1614 return ZmRecurrence.RECURRENCE_WEEKDAY; 1615 } 1616 1617 var weekEndDays = [ZmCalItem.SERVER_WEEK_DAYS[0], ZmCalItem.SERVER_WEEK_DAYS[6]]; 1618 if(repeatCustomDays == weekEndDays.join(",")) { 1619 return ZmRecurrence.RECURRENCE_WEEKEND; 1620 } 1621 1622 1623 for (var i = 0; i < ZmCalItem.SERVER_WEEK_DAYS.length; i++) { 1624 if (ZmCalItem.SERVER_WEEK_DAYS[i] == repeatCustomDays) { 1625 return i; 1626 break; 1627 } 1628 } 1629 1630 }; 1631 1632 ZmApptRecurDialog.prototype.getWeekdaySelectValue = 1633 function(weekdaySelect) { 1634 1635 var day = weekdaySelect.getValue(); 1636 1637 if(ZmCalItem.SERVER_WEEK_DAYS[day]) { 1638 return [ZmCalItem.SERVER_WEEK_DAYS[day]]; 1639 } 1640 1641 if(day == ZmRecurrence.RECURRENCE_DAY) { 1642 return ZmCalItem.SERVER_WEEK_DAYS; 1643 }else if(day == ZmRecurrence.RECURRENCE_WEEKDAY) { 1644 return ZmCalItem.SERVER_WEEK_DAYS.slice(1,6); 1645 }else if(day == ZmRecurrence.RECURRENCE_WEEKEND) { 1646 return [ZmCalItem.SERVER_WEEK_DAYS[0], ZmCalItem.SERVER_WEEK_DAYS[6]]; 1647 } 1648 1649 }; 1650 1651 ZmApptRecurDialog.prototype.getFirstWeekDayOffset = 1652 function(weekDaySelect) { 1653 var weekDayVal = weekDaySelect.getValue(); 1654 var dayVal = 0; 1655 if(ZmCalItem.SERVER_WEEK_DAYS[weekDayVal]) { 1656 dayVal = weekDayVal; 1657 }else if(weekDayVal == ZmRecurrence.RECURRENCE_DAY || weekDayVal == ZmRecurrence.RECURRENCE_WEEKEND) { 1658 //if the selection is just the day or weekend than first day (Sunday) is selected 1659 dayVal = 0; 1660 }else if(weekDayVal == ZmRecurrence.RECURRENCE_WEEKDAY) { 1661 dayVal = 1; 1662 } 1663 return dayVal; 1664 }; 1665 1666 ZmApptRecurDialog.prototype.getPossibleStartDate = 1667 function(weekDayVal, lastDate, repeatBySetPos) { 1668 //weekday select might contain normal weekdays, day, weekend values also 1669 if(ZmCalItem.SERVER_WEEK_DAYS[weekDayVal]) { 1670 return AjxDateUtil.getDateForThisDay(lastDate, weekDayVal, repeatBySetPos); //Last day of next month/year 1671 }else if(weekDayVal == ZmRecurrence.RECURRENCE_DAY) { 1672 var dayOffset = ((repeatBySetPos==-1)? 0 : (repeatBySetPos-1)); 1673 lastDate.setDate(lastDate.getDate() + dayOffset); 1674 return lastDate; 1675 }else if(weekDayVal == ZmRecurrence.RECURRENCE_WEEKDAY) { 1676 return AjxDateUtil.getDateForThisWorkWeekDay(lastDate, repeatBySetPos); 1677 }else if(weekDayVal == ZmRecurrence.RECURRENCE_WEEKEND) { 1678 var lastSunday = AjxDateUtil.getDateForThisDay(lastDate, AjxDateUtil.SUNDAY, repeatBySetPos); 1679 var lastSaturday = AjxDateUtil.getDateForThisDay(lastDate, AjxDateUtil.SATURDAY, repeatBySetPos); 1680 //nearest possible weekend 1681 if(repeatBySetPos < 0) { 1682 return (lastSaturday.getTime() > lastSunday.getTime()) ? lastSaturday : lastSunday; 1683 }else { 1684 return (lastSaturday.getTime() > lastSunday.getTime()) ? lastSunday : lastSaturday; 1685 } 1686 } 1687 } 1688 // Listeners 1689 1690 ZmApptRecurDialog.prototype._repeatChangeListener = 1691 function(ev) { 1692 var newValue = ev._args.newValue; 1693 this._setRepeatSection(newValue); 1694 }; 1695 1696 ZmApptRecurDialog.prototype._selectChangeListener = 1697 function(ev) { 1698 if(ev.item && ev.item instanceof DwtMenuItem){ 1699 this._weeklyDefaultRadio.checked = true; 1700 this._weeklySelectButton.setText(ev.item.getText()); 1701 this._weeklySelectButton._selected = ev.item.getData("index"); 1702 this._weeklySelectButton.setDisplayState(DwtControl.SELECTED); 1703 return; 1704 } 1705 switch (ev._args.selectObj) { 1706 case this._weeklySelectButton: this._weeklyDefaultRadio.checked = true; break; 1707 case this._monthlyDaySelect: 1708 case this._monthlyWeekdaySelect: this._monthlyFieldRadio.checked = true; break; 1709 case this._yearlyMonthSelect: 1710 this._yearlyDefaultRadio.checked = true; 1711 this._yearlyDayField.validate(); 1712 break; 1713 case this._yearlyDaySelect: 1714 case this._yearlyWeekdaySelect: 1715 case this._yearlyMonthSelectEx: this._yearlyFieldRadio.checked = true; break; 1716 } 1717 }; 1718 1719 ZmApptRecurDialog.prototype._endByButtonListener = 1720 function(ev) { 1721 var menu = ev.item.getMenu(); 1722 var cal = menu.getItem(0); 1723 var initDate = this._endByField.isValid() 1724 ? new Date(AjxDateUtil.simpleParseDateStr(this._endByField.getValue())) 1725 : new Date(); 1726 cal.setDate(initDate, true); 1727 ev.item.popup(); 1728 }; 1729 1730 ZmApptRecurDialog.prototype._dateCalSelectionListener = 1731 function(ev) { 1732 this._endByField.setValue(AjxDateUtil.simpleComputeDateStr(ev.detail)); 1733 this._endByRadio.checked = true; 1734 }; 1735 1736 ZmApptRecurDialog.prototype._okListener = 1737 function() { 1738 this._saveState = true; 1739 this._isDirty = true; 1740 }; 1741 1742 ZmApptRecurDialog.prototype._cancelListener = 1743 function() { 1744 this._cleanup(); 1745 }; 1746 1747 1748 // Callbacks 1749 1750 ZmApptRecurDialog.prototype._positiveIntValidator = 1751 function(value) { 1752 DwtInputField.validateInteger(value); 1753 if (parseInt(value) < 1) { 1754 throw ZmMsg.errorLessThanOne; 1755 } 1756 return value; 1757 }; 1758 1759 ZmApptRecurDialog.prototype._yearlyDayValidator = 1760 function(value) { 1761 DwtInputField.validateInteger(value); 1762 var dpm = AjxDateUtil._daysPerMonth[this._yearlyMonthSelect.getValue()]; 1763 if (value < 1) 1764 throw AjxMessageFormat.format(AjxMsg.numberLessThanMin, 1); 1765 if (value > dpm) { 1766 throw AjxMessageFormat.format(AjxMsg.numberMoreThanMax, dpm); 1767 } 1768 return value; 1769 }; 1770 1771 ZmApptRecurDialog.prototype._endByDateValidator = 1772 function(value) { 1773 DwtInputField.validateDate(value); 1774 var endByDate = AjxDateUtil.simpleParseDateStr(value); 1775 if (endByDate == null || endByDate.valueOf() < this._startDate.valueOf()) { 1776 throw ZmMsg.errorEndByDate; 1777 } 1778 return value; 1779 }; 1780 1781 ZmApptRecurDialog.prototype._weeklyValidator = 1782 function(value) { 1783 value = this._positiveIntValidator(value); 1784 // make sure at least one day of the week is selected 1785 var checked = false; 1786 for (var i=0; i<this._weeklyCheckboxes.length; i++) { 1787 if (this._weeklyCheckboxes[i].checked) { 1788 checked = true; 1789 break; 1790 } 1791 } 1792 if (!checked) { 1793 throw ZmMsg.errorNoWeekdayChecked; 1794 } 1795 return value; 1796 }; 1797 1798 1799 // Static methods 1800 1801 ZmApptRecurDialog._onCheckboxFocus = function(ev) { 1802 var el = DwtUiEvent.getTarget(ev); 1803 var ard = AjxCore.objectWithId(el._recurDialogId); 1804 ard._weeklyFieldRadio.checked = true; 1805 }; 1806 1807 ZmApptRecurDialog._onFocus = 1808 function(ev) { 1809 ev || (ev = window.event); 1810 1811 var el = DwtUiEvent.getTarget(ev); 1812 var ard = AjxCore.objectWithId(el._recurDialogId); 1813 var dwtObj = DwtControl.findControl(el); 1814 switch (dwtObj) { 1815 case ard._endIntervalField: ard._endAfterRadio.checked = true; break; 1816 case ard._endByField: ard._endByRadio.checked = true; break; 1817 case ard._dailyField: ard._dailyFieldRadio.checked = true; break; 1818 case ard._weeklyField: ard._weeklyFieldRadio.checked = true; break; 1819 case ard._monthlyMonthField: 1820 case ard._monthlyDayField: ard._monthlyDefaultRadio.checked = true; break; 1821 case ard._monthlyMonthFieldEx: ard._monthlyFieldRadio.checked = true; break; 1822 case ard._yearlyDayField: ard._yearlyDefaultRadio.checked = true; break; 1823 } 1824 1825 appCtxt.getKeyboardMgr().grabFocus(dwtObj); 1826 }; 1827