]> CyberLeo.Net >> Repos - Github/sugarcrm.git/blob - jssource/src_files/include/javascript/calendar.js
Release 6.5.15
[Github/sugarcrm.git] / jssource / src_files / include / javascript / calendar.js
1 /*********************************************************************************
2  * SugarCRM Community Edition is a customer relationship management program developed by
3  * SugarCRM, Inc. Copyright (C) 2004-2013 SugarCRM Inc.
4  * 
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.
11  * 
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
15  * details.
16  * 
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
20  * 02110-1301 USA.
21  * 
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.
24  * 
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.
28  * 
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  ********************************************************************************/
35
36
37 Calendar = function() {};
38
39 Calendar.getHighestZIndex = function (containerEl)
40 {
41    var highestIndex = 0;
42    var currentIndex = 0;
43    var els = Array();
44    
45    els = containerEl ? containerEl.getElementsByTagName('*') : document.getElementsByTagName('*');
46    
47    for(var i=0; i < els.length; i++)
48    {
49       currentIndex = YAHOO.util.Dom.getStyle(els[i], "zIndex");
50       if(!isNaN(currentIndex) && currentIndex > highestIndex)
51       { 
52          highestIndex = parseInt(currentIndex); 
53       }
54    }
55    
56    return (highestIndex == Number.MAX_VALUE) ? Number.MAX_VALUE : highestIndex+1;
57 };
58
59 /**
60  * Returns a HTML Element reference by looking for the id in the given form
61  *
62  * @param id - id of the input element
63  * @param form - form (id) in which to look for the element
64  * @return HTMLInputElement
65  */
66 Calendar.getDateField = function (id, form)
67 {
68     var input;
69
70     // If we have a form, try to pull the element from it
71     if (form) {
72         var formElement = document.getElementById(form);
73         if (formElement) {
74             for (var i = 0; i < formElement.elements.length; i++) {
75                 if (formElement.elements[i].id == id) {
76                     input = formElement.elements[i];
77                     break;
78                 }
79             }
80         }
81     } else {
82         input = document.getElementById(id);
83     }
84
85     return input;
86 };
87
88 Calendar.setup = function (params) {
89
90     YAHOO.util.Event.onDOMReady(function(){
91
92         var Event = YAHOO.util.Event;
93         var Dom = YAHOO.util.Dom;
94         var dialog;
95         var calendar;
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,'');
104                 
105         var monthPos = dateFormat.search(/m/);
106         var dayPos = dateFormat.search(/d/);
107         var yearPos = dateFormat.search(/Y/);         
108         
109         var dateParams = new Object();
110         dateParams.delim = date_field_delimiter;  
111         dateParams.monthPos = monthPos;
112         dateParams.dayPos = dayPos;
113         dateParams.yearPos = yearPos;
114         
115         var showButtonElement = Dom.get(showButton);
116         Event.on(showButtonElement, "click", function() {
117
118             if (!dialog) {
119                                   
120                 dialog = new YAHOO.widget.SimpleDialog("container_" + showButtonElement.id, {
121                     visible:false,
122                     context:[showButton, "tl", "bl", null, [-175,5]],
123                     buttons:[],
124                     draggable:false,
125                     close:true,
126                     zIndex: Calendar.getHighestZIndex(document.body),
127                     constraintoviewport:true
128                 });
129                 
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);
134
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");
137                 
138                 //Clear the date selection if the user clicks on today.
139                 Event.addListener("callnav_today", "click", function(){ 
140                     calendar.clear();
141                     var now = new Date();
142                     // Reset the input field value
143                     var input = Calendar.getDateField(inputField, form);
144
145                     input.value = formatSelectedDate(now);
146                     //Highlight the cell
147                     var cellIndex = calendar.getCellIndex(now);
148                     if(cellIndex > -1 )
149                     {
150                         var cell = calendar.cells[cellIndex];
151                         Dom.addClass(cell, calendar.Style.CSS_CELL_SELECTED);
152                     }
153
154                     //bug 50740 - explicitly fire onchange event for this input
155                     if(input.onchange)
156                         input.onchange();
157
158                     //Fire any on-change events for this input field
159                     SUGAR.util.callOnChangeListers(input);
160
161                     //Must return false to prevent onbeforeunload from firing in IE8
162                     return false;
163                 });
164                 
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
169                         // shown
170                         dialog.fireEvent("changeContent");
171                     }
172                 });
173                 
174                 // Hide Calendar if we click anywhere in the document other than the calendar
175                 Event.on(document, "click", function(e) {
176                         
177                     if(!dialog)
178                     {
179                        return;  
180                     }                   
181                         
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)) {
185                         dialog.hide();
186                     }
187                 });                
188             }
189
190             // Lazy Calendar Creation - Wait to create the Calendar until the first time the button is clicked.
191             if (!calendar) {
192                 var navConfig = {
193                     strings : {
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')
199                     },
200                     monthFormat: YAHOO.widget.Calendar.SHORT,
201                     initialFocus: "year"
202                 };                      
203                 
204                 calendar = new YAHOO.widget.Calendar(showButtonElement.id + '_div', {
205                     iframe:false,
206                     hide_blank_weeks:true,
207                     navigator:navConfig
208                 });
209                 
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);
215                 
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')
218                 {
219                         if(SUGAR.language.languages['app_list_strings']['dom_cal_month_long'].length == 13)
220                         {
221                            SUGAR.language.languages['app_list_strings']['dom_cal_month_long'].shift();
222                         }
223                         calendar.cfg.setProperty('MONTHS_LONG', SUGAR.language.languages['app_list_strings']['dom_cal_month_long']);
224                 }
225                 
226                 if(typeof SUGAR.language.languages['app_list_strings'] != 'undefined'  && typeof SUGAR.language.languages['app_list_strings']['dom_cal_day_short'] != 'undefined')
227                 {
228                         if(SUGAR.language.languages['app_list_strings']['dom_cal_day_short'].length == 8)
229                         {
230                            SUGAR.language.languages['app_list_strings']['dom_cal_day_short'].shift();
231                         }                       
232                         calendar.cfg.setProperty('WEEKDAYS_SHORT', SUGAR.language.languages['app_list_strings']['dom_cal_day_short']);
233                 }
234
235                 var formatSelectedDate = function(selDate)
236                 {
237                     var monthVal = selDate.getMonth() + 1; //Add one for month value
238                     if(monthVal < 10)
239                     {
240                         monthVal = '0' + monthVal;
241                     }
242
243                     var dateVal = selDate.getDate();
244
245                     if(dateVal < 10)
246                     {
247                         dateVal = '0' + dateVal;
248                     }
249
250                     var yearVal = selDate.getFullYear();
251
252                     selDate = '';
253                     if(monthPos == 0)
254                     {
255                         selDate = monthVal;
256                     }
257                     else if(dayPos == 0)
258                     {
259                         selDate = dateVal;
260                     }
261                     else
262                     {
263                         selDate = yearVal;
264                     }
265
266                     if(monthPos == 1)
267                     {
268                         selDate += date_field_delimiter + monthVal;
269                     }
270                     else if(dayPos == 1)
271                     {
272                         selDate += date_field_delimiter + dateVal;
273                     }
274                     else
275                     {
276                         selDate += date_field_delimiter + yearVal;
277                     }
278
279                     if(monthPos == 2)
280                     {
281                         selDate += date_field_delimiter + monthVal;
282                     }
283                     else if(dayPos == 2)
284                     {
285                         selDate += date_field_delimiter + dateVal;
286                     }
287                     else
288                     {
289                         selDate += date_field_delimiter + yearVal;
290                     }
291
292                     return selDate;
293                 };
294
295                 calendar.selectEvent.subscribe(function(type, args, obj) {
296
297                     var input = Calendar.getDateField(inputField, form);
298                                         if (calendar.getSelectedDates().length > 0) {
299
300                         input.value = formatSelectedDate(calendar.getSelectedDates()[0]);
301                         
302                         if(params.comboObject)
303                         {
304                            params.comboObject.update();
305                         }
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]));
310                     } else {
311                         input.value = '';
312                     }
313                                         
314                                         //bug 44147 fix
315                     //does not trigger onchange event
316                     if(input.onchange)
317                         input.onchange();
318                     //end bugfix
319                     
320
321                     dialog.hide();
322                                         //Fire any on-change events for this input field
323                                         SUGAR.util.callOnChangeListers(input);
324                 });
325
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");
330                 });
331                
332             }
333             
334             var sanitizeDate = function(date, dateParams){
335                 var dateArray = Array();
336                 var returnArray = Array('','','');
337                 var delimArray = Array(".", "/", "-");
338                 var dateCheck = 0;
339                 
340                 for (var delimCounter = 0; delimCounter < delimArray.length; delimCounter++){
341                         dateArray = date.split(delimArray[delimCounter]);
342                         if(dateArray.length == 3){
343                                 break;
344                         }
345                 }
346                 
347                 //If it's not a valid date format, use the current date.
348                 //fixing bug #48823: 
349                 //'Stack overflow at line : 80' alert displayed when user clicks on the calendar icon 
350                 if(dateArray.length != 3)
351                 {
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();
357                 }
358
359                 
360                 for(var i = 0; i < dateArray.length; i++){
361                         if (dateArray[i] > 32){
362                                 returnArray[dateParams.yearPos] = dateArray[i];
363                                 dateCheck += 1;
364                         }
365                         else if(dateArray[i] <= 12){
366                                 
367                                 if((dateParams.monthPos < dateParams.dayPos) && (returnArray[dateParams.monthPos] == '')){
368                                         returnArray[dateParams.monthPos] = dateArray[i];
369                                         dateCheck += 100;
370                                 }
371                                 else if((dateParams.monthPos > dateParams.dayPos) && (returnArray[dateParams.dayPos] != '')){
372                                         returnArray[dateParams.monthPos] = dateArray[i];
373                                         dateCheck += 100;
374                                         }
375                                 else if((dateParams.dayPos < dateParams.monthPos) && (returnArray[dateParams.dayPos] == '')){
376                                         returnArray[dateParams.dayPos] = dateArray[i];
377                                         dateCheck += 10;
378                                 }
379                                         else if((dateParams.dayPos > dateParams.monthPos) && (returnArray[dateParams.monthPos] != '')){
380                                                         returnArray[dateParams.dayPos] = dateArray[i];
381                                                         dateCheck += 10;
382                                                 }
383                                          
384                         }
385                         else if(dateArray[i] > 12 && dateArray[i] < 32){
386                                 if(returnArray[dateParams.dayPos] != ''){
387                                         returnArray[dateParams.monthPos] = returnArray[dateParams.dayPos];
388                                         dateCheck -= 10;
389                                         dateCheck += 100; 
390                                 }
391                                 returnArray[dateParams.dayPos] = dateArray[i];
392                                 dateCheck += 10;                                
393                         }                       
394                 }
395                 
396                 //if we're not 111, that means we didn't find all date parts
397                 if(dateCheck != 111){
398                         return sanitizeDate("", dateParams);
399                 }
400                 return returnArray.join(dateParams.delim);
401             };
402
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]);
407                 
408             calendar.render();
409             dialog.show();
410         });
411     }); 
412 };