1 /*********************************************************************************
2 * SugarCRM Community Edition is a customer relationship management program developed by
3 * SugarCRM, Inc. Copyright (C) 2004-2013 SugarCRM Inc.
5 * This program is free software; you can redistribute it and/or modify it under
6 * the terms of the GNU Affero General Public License version 3 as published by the
7 * Free Software Foundation with the addition of the following permission added
8 * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
9 * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
10 * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
12 * This program is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
17 * You should have received a copy of the GNU Affero General Public License along with
18 * this program; if not, see http://www.gnu.org/licenses or write to the Free
19 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22 * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
23 * SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com.
25 * The interactive user interfaces in modified source and object code versions
26 * of this program must display Appropriate Legal Notices, as required under
27 * Section 5 of the GNU Affero General Public License version 3.
29 * In accordance with Section 7(b) of the GNU Affero General Public License version 3,
30 * these Appropriate Legal Notices must retain the display of the "Powered by
31 * SugarCRM" logo. If the display of the logo is not reasonably feasible for
32 * technical reasons, the Appropriate Legal Notices must display the words
33 * "Powered by SugarCRM".
34 ********************************************************************************/
37 Calendar = function() {};
39 Calendar.getHighestZIndex = function (containerEl)
45 els = containerEl ? containerEl.getElementsByTagName('*') : document.getElementsByTagName('*');
47 for(var i=0; i < els.length; i++)
49 currentIndex = YAHOO.util.Dom.getStyle(els[i], "zIndex");
50 if(!isNaN(currentIndex) && currentIndex > highestIndex)
52 highestIndex = parseInt(currentIndex);
56 return (highestIndex == Number.MAX_VALUE) ? Number.MAX_VALUE : highestIndex+1;
60 * Returns a HTML Element reference by looking for the id in the given form
62 * @param id - id of the input element
63 * @param form - form (id) in which to look for the element
64 * @return HTMLInputElement
66 Calendar.getDateField = function (id, form)
70 // If we have a form, try to pull the element from it
72 var formElement = document.getElementById(form);
74 for (var i = 0; i < formElement.elements.length; i++) {
75 if (formElement.elements[i].id == id) {
76 input = formElement.elements[i];
82 input = document.getElementById(id);
88 Calendar.setup = function (params) {
90 YAHOO.util.Event.onDOMReady(function(){
92 var Event = YAHOO.util.Event;
93 var Dom = YAHOO.util.Dom;
96 var showButton = params.button ? params.button : params.buttonObj;
97 var userDateFormat = params.ifFormat ? params.ifFormat : (params.daFormat ? params.daFormat : "m/d/Y");
98 var inputField = params.inputField ? params.inputField : params.inputFieldObj.id;
99 var form = params.form ? params.form : '';
100 var startWeekday = params.startWeekday ? params.startWeekday : 0;
101 var dateFormat = userDateFormat.substr(0,10);
102 var date_field_delimiter = /([-.\\/])/.exec(dateFormat)[0];
103 dateFormat = dateFormat.replace(/[^a-zA-Z]/g,'');
105 var monthPos = dateFormat.search(/m/);
106 var dayPos = dateFormat.search(/d/);
107 var yearPos = dateFormat.search(/Y/);
109 var dateParams = new Object();
110 dateParams.delim = date_field_delimiter;
111 dateParams.monthPos = monthPos;
112 dateParams.dayPos = dayPos;
113 dateParams.yearPos = yearPos;
115 var showButtonElement = Dom.get(showButton);
116 Event.on(showButtonElement, "click", function() {
120 dialog = new YAHOO.widget.SimpleDialog("container_" + showButtonElement.id, {
122 context:[showButton, "tl", "bl", null, [-175,5]],
126 zIndex: Calendar.getHighestZIndex(document.body),
127 constraintoviewport:true
130 dialog.setHeader(SUGAR.language.get('app_strings', 'LBL_MASSUPDATE_DATE'));
131 var dialogBody = '<p class="callnav_today"><a href="javascript:void(0)" id="callnav_today">' + SUGAR.language.get('app_strings', 'LBL_EMAIL_DATE_TODAY') + '</a></p><div id="' + showButtonElement.id + '_div"></div>';
132 dialog.setBody(dialogBody);
133 dialog.render(document.body);
135 //Since the cal div name is dynamic we need to add a custom class to override some default yui css styles
136 Dom.addClass("container_" + showButtonElement.id, "cal_panel");
138 //Clear the date selection if the user clicks on today.
139 Event.addListener("callnav_today", "click", function(){
141 var now = new Date();
142 // Reset the input field value
143 var input = Calendar.getDateField(inputField, form);
145 input.value = formatSelectedDate(now);
147 var cellIndex = calendar.getCellIndex(now);
150 var cell = calendar.cells[cellIndex];
151 Dom.addClass(cell, calendar.Style.CSS_CELL_SELECTED);
154 //bug 50740 - explicitly fire onchange event for this input
158 //Fire any on-change events for this input field
159 SUGAR.util.callOnChangeListers(input);
161 //Must return false to prevent onbeforeunload from firing in IE8
165 dialog.showEvent.subscribe(function() {
166 if (YAHOO.env.ua.ie) {
167 // Since we're hiding the table using yui-overlay-hidden, we
168 // want to let the dialog know that the content size has changed, when
170 dialog.fireEvent("changeContent");
174 // Hide Calendar if we click anywhere in the document other than the calendar
175 Event.on(document, "click", function(e) {
182 var el = Event.getTarget(e);
183 var dialogEl = dialog.element;
184 if (el != dialogEl && !Dom.isAncestor(dialogEl, el) && el != showButtonElement && !Dom.isAncestor(showButtonElement, el)) {
190 // Lazy Calendar Creation - Wait to create the Calendar until the first time the button is clicked.
194 month: SUGAR.language.get('app_strings', 'LBL_CHOOSE_MONTH'),
195 year: SUGAR.language.get('app_strings', 'LBL_ENTER_YEAR'),
196 submit: SUGAR.language.get('app_strings', 'LBL_EMAIL_OK'),
197 cancel: SUGAR.language.get('app_strings', 'LBL_CANCEL_BUTTON_LABEL'),
198 invalidYear: SUGAR.language.get('app_strings', 'LBL_ENTER_VALID_YEAR')
200 monthFormat: YAHOO.widget.Calendar.SHORT,
204 calendar = new YAHOO.widget.Calendar(showButtonElement.id + '_div', {
206 hide_blank_weeks:true,
210 calendar.cfg.setProperty('DATE_FIELD_DELIMITER', date_field_delimiter);
211 calendar.cfg.setProperty('MDY_DAY_POSITION', dayPos+1);
212 calendar.cfg.setProperty('MDY_MONTH_POSITION', monthPos+1);
213 calendar.cfg.setProperty('MDY_YEAR_POSITION', yearPos+1);
214 calendar.cfg.setProperty('START_WEEKDAY', startWeekday);
216 //Configure the month and days label with localization support where defined
217 if(typeof SUGAR.language.languages['app_list_strings'] != 'undefined' && SUGAR.language.languages['app_list_strings']['dom_cal_month_long'] != 'undefined')
219 if(SUGAR.language.languages['app_list_strings']['dom_cal_month_long'].length == 13)
221 SUGAR.language.languages['app_list_strings']['dom_cal_month_long'].shift();
223 calendar.cfg.setProperty('MONTHS_LONG', SUGAR.language.languages['app_list_strings']['dom_cal_month_long']);
226 if(typeof SUGAR.language.languages['app_list_strings'] != 'undefined' && typeof SUGAR.language.languages['app_list_strings']['dom_cal_day_short'] != 'undefined')
228 if(SUGAR.language.languages['app_list_strings']['dom_cal_day_short'].length == 8)
230 SUGAR.language.languages['app_list_strings']['dom_cal_day_short'].shift();
232 calendar.cfg.setProperty('WEEKDAYS_SHORT', SUGAR.language.languages['app_list_strings']['dom_cal_day_short']);
235 var formatSelectedDate = function(selDate)
237 var monthVal = selDate.getMonth() + 1; //Add one for month value
240 monthVal = '0' + monthVal;
243 var dateVal = selDate.getDate();
247 dateVal = '0' + dateVal;
250 var yearVal = selDate.getFullYear();
268 selDate += date_field_delimiter + monthVal;
272 selDate += date_field_delimiter + dateVal;
276 selDate += date_field_delimiter + yearVal;
281 selDate += date_field_delimiter + monthVal;
285 selDate += date_field_delimiter + dateVal;
289 selDate += date_field_delimiter + yearVal;
295 calendar.selectEvent.subscribe(function(type, args, obj) {
297 var input = Calendar.getDateField(inputField, form);
298 if (calendar.getSelectedDates().length > 0) {
300 input.value = formatSelectedDate(calendar.getSelectedDates()[0]);
302 if(params.comboObject)
304 params.comboObject.update();
306 } else if(typeof args[0][0] == 'object') {
307 //We resort to using the args parameter to set the date should calendar.getSelectedDates return an empty array
308 selDate = args[0][0];
309 input.value = formatSelectedDate(new Date(selDate[0], selDate[1], selDate[2]));
315 //does not trigger onchange event
322 //Fire any on-change events for this input field
323 SUGAR.util.callOnChangeListers(input);
326 calendar.renderEvent.subscribe(function() {
327 // Tell Dialog it's contents have changed, which allows
328 // container to redraw the underlay (for IE6/Safari2)
329 dialog.fireEvent("changeContent");
334 var sanitizeDate = function(date, dateParams){
335 var dateArray = Array();
336 var returnArray = Array('','','');
337 var delimArray = Array(".", "/", "-");
340 for (var delimCounter = 0; delimCounter < delimArray.length; delimCounter++){
341 dateArray = date.split(delimArray[delimCounter]);
342 if(dateArray.length == 3){
347 //If it's not a valid date format, use the current date.
349 //'Stack overflow at line : 80' alert displayed when user clicks on the calendar icon
350 if(dateArray.length != 3)
352 var oDate = new Date();
353 var dateArray = [0,0,0];
354 dateArray[dateParams.dayPos] = oDate.getDate();
355 dateArray[dateParams.monthPos] = oDate.getMonth() + 1;
356 dateArray[dateParams.yearPos] = oDate.getFullYear();
360 for(var i = 0; i < dateArray.length; i++){
361 if (dateArray[i] > 32){
362 returnArray[dateParams.yearPos] = dateArray[i];
365 else if(dateArray[i] <= 12){
367 if((dateParams.monthPos < dateParams.dayPos) && (returnArray[dateParams.monthPos] == '')){
368 returnArray[dateParams.monthPos] = dateArray[i];
371 else if((dateParams.monthPos > dateParams.dayPos) && (returnArray[dateParams.dayPos] != '')){
372 returnArray[dateParams.monthPos] = dateArray[i];
375 else if((dateParams.dayPos < dateParams.monthPos) && (returnArray[dateParams.dayPos] == '')){
376 returnArray[dateParams.dayPos] = dateArray[i];
379 else if((dateParams.dayPos > dateParams.monthPos) && (returnArray[dateParams.monthPos] != '')){
380 returnArray[dateParams.dayPos] = dateArray[i];
385 else if(dateArray[i] > 12 && dateArray[i] < 32){
386 if(returnArray[dateParams.dayPos] != ''){
387 returnArray[dateParams.monthPos] = returnArray[dateParams.dayPos];
391 returnArray[dateParams.dayPos] = dateArray[i];
396 //if we're not 111, that means we didn't find all date parts
397 if(dateCheck != 111){
398 return sanitizeDate("", dateParams);
400 return returnArray.join(dateParams.delim);
403 var sanitizedDate = sanitizeDate(Calendar.getDateField(inputField, form).value, dateParams);
404 var sanitizedDateArray = sanitizedDate.split(dateParams.delim);
405 calendar.cfg.setProperty("selected", sanitizedDate);
406 calendar.cfg.setProperty("pageDate", sanitizedDateArray[monthPos] + dateParams.delim + sanitizedDateArray[yearPos]);