/*---------------------------------------------------------------------------------- Called by page onload handler sets the hidden calendar parameters on form. ----------------------------------------------------------------------------------*/ function setup() //calendar_events-editform (shows in callback) { var offset, results; //DCO 09-02-2014 if (!RZ.editaction) //restore when eventid='new' // '' RZ.editaction = 'create'; // '' /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Don't need to be so cleaver now that calendar names & credentials can * * be read from xml file name follow these rules learned the hard way: * * 1. Don't reload homeframe; just set update data and it will display * * (avoids issues with referenced object) * * 2. Don't set homeframe variables to objects on this page (e.g. date) * * because they become unaccessible once this page closes * * * * Just do the following which following standard conventions: * * 1. Always do save with updated counter evemtid=-1 ??? * * 2. Let save return to page as normally done * * Upon return from save, * * -notify homeframe via setEventDataCurrent(false) data is updated * * 3. If returning to config page, append groupid and calendarid to url * * * * The homeframe will refresh itself onfocus if data needs updating * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ if (!RZloadResources('form',setup)) return; //wait for resources to load if (!isGlobalDataCurrent(setup)) return; //wait for reload if not current // return from save if (RZ.savereturn.indexOf('refreshData()') != -1) return refreshData('setup'); RZ.nextsavereturn = 'refreshData()'; //control after save //----- Quit if record deleted if (isRecordDeleted('Event Has Been Deleted')) return; //----- Define element convenience varibles g.errorMsg = document.getElementById('errorMsg'); g.repeatLayer = document.getElementById('repeatLayer'); g.repeatList = document.getElementById('repeatList'); g.repeatNote = document.getElementById('repeatNote'); g.repeatMonthly = document.getElementById('repeatMonthly'); g.repeatMonthlyOptions = document.getElementById('repeatMonthlyOptions'); g.repeatWeekly = document.getElementById('repeatWeekly'); g.repeatWeeklyOptions = document.getElementById('repeatWeeklyOptions'); g.signupLayer = document.getElementById('signupLayer'); g.end_date_saved_container = document.getElementById('end_date_saved_container'); g.skipDates = document.getElementById('skipDates'); g.skippedDatesNote = document.getElementById('skippedDatesNote'); g.skipDatesLabel = document.getElementById('skipDatesLabel'); //----- Indivdual note containers for specific fields RZ.calendar.noteFields = { begin_date: document.getElementById('begin_date_note'), begin_date_dayName: document.getElementById('begin_date_dayName'), end_date: document.getElementById('end_date_note'), repeatMonthlyCount: document.getElementById('repeat_note'), repeatWeeklyCount: document.getElementById('repeat_note'), repeatMonthlyOn: document.getElementById('repeat_note'), repeatWeeklyOn: document.getElementById('repeat_note'), repeat_times: document.getElementById('end_date_note'), duration: document.getElementById('duration_note'), start_time_hours: document.getElementById('start_time_note'), start_time_minutes: document.getElementById('start_time_note'), duration_units: document.getElementById('duration_note') } //----- Format calendar name for display var calid = RZgetfieldvalue(document.XMLForm.calendarid); var calname = ' ' + getCalendarName(calid) if (RZ.debug) calname += ' (id=' + calid + ')' document.getElementById("calendarName").innerHTML = calname; /// if (RZ.debug) setInnerHTML( 'eventid', '(id=' + RZ.editrecordid + ') ' ); //----- Populate data var signupstatus = g.signupstatus; var supervisoremail = g.supervisoremail; if ("yes" == signupstatus) RZshowlayer(g.signupLayer,true); else RZshowlayer(g.signupLayer,false); // Signup same as event coordinator RZformatphone(document.XMLForm.contact_phone) if ((document.XMLForm.contact_name.value || document.XMLForm.contact_name.value || document.XMLForm.contact_name.value) && document.XMLForm.event_coordinator_name.value == document.XMLForm.contact_name.value && document.XMLForm.event_coordinator_email.value == document.XMLForm.contact_email.value && document.XMLForm.event_coordinator_phone.value == document.XMLForm.contact_phone.value) assignEventContactInfo(true); else RZformatphone(document.XMLForm.event_coordinator_phone); // checking if supervisor email is required if ("yes" == supervisoremail) document.XMLForm.supervisorinfo.checked = true; else document.XMLForm.supervisorinfo.checked = false; //----- Backward compatibility for start time var startTime = g.startTime; var pos = startTime.indexOf(':') if (pos != -1) { RZsetfieldvalue( document.XMLForm.start_time_hours, startTime.substring(0,pos) ) RZsetfieldvalue( document.XMLForm.start_time_minutes, startTime.substring(pos) ) } //----- Set default date if blank var beginDate = RZgetfieldvalue(document.XMLForm.begin_date); g.begin_date_original = beginDate; if (beginDate == '') //should only be for create { var selectedDate = homeframe.RZdate(homeframe.RZ.calendar.date); if (!selectedDate) //should not happen selectedDate = homeframe.RZdate(); document.XMLForm.begin_date.value = selectedDate.get('shortDate'); } //----- Rollup / down options var rollup = document.XMLForm.rollup.value; g.rollup_master_choice = RZgetoptionvalue(rollup,'rollup_master_choice'); RZsetfieldvalue('rollup_master_choice',g.rollup_master_choice); //-----rollup options setup if (g.rollup_master == 'selectively') document.getElementById('rollup_master_container').className = ''; //----- rolldown available on current calendar if (isRollDown(calid)) { RZshowlayer('rollDownLabel',true); RZshowlayer('rollDownList',true); //----- fillin rollup list if (rollup.indexOf('all') == 0) { rollup = RZ.calendar.allcalendarids; RZsetfieldvalue(document.XMLForm.show_in_all,'yes') } else if (rollup.indexOf('IDS=') != -1) rollup = RZgetoptionvalue(rollup,"IDS"); RZclearList(document.XMLForm.rolluplist); var event_calendarid = document.XMLForm.calendarid.value; var listids = RZ.calendar.allcalendarids.split('|'); for (var id=0;id= new Date('04/24/2013').getTime()) { //----- build list of skipped dates var dates = RZgetfieldvalue('summary'); if (dates.substr(0,6) == 'DATES:') { //DCO 09-02-2014\\ if (g.isRepeatContentOverride) { if (dates && RZright(dates,1) != ';') dates += ';'; // backward compatibility for code before 09-02-2014 // convert ,; to ; at end of DATES: and ;- to ; at end of field dates = dates.replace(",;",";").replace(";-",";"); // if any active content override events, multi-day duration not allowed if (/EDITS:(.+)(?=;)/.test(dates)) RZshowlayer('durationDays',false); // get DATES: keyword values only results = dates.match(/DATES:(.*?)(?=;)/); if (results) dates = results[0]; else dates = ''; } //DCO 09-02-2014// //dates = dates.substr(7).split(','); dates = dates.substr(6).split(','); //DCO 09-02-2014 for (var i=0;i= new Date('04/24/2013').getTime()) RZshowlayer(g.skipDatesLabel,eventProps.repeatUnits != ''); /*BOOKMARK -----show repeat dates-----*/ if (dates.length > 0) { //DCO 09-02-2014 // edit button added after date var editTag = ''; if (g.isRepeatContentOverride && RZgetfieldvalue('duration_units') != 'days') editTag = ''; //DCO 09-02-2014// if (!g.skipDates.checked) { var html = dates.join('
').replace(/(
)(\d)/,'$1
$2'); html = html.replace(/
/g, editTag+'
') + editTag; //DCO 09-02-2014 setInnerHTML(g.repeatList,html); //populate repeat list popup w/o checkboxes } else { html = '
' + dates.join('
') + '
'; var chkBeg = ''; //html = html.replace(/
(\d{2}.*?)(?=
)/g,'
'+chkBeg+'$1'+chkEnd); html = html.replace(/
(\d{2}.*?)(?=
)/g,'
'+chkBeg+'$1'+editTag+chkEnd);//DCO 09-02-2014 html = html.substring(4,html.length-4); html = html.replace(/(
)($2'); html = html.replace(/  /g,''); setInnerHTML(g.repeatList,html); //populate repeat list popup //var skipDatesChecked = false; var checkBoxes = document.getElementsByName('repeatDates'); for (var i=0;i 0; if (!isNaN(eventProps.start_time_int)) break; //valid // should not get here but if it happens, clear start time eventProps.start_time_hours = ''; eventProps.start_time_minutes = ''; eventProps.start_time_exists = false; break; } //----- Setup end_date properties dateProperties = getDateProperties(args.end_date,'Ending Date'); var end_date_msg = dateProperties.msg; var end_date_obj = dateProperties.date; var end_date_int = dateProperties.time; //current end date //end_date before begin_date if (!end_date_msg && end_date_int < eventProps.begin_date_int) end_date_msg = 'Ending Date is Before Begin Date'; if (end_date_msg) //invalid end date { // Already waited couple seconds WITHIN end_date field, quit with message if (isUpdatingEndDate || args.fieldname == 'end_date') return eventPropertiesReturn('end_date',end_date_msg); // Set to begin date so code can calculate and update // For new event -or- prior to frameless release end_date not defined else { end_date_int = eventProps.begin_date_int; //end_date_int = eventProps.begin_date_int + eventProps.start_time_int; end_date_obj = homeframe.RZdate(end_date_int); } } //----- Specified end date values if valid otherwise begin date + start time values; eventProps.end_date_obj = end_date_obj; eventProps.end_date_int = end_date_int; //---------------------------------------------------------------------\\ var debug = RZdisplayCaller('','debug=eventProperties,yes'); if (RZ.debug && (debug === true || debug === false)) { //ignore next onBlur/onChange if debug mode caused RZ.debugField = args.fieldname; if (debug === true) debugger; } //---------------------------------------------------------------------// //-------------------------------------------------------------\\ // end_date has been or is being updated and no repeat properties // update duration properties based on updated end_date value; //-------------------------------------------------------------// if (args.fieldname == 'end_date' && !eventProps.repeatUnits) { var days = (end_date_obj.getTime() - eventProps.begin_date_int) / 24 / 60 / 60 / 1000 + 1; while (!end_date_msg && days > 1) //if valid end date and day > 1 { end_date_obj = end_date_obj.getDatePart(); //date component (i.e. w/o time) eventProps.repeat_times = 0; //----- multi day duration if (end_date_obj.getTime() > eventProps.begin_date_int || (end_date_obj.getTime() == eventProps.begin_date_int && eventProps.end_date_obj.getTimePart().getTime() == 0)) { eventProps.duration = days; eventProps.duration_units = 'days'; eventProps.dayCount = eventProps.duration; end_date_int = eventDates(eventProps, eventProps.begin_date_obj); } //----- end_date less than begin_date else if (end_date_obj.getTime() < eventProps.begin_date_int) { setEventPropertiesError('end_date','Ending Date is Less than Start Date'); } //----- same day, have start time and duration else if (eventProps.start_time_exists) { // time component of end date - start time = duration in milliseconds duration = end_date_int - end_date_obj.getDatePart().getTime() - eventProps.start_time_int // end_date time before start time if (duration < 0) { setEventPropertiesError('end_date','Ending Time Before Start Time'); break; } // try for minutes if currently selected or not whole number of hours eventProps.duration = duration / 1000 / 60; //duration as minutes if (eventProps.duration_units == 'min' || (eventProps.duration_units != 'min' //has no effect; kept to breadboard ideas && parseInt(eventProps.duration/60) != parseFloat(eventProps.duration/60))) { eventProps.duration_units = 'min'; // use hours if max minutes duration exceeded if (eventProps.duration <= RZ.calendar.maxDurationMinutes) break; } // store duration as hours (whole or fraction of hour) eventProps.duration_units = 'hrs' //duration as hours eventProps.duration = eventProps.duration / 60; // only keep first 2 decimals eventProps.duration = parseInt(eventProps.duration * 100 + 0.5) / 100; } //----- same day, no start time and showing end time else if (end_date.indexOf(':') != -1) setInnerHTML('end_date_note','Ending Time Cleared (No Start Time)'); break; } //----- if duration or duration_units changed by end_date, give focus and display note if (args.duration != eventProps.duration || args.duration_units != eventProps.duration_units) setInnerHTML('duration_note','Updated by End Date'); //----- if inside end_date field, don't change it if (isUpdatingEndDate) { end_date_int = 0; } } //--------------------------------------------------------------\\ // duration specified AND end_date NOT processed above // dayCount updated if multi-day event (days > 1 or after midnight) // compute end_date_int using duration & repeat properties // (but don't update end_date if there are repeat properties) //-------------------------------------------------------------// else if (eventProps.duration.length > 0) { while (true) { // Cannot continue if duration is not numberic if (isNaN(eventProps.duration) || eventProps.duration <= 0) { setEventPropertiesError('duration', "Duration Must be Number > 0"); if (args.fieldname == 'save_anyway') eventProps.duration = ''; break; } // Determine if start time, needed (for duration_units min or hrs) if (!eventProps.start_time_exists && RZcheckoptions('min,hrs',eventProps.duration_units)) { setEventPropertiesError('start_time_hours','Duration Requires Start Time'); if (args.fieldname == 'save_anyway') eventProps.duration = ''; break; } //if (isUpdatingEndDate) //if within end_date field... // break; //..don't update duration //----- Start with new end_date_int = begin_date_int (w/o time part) end_date_int = eventProps.begin_date_int; //----- Process duration based on duration_units var duration = eventProps.duration; var duration_desc = ''; var duration_max = 99999; var nextday_int = eventProps.begin_date_int + 24 * 60 * 60 * 1000; eventProps.dayCount = 1; switch (eventProps.duration_units) { case 'min': duration_desc = 'Minutes'; duration_max = RZ.calendar.maxDurationMinutes; duration = parseInt(parseFloat(duration) + 0.5); // check min duration if (duration < RZ.calendar.minDurationMinutes) { // try converting to hours (only keep first 2 decimals) duration = parseInt(eventProps.duration * 100 + 0.5) / 100; duration = parseInt(duration * 60 + .5); //round to whole minutes if (args.fieldname != 'duration_units' || duration < RZ.calendar.minDurationMinutes || duration > RZ.calendar.maxDurationMinutes || !confirm('Convert ' + eventProps.duration + ' Hours to ' + duration + ' Minutes')) { msg = 'Minimum Duration: ' + RZ.calendar.minDurationMinutes + ' Minutes'; setEventPropertiesError('duration',msg); //msg for save if (args.fieldname == 'save_anyway') duration = ''; break; } } // check max duration else if (duration > duration_max) break; // check for whole minutes else if (parseInt(duration) != duration) { duration = parseInt(duration); setInnerHTML('duration_notes','Duration Must Be Whole Minutes'); break; } eventProps.duration = duration; end_date_int += duration * 60 * 1000 + eventProps.start_time_int; break; case 'hrs': duration_desc = 'Hours'; duration_max = RZ.calendar.maxDurationHours; duration = parseInt(eventProps.duration * 100 + 0.5) / 100; //only keep first 2 decimals // check max duration if (eventProps.duration > duration_max) { // try converting minutes to hours duration = parseInt((parseFloat(duration) + .5) / 60 * 100) / 100; if (args.fieldname != 'duration_units' || duration > duration_max || !confirm('Convert ' + eventProps.duration + ' Minutes to ' + duration + ' Hours')) break; } eventProps.duration = duration; end_date_int += eventProps.duration * 60 * 60 * 1000 + eventProps.start_time_int; break; case 'days': //use integer variant - not concerned with time duration = parseInt(duration); duration_desc = 'Days'; duration_max = RZ.calendar.maxDurationDays; if (duration > duration_max) break; eventProps.duration = duration; eventProps.dayCount = eventProps.duration; // compute end date (w/o time component) based on specified duration days end_date_int += (eventProps.duration-1) * 24 * 60 * 60 * 1000; end_date_obj = homeframe.RZdate(end_date_int).getDatePart(); end_date_int = end_date_obj.getTime(); // only update dates if not repeating otherwise, repeat code will update if (!eventProps.repeatUnits) end_date_int = eventDates(eventProps, eventProps.begin_date_obj); //end_date_int = eventDates(eventProps, homeframe.RZdate(end_date_int)); break; // duration but no duration units selected; leave current end_date // (end_date will be re-calculated if there are repeat properties) default: //end_date_int = eventProps.begin_date_int; setEventPropertiesError('duration_units','Select Duration Units'); if (args.fieldname == 'save_anyway') eventProps.duration = ''; break; } if (duration > duration_max) { msg = duration_max + ' ' + duration_desc; if (eventProps.duration_units == 'min') msg += ' Max (use hours)'; else msg += ' Maximum'; return eventPropertiesReturn('duration',msg); } // if event duration goes into the next day... if (eventProps.duration_units != 'days' && end_date_int > nextday_int) { //04-10-2012 //after midnight support\\ setInnerHTML('duration_note','Event Ends After Midnight'); eventProps.dayCount = 2; //end_date_int = nextday_int; if (!eventProps.repeatUnits) //update dates but keep end_date_int eventDates(eventProps, homeframe.RZdate(end_date_int)); // \\after midnight support// /* As of 04-10-2012, use above: after midnight support // display message but correct duration is not calculated // end_date_int is restored to begin date for proper calculation of eventDates() // duration is left for user to correct. setEventPropertiesError('duration','Event Ends After Midnight'); end_date_int = eventProps.begin_date_int; eventProps.duration = args.duration; */ } // if within duration, don't update that field value if (isUpdatingDuration) { eventProps.duration = args.duration; eventProps.duration_units = args.duration_units; } // if within end_date field, don't change end date if (isUpdatingEndDate) end_date_int = 0; // if duration updates ending date if (args.fieldname == 'duration' || args.fieldname == 'duration_units' || args.fieldname == 'start_time_hours' || args.fieldname == 'start_time_minutes') { var updated = false; if (!eventProperties.dayCount || eventProperties.dayCount != eventProps.dayCount) updated = true; if (!eventProps.repeatUnits) { if (!eventProperties.end_date_int || eventProperties.end_date_int != end_date_int) updated = true; } if (updated) { msg = 'Start Time Updated Ending Date/Time'; if (args.fieldname == 'duration' || args.fieldname == 'duration_units') { msg = 'Duration Updated Ending Date'; if (!end_date_msg) //if not invalid end_date { msg += ' (from ' + args.end_date + ')'; if (homeframe.RZdate(end_date_int).getDatePart().getTime() == homeframe.RZdate(eventProps.end_date_int).getDatePart().getTime()) msg = 'Duration Updated Ending Time'; } } setInnerHTML('end_date_note',msg); } } break; } } //--------------------------------------------------------------\\ // Not updating end_date, no duration, no repeat // clear time from end date //--------------------------------------------------------------// else if (!eventProps.repeatUnits && end_date_obj.getTimePart().getTime() > 0) { end_date_int = homeframe.RZdate(end_date_int).getDatePart().getTime(); setInnerHTML('end_date_note','Ending Time Cleared (No Duration)'); } //--------------------------------------------------------------------------\\ // if repeating events, drop time component from end_date_Time & compute dates // end_date_int includes duration minutes or hours //--------------------------------------------------------------------------// /*BOOKMARK **if (eventProps.repeatUnits)*/ if (eventProps.repeatUnits) { while (true) { if (!eventProps.repeatMonthlyCount) eventProps.repeatMonthlyCount = 1; if (!eventProps.repeatWeeklyCount) eventProps.repeatWeeklyCount = 1; if (!eventProps.repeatMonthlyOn) eventProps.repeatMonthlyOn = 'sameday'; //if (!eventProps.repeatWeeklyOn) //TODO: set to current day of week end_date_OR_count = 0; // start with repeat_times if > 0 var repeat_times = args.repeat_times; if (!isNaN(repeat_times) && repeat_times > 0) end_date_OR_count = repeat_times; switch (args.fieldname) { //---------------------------------------------\\ // use repeat count for calls from these fields //---------------------------------------------// case 'repeatUnits': case 'repeatMonthlyCount': case 'repeatMonthlyOn': case 'repeatWeeklyCount': case 'repeatWeeklyOn': case 'repeat_times': if (isNaN(repeat_times) || repeat_times < 0) { msg = "Repeat Count Must be Number > 0"; if (isUpdatingRepeatTimes) return eventPropertiesReturn('repeat_times',msg); else eventProps.repeat_times = ''; } case 'begin_date': eventProps.showdates = true; //auto open dates popup case 'dates': case 'start_time_hours': case 'start_time_minutes': case 'duration': case 'duration_units': case 'duration': break; //-----------------------------------------\\ // use end_date for calls from these fields // just break and use most recent end_date //------------------------------------------// case 'end_date': eventProps.showdates = true; //auto open dates popup case 'setup': case 'save': end_date_OR_count = homeframe.RZdate(eventProps.end_date_int); break; // non-listed fields (should not get here) default: msg = 'Unknown event property: ' + args.fieldname; RZdisplayMessage('eventProperties: ' + msg); setEventPropertiesError('repeat_times', msg); if (args.fieldname == 'save_anyway') { eventProps.duration = ''; eventProps.repeatUnits = ''; } break; } //----- If invalid repeat_count, use end_date to calculate repeat_count if (typeof end_date_OR_count != 'object' && (isNaN(end_date_OR_count) || !end_date_OR_count)) end_date_OR_count = eventProps.end_date_obj; /***********************************************************/ /*BOOKMARK -----get dates for every day event is displayed*/ /*********************************************************/ end_date_int = eventDates(eventProps, end_date_OR_count); if (!eventProps.repeat_times) //blank or zero { msg = "Advance Ending Date -OR- Enter Number of Times to Repeat"; if (args.fieldname == 'save') msg = 'Event Cannot Repeat with Current Ending Date and/or Repeat Count'; setEventPropertiesError('repeat_times', msg); if (args.fieldname == 'save_anyway') eventProps.repeatUnits = ''; } break; } } //----- If end_date_int represents updated end_date, update all end_date properties if (end_date_int) { if ((eventProps.duration || eventProps.repeatUnits) && eventProps.end_date_int != end_date_int) eventProps.showdates = true; eventProps.end_date_int = end_date_int; eventProps.end_date_obj = homeframe.RZdate(eventProps.end_date_int); if (!isUpdatingEndDate) //not updating end_date { dateStr = eventProps.end_date_obj.get('shortDate'); //formatted date if (!eventProps.repeatUnits && eventProps.start_time_exists) //not repeating with start time dateStr += ' ' + eventProps.end_date_obj.get('briefTime'); //add formatted time eventProps.end_date = RZtrim(dateStr); } } //----- Check for expired event if (!eventProps.end_date_obj && eventProps.end_date_obj.getDatePart().getTime() < homeframe.RZdate().getDatePart().getTime()) eventProps.isExpired = true; //----------------------------------------------------------------------\\ return eventPropertiesReturn(); //----------------------------------------------------------------------// function eventPropertiesReturn(field,msg) { if (field) setEventPropertiesError(field,msg) eventProperties.dayCount = eventProps.dayCount; eventProperties.end_date_int = eventProps.end_date_int; return eventProps; } /*----------------------------------------------------------------------------- Internal eventProperties() function return errorMsg and optionally field to get focus -----------------------------------------------------------------------------*/ function setEventPropertiesError(field,msg) { eventProps.errorField = field; eventProps.errorMsg = msg; return eventProps; } /*----------------------------------------------------------------------------- Internal eventProperties() function compute all event dates using duration and repeat properties Called with end_date or count; end_date used by setup call, if type of repeat repeat changes or new end_date entered; if duration or begin date changes, the last computed count should be used. end_date_OR_count either end_date of last occurance or repeat_times eventProps.dayCount used to determine days for each occurance -----------------------------------------------------------------------------*/ function eventDates(eventProps, end_date_OR_count) { var i,j; var msg = ''; var date,dateStr; var beginTime = eventProps.begin_date_int; var beginDay = new Date(beginTime).getDate(); var nextTime = beginTime; var nextDate = homeframe.RZdate(beginTime); var repeatMsg = ''; var repeatMonthlyOptionMsg = ''; var nth = nextDate.getNthDayInMonth(); var dayName = nextDate.getDayName(); var dayOfWeek = nextDate.getDay(); //----- Clear dates eventProps.dates = []; eventProps.datesFormatted = []; eventProps.periods = {yearMonths:[], yearWeeks:[]}; //----- No data to calculate dates if (!end_date_OR_count.isRZdate && end_date_OR_count <= 0) { if (!isUpdatingRepeatTimes) eventProps.repeat_times = ''; return 0; //end_date not updated } //----- limit repeating events to one (1) year past begin_date var count = RZ.calendar.repeatCountMax; var endDate = RZ.calendar.repeatDateMax; //TODO not used var endDate = homeframe.RZdate(eventProps.begin_date_int); endDate.setYear(endDate.getFullYear()+1); var endTime = endDate.getTime(); var endTimeMax = endTime; var countRequest = 0; var endTimeRequest = 0; //----- Update endTime or count max based on end_date_OR_count type // if count specified, still limit to year // if end_date specified, still limit to 100 repeats (should not happen) if (typeof end_date_OR_count == 'object') { //end_date eventProps.end_date_saved = end_date_OR_count.get('shortDateTime'); endTimeRequest = end_date_OR_count.getTime(); endTime = Math.min(endTime, end_date_OR_count.getTime()); } else { //repeat_times eventProps.end_date_saved = end_date_OR_count; countRequest = end_date_OR_count; count = Math.min(count, end_date_OR_count) endTime = endTimeMax; } //----- loop to find all dates var theCount = 0; for (i=0;i<=count && nextTime <= endTime;i++) { theCount = i; // add 1st date for this occurance date = homeframe.RZdate(nextTime).getDatePart(); eventDatesAdd(date); // add additional dates for multi-day duration nextDate = homeframe.RZdate(date); for (j=1;j 0) { dateStr = eventProps.dates[eventProps.dates.length-1]; //last date added date = homeframe.RZdate(dateStr.replace(/\+$/m,'')); //convert to date repeatMsg += ', ' + repeat_times + ' times until ' + date.get('shortDate'); /*BOOKMARK -----determine except dates*/ if (g.skipDates.checked) { var skippedDates = {}; for (var i=0;i endTimeMax && endTimeRequest > endTimeMax && ((g.end_date_last != args.end_date) || (args.fieldname == 'repeat_times' && g.repeat_times_last != args.repeat_times))) { msg = debugNote + "Events Can Only Repeat a Year Past Begin Date"; // (i.e. " + endDate.get('shortDate'); setEventPropertiesError(args.fieldname, msg); g.end_date_last = args.end_date; g.repeat_times_last = args.repeat_times; return 0; } // repeat count updated end date else if (args.fieldname == 'repeat_times' && theCount == countRequest && date.getTime() != eventProps.end_date_int) { msg = 'Repeat Count Updated Ending Date'; setInnerHTML('end_date_note',msg); } // Every X Months/Weeks Updated Ending Date else if ((args.fieldname == 'repeatMonthlyCount' || args.fieldname == 'repeatMonthlyCount') && (date.getTime() != eventProps.end_date_int || theCount < countRequest)) { msg = eventProps.repeatMonthlyCount + ' Month' + RZs(eventProps.repeatMonthlyCount); if (args.fieldname == 'repeatWeeklyCount') msg = eventProps.repeatWeeklyCount + ' Week' + RZs(eventProps.repeatWeeklyCount); msg = 'Updated Ending Date for: Every ' + msg; setInnerHTML('end_date_note',msg); } // Updated Ending Date for Same Day of Month/Week else if (args.fieldname == 'repeatMonthlyOn' && (date.getTime() != eventProps.end_date_int || theCount < countRequest)) { msg = 'Updated Ending Date for: ' + repeatMonthlyOptionMsg; setInnerHTML('end_date_note',msg); } // if not within either end_date, repeat_times nor count field // -AND- ending date or repeat_times updated // setInnerHTML so focus does not change and not reported to save else if (!isUpdatingEndDate && !isUpdatingRepeatTimes && (args.fieldname == 'end_date' || args.fieldname == 'repeat_times') && (date.getTime() != eventProps.end_date_int || theCount < countRequest)) { if (theCount < countRequest) //repeat count changed msg = 'Repeat Count '; if (date.getTime() != eventProps.end_date_int) { if (msg) msg += 'and ' msg += 'Ending Date '; } msg = 'Updated ' + msg + ' to Last Valid Value'; setInnerHTML('end_date_note',msg); } // updated repeat count to match ending date else if (!isUpdatingRepeatTimes && repeat_times != eventProps.repeat_times) { msg = 'Ending Date Used to Determine Repeat Count' if (eventProps.repeat_times) ' (from ' + eventProps.repeat_times + ')'; setInnerHTML('end_date_note',debugNote + msg); } else if (args.fieldname == 'repeatUnits' && date.getTime() != eventProps.end_date_int) { msg = eventProps.repeatUnits.substr(0,1).toUpperCase() + eventProps.repeatUnits.substr(1); msg = 'Updated Ending Date for: Repeats ' + msg; setInnerHTML('end_date_note',msg); } } if (!isUpdatingRepeatTimes) eventProps.repeat_times = repeat_times; if (!isUpdatingEndDate) return date.getTime(); else return 0; return homeframe.RZdate(); //debugging /** Internal eventDates() function * Add date, formattedDate, yearMonth & yearWeek * Format dates for display; compute yearMonths & yearWeeks **/ function eventDatesAdd(date,isDuration) { var formatted = date.formatted.shortDate + ' ' + date.formatted.dayName.substr(0,3); var flag = ''; if (isDuration) { formatted = '  ' + date.formatted.shortDate + ' ' + date.formatted.dayName.substr(0,1); flag = '+'; } eventProps.datesFormatted.push(formatted); eventProps.dates.push(date.formatted.shortDate+flag); //mm-dd-yyyy //----- Get yearMonth and yearWeek for date and add to cooresponding arrays if new value var periods = getPeriods(date); if (!RZcheckoptions(eventProps.periods.yearMonths.join(','),periods.yearMonth)) eventProps.periods.yearMonths.push(periods.yearMonth); if (!RZcheckoptions(eventProps.periods.yearWeeks.join(','),periods.yearWeek)) eventProps.periods.yearWeeks.push(periods.yearWeek); } } } /*------------------------------------------------------------------------------------------------ Return month MM, week ww, year yyyy, yearMonth yyyyMM, yearWeek yyyyww -------------------------------------------------------------------------------------------------*/ function getPeriods(dateObj) { var periods = {} if (typeof dateObj != 'object') dateObj = homeframe.RZdate(dateObj) var month = dateObj.getMonth()+1; var week = dateObj.getWeek() periods.month = RZright('0'+month.toString(),2); periods.week = RZright('0'+week.toString(),2); periods.year = dateObj.getFullYear(); periods.yearMonth = periods.year + periods.month; periods.yearWeek = periods.year + periods.week; return periods; } /*----------------------------------------------------------------------------------------------- Create new RZdate object from dateStr; Returns object with the following: date object created, getTime() and msg; msg non-blank for any of the following: dateStr blank, before dateMin or after dateMax -----------------------------------------------------------------------------------------------*/ function getDateProperties(dateStr,label) { var msg = ''; var date = homeframe.RZdate(dateStr); var time = 0; if (dateStr == '') msg = label + ' Required'; else if (!date) msg = label + ' Invalid Date'; else if (date.getTime() > RZ.calendar.dateMax.getTime()) msg = 'Maximum ' + label + ': ' + homeframe.RZdate(RZ.calendar.dateMax).formatted.shortDate; else if (date.getTime() < RZ.calendar.dateMin.getTime()) msg = 'Minimum ' + label + ': ' + homeframe.RZdate(RZ.calendar.dateMin).formatted.shortDate; else time = date.getTime(); return {msg: msg, date: date, time: time}; } /*------------------------------------------------------------------------------------------- Function which checks the start time specified -------------------------------------------------------------------------------------------*/ function setTimeBegin() { if ( 0 == document.XMLForm.start_time_hours.selectedIndex ) document.XMLForm.start_time_minutes.selectedIndex = 0; else if ( 0 == document.XMLForm.start_time_minutes.selectedIndex ) document.XMLForm.start_time_minutes.selectedIndex = 1; } /*---------------------------------------------------------------------------------------------- Function that assigns the event contact info to the event coordinator info on clicking the checkbox ----------------------------------------------------------------------------------------------*/ function assignEventContactInfo(isTrueFalse) { if (typeof isTrueFalse != 'undefined') document.XMLForm.eventcontactinfo.checked = isTrueFalse; if (document.XMLForm.eventcontactinfo.checked) { document.XMLForm.event_coordinator_name.value = document.XMLForm.contact_name.value; document.XMLForm.event_coordinator_email.value = document.XMLForm.contact_email.value; document.XMLForm.event_coordinator_phone.value = document.XMLForm.contact_phone.value document.XMLForm.event_coordinator_name.disabled = true; document.XMLForm.event_coordinator_email.disabled = true; document.XMLForm.event_coordinator_phone.disabled = true; } else { document.XMLForm.event_coordinator_name.value = ""; document.XMLForm.event_coordinator_email.value = ""; document.XMLForm.event_coordinator_phone.value = ""; document.XMLForm.event_coordinator_name.disabled = false; document.XMLForm.event_coordinator_email.disabled = false; document.XMLForm.event_coordinator_phone.disabled = false; } } /*--------------------------------------------------------------------------------------------- Function which assigns the value to the event coordinator attributes from the contact attribute if checkbox "same as contact information" is checked ----------------------------------------------------------------------------------------------*/ function assignValues() { if (XMLForm.eventcontactinfo.checked) { document.XMLForm.event_coordinator_name.disabled = false; document.XMLForm.event_coordinator_name.value = document.XMLForm.contact_name.value; document.XMLForm.event_coordinator_name.disabled = true; document.XMLForm.event_coordinator_email.disabled = false; document.XMLForm.event_coordinator_email.value = document.XMLForm.contact_email.value; document.XMLForm.event_coordinator_email.disabled = true; document.XMLForm.event_coordinator_phone.disabled = false; document.XMLForm.event_coordinator_phone.value = document.XMLForm.contact_phone.value; document.XMLForm.event_coordinator_phone.disabled = true; } } /*----------------------------------------------------------------------------------------------- -----------------------------------------------------------------------------------------------*/ function showList(calendarObj, listName) { if ( !calendarObj.checked ) selectAll(listName, true); else selectAll(listName, false); } /*----------------------------------------------------------------------------------------------- -----------------------------------------------------------------------------------------------*/ function selectAll(listName, showhide) { if( !showhide ) { for ( var t = 0 ; t < listName.length ; t++ ) listName.options[t].selected = true; } else { for ( var t = 0 ; t < listName.length ; t++ ) listName.options[t].selected = false; } } /*----------------------------------------------------------------------------------------------- Form onSubmit handler. -----------------------------------------------------------------------------------------------*/ function selectChange(listName,showAllCheckbox) { var value = RZgetfieldvalue(listName); var results = value.match(/\|/g); if (results && (results.length+1) == listName.options.length) //all selected showAllCheckbox.checked = true; else showAllCheckbox.checked = false; } /*----------------------------------------------------------------------------- //DCO 09-02-2014: new function called when edit button on dates list clicked update DATES: and EDITS: properties, save primary event then redisplay this edit form to create or update event record for single repeat occurance. -----------------------------------------------------------------------------*/ function editOneRepeatDate(field) { var msg; var date = field.previousSibling.nodeValue.substr(0,10); var status = validateForm(); if (!status) return; // Add this date to skipped and EDITS maps g.skipDates.checked = true; g.skippedDates[date] = true; // Use prior content for override date if record exists var recordid = (g.repeatRecordsMap[date]) ? g.repeatRecordsMap[date] : 'new'; // add or update selected date item in EDITS: list g.repeatEditsMap[date] = recordid == 'new' ? '' : recordid; // override parameters appended to url var newargs = '&recordid=' + recordid //new or id of existing varient + '&repeatid=' + RZ.editrecordid + '&repeatdate=' + date; // drop url paramters followings set=... -- append varient properties // Example url: // http://localhost:8080/revize/plugins/calendar/editpages/calendar_events-editform.jsp // ?viewdate=11-04-2014 // &webspace=demositeIII&module=calendar_events // &pagetemplateid=115&linkedmoduleid=&linkedrecordid= // &set=calendarid%3D1&permissions_parent=calendar_app[]&page_key=calendar_app[] // &recordid=12 var nexturl = location.href.replace(/(&set=.*?)&.*/, '$1' + newargs); // validate form with updated varient properties // save primary event with updated properties (inc updated EDITS list) // then reload this editform to create or edit varient if (!status) return false; RZsave(nexturl); } /*----------------------------------------------------------------------------------------------- Form onSubmit handler. -----------------------------------------------------------------------------------------------*/ //function validateForm(caller) function validateForm(caller) //DCO 09-02-2014 { var msg = ''; var status = true; //DCO 09-02-2014 for debugger document.XMLForm.event_name.value = RZtrim(document.XMLForm.event_name.value); document.XMLForm.detail.value = RZtrim(document.XMLForm.detail.value); document.XMLForm.contact_name.value = RZtrim(document.XMLForm.contact_name.value); document.XMLForm.contact_phone.value = RZtrim(document.XMLForm.contact_phone.value); document.XMLForm.contact_email.value = RZtrim(document.XMLForm.contact_email.value); document.XMLForm.event_coordinator_name.value = RZtrim(document.XMLForm.event_coordinator_name.value); document.XMLForm.event_coordinator_phone.value = RZtrim(document.XMLForm.event_coordinator_phone.value); document.XMLForm.event_coordinator_email.value = RZtrim(document.XMLForm.event_coordinator_email.value); //----- Make sure event name is supplied if (document.XMLForm.event_name.value=='') return RZfieldError(document.XMLForm.event_name, "Event Name Required"); //----- Validates begin_date, end_date, duration and repeat properties; // Kill save if updateEventProperties() called RZfieldError() to display message. // If message is reporting auto updated fields, Save will proceed if clicked again. var eventProps = updateEventProperties('save'); if (RZtrim(eventProps.errorMsg)) { msg = eventProps.errorMsg; RZfieldError(eventProps.errorField,msg); } //----- Contact email (if entered - not required) else if ( (msg = RZvalidate_email(document.XMLForm.contact_email)) != '' ) { msg = "Contact Email:\n\n" +msg; RZfieldError(document.XMLForm.contact_email,msg); } //----- Contact phone number (if entered - not required) else if ( (msg = RZvalidatephone(document.XMLForm.contact_phone)) != '' ) { msg = "Contact Phone Number:\n\n" + msg; RZfieldError(document.XMLForm.contact_phone,msg); } // Coordinator name (required if signup form) else if (RZgetfieldvalue('signup_form') == 'yes' && !document.XMLForm.event_coordinator_name.value) { msg = "Event Coordinator Name Required for Signup Form"; RZfieldError(document.XMLForm.event_coordinator_email,msg); } // Coordinator email (required) else if (RZgetfieldvalue('signup_form') == 'yes' && !document.XMLForm.event_coordinator_email.value) { msg = "Event Coordinator Email Required for Signup Form"; RZfieldError(document.XMLForm.event_coordinator_email,msg); } else if ( (msg = RZvalidate_email(document.XMLForm.event_coordinator_email)) != '' ) { msg = "Event Coordinator Email:\n\n" + msg; RZfieldError(document.XMLForm.event_coordinator_email,msg); } // Coordinator phone (validate if specified) else if ( (msg = RZvalidatephone(document.XMLForm.event_coordinator_phone)) != '' ) { msg = "Event Coordinator Phone Number:\n\n" + msg; RZfieldError(document.XMLForm.event_coordinator_phone,msg); } //----- If same msg when save last clicked, offer to continue if admin user while (msg) { if (g.errorMsg_lastsave == msg) { if (!confirm(msg + '\n\nSave Anyway?')) { g.errorMsg_lastsave = ''; return false; } else { if (!document.XMLForm.begin_date.value) document.XMLForm.begin_date.value = RZ.calendar.today.get('shortDate'); updateEventProperties('save_anyway'); break; } } g.errorMsg_lastsave = msg; alert(msg); return false; } if (caller != 'save') return status; //DCO 09-02-2014 //----- date_time_stamp document.XMLForm.date_time_stamp.value = homeframe.RZdate().formatted.longDateTime; //----- Set event_maker to who created the event (not used) if (RZisValidCalendarEditor()) document.XMLForm.event_maker.value = "editor"; else if (document.XMLForm.event_maker.value != "editor") document.XMLForm.event_maker.value = "administrator"; //----- Remove time part from end_date var end_date = RZgetfieldvalue('end_date'); var end_date_obj = homeframe.RZdate(end_date); if (end_date_obj) RZsetfieldvalue('end_date',end_date_obj.get('shortDate')); else RZsetfieldvalue('end_date','') //----- Clear duration_units if no duration if (!RZgetfieldvalue('duration')) RZsetfieldvalue('duration_units','') //----- Update hidden repeat field var repeat = RZgetfieldvalue('repeatUnits'); if (repeat == 'weekly') repeat += '#' + RZgetfieldvalue('repeatWeeklyCount') + '#'; //future weekly options else if (repeat == 'monthly') repeat += '#' + RZgetfieldvalue('repeatMonthlyCount') + '#' + RZgetfieldvalue('repeatMonthlyOn'); if (repeat) repeat += '#' + g.repeatDesc; RZsetfieldvalue('repeat',repeat) //----- Set hidden fields based on event begin date (validated above) var periods = getPeriods(document.XMLForm.begin_date.value) document.XMLForm.month.value = periods.month; document.XMLForm.week.value = periods.week; document.XMLForm.year.value = periods.year; document.XMLForm.year_month.value = periods.yearMonth; document.XMLForm.year_week.value = periods.yearWeek; if (eventProps.periods.length == 0) //not repeated or multiday duration eventProps.periods = {yearMonths: [periods.yearMonth], yearWeeks: [periods.yearWeek]}; //----- Event calendar and date var event_calendarid = document.XMLForm.calendarid.value; var event_calendarname = getCalendarName(event_calendarid); var event_date = RZgetfieldvalue('begin_date'); //----- Update viewed calendar date but not viewed calendar // If event_date same, keep display_date otherwise use new event_date if (g.begin_date_original != event_date) g.viewdate = event_date; homeframe.setView(RZ.calendar.name, g.viewdate); homeframe.setDataStale(null,false); /***************************************************************/ /*BOOKMARK -----Store updated DATES: & EDITS: in summary field*/ /*************************************************************/ var dates = ''; if (eventProps.dates) { dates = 'DATES:' + eventProps.dates.join(','); if (g.skipDates.checked) { for (var pattern in g.skippedDates) dates = dates.replace(new RegExp('('+pattern +')'), '$1-'); // remove + dates that follow - date dates = dates.replace(/-,(\d{2}-\d{2}-\d{4}\+,)+/g,'-,') } } //DCO 09-02-2014\\ if (g.isRepeatContentOverride) { if (g.repeatId) //content override record dates = 'REPEATID:' + g.repeatId; else //NOT content override record { //----- rebuild list of active content override dates var edits = ''; for (var date in g.repeatEditsMap) //for all overides dates previously... { //...selected and edit date if clicked if (g.skippedDates[date]) { //if checked... edits += ',' + date; //...add override date to list if (g.repeatEditsMap[date]) //...add recordid if known edits += "=" + g.repeatEditsMap[date]; } } edits = edits.substr(1); if (edits) //currently have content override dates { // backward compatibility for code before 09-02-2014 edits = edits.replace(/,/g, '-,'); dates += ',; EDITS:' + edits + ';-'; } else if (g.repeatEdits) //content override dates previously created dates += ',; EDITS:-'; } } //DCO 09-02-2014// RZsetfieldvalue('summary',dates); //----- Determine mapping calendarids var mapids = RZ.calendar.default_id + ''; if (g.rollup_master == 'selectively') g.rollup_master_choice = RZgetfieldvalue('rollup_master_choice') if (g.rollup_master != 'always' && (g.rollup_master == 'never' || g.rollup_master_choice != 'true')) mapids = ''; if (RZ.calendar.default_id != event_calendarid) mapids += '|' + event_calendarid; /*BOOKMARK -----save rollup options-----*/ var allRollDown = ''; if (isRollDown(event_calendarid)) { var calendarids = RZgetfieldvalue(document.XMLForm.rolluplist); document.XMLForm.rollup.value = calendarids; if (RZgetfieldvalue(document.XMLForm.show_in_all) == 'yes') { calendarids = RZ.calendar.allcalendarids; //document.XMLForm.rollup.value = 'all'; allRollDown = 'all,' } else { if (calendarids == '|') calendarids = ''; if (!RZcheckoptions(calendarids,event_calendarid)) //add this calendar id to list calendarids = event_calendarid + '|' + calendarids; if (RZright(calendarids,1) == '|') calendarids = calendarids.substring(0,calendarids.length-1); } mapids = calendarids; } //----- Store rollup/down options var rollup = allRollDown + 'IDS=' + mapids + ',YEAR_MONTH=' + eventProps.periods.yearMonths.join('|') + ',YEAR_WEEK=' + eventProps.periods.yearWeeks.join('|'); if (g.rollup_master_choice) rollup += ',rollup_master_choice=' + g.rollup_master_choice; RZsetfieldvalue(document.XMLForm.rollup,rollup); if (!status) return false; //DCO 09-02-2014 /*BOOKMARK **** for backend mapping*/ var detailWin = RZ.calendar.openWins[RZ.calendar.winNames.eventDetail]; if (detailWin) { if (RZwinaccess(detailWin) && RZwinaccess(homeframe)) { detailWin.closeWindow(false); //disable unload handler detailWin.close(); } delete RZ.calendar.openWins[RZ.calendar.winNames.eventDetail]; } return status; //DCO 09-02-2014 } /*------------------------------------------------------------------------------- Trigger data and screen refresh onFocus (called after save) Should be called onopen but also called in setup to be safe. --------------------------------------------------------------------------------*/ function refreshData() { //------------------------------------------------------\\ if (RZdisplayCaller('','debug=refresh') === true) debugger; //------------------------------------------------------// if (refreshData.isCalled) return; refreshData.isCalled = true; homeframe.setEventDataCurrent(false); if (typeof(closeWindow) == 'undefined') window.close(); else { // more robust but closeWindow may not be loaded yet RZ.saveclicks = 0 //probably not needed but safe closeWindow(returnurl); } } /*----------------------------------------------------------------------------------- End of Page Specific Javascript -----------------------------------------------------------------------------------*/