]> CyberLeo.Net >> Repos - Github/sugarcrm.git/blob - jssource/src_files/include/javascript/calendar.js
Release 6.3.1
[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-2011 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 Calendar.setup = function (params) {
60
61     YAHOO.util.Event.onDOMReady(function(){
62         
63         var Event = YAHOO.util.Event;
64         var Dom = YAHOO.util.Dom;
65         var dialog;
66         var calendar;
67         var showButton = params.button ? params.button : params.buttonObj;
68         var userDateFormat = params.ifFormat ? params.ifFormat : (params.daFormat ? params.daFormat : "m/d/Y");
69         var inputField = params.inputField ? params.inputField : params.inputFieldObj;
70         var dateFormat = userDateFormat.substr(0,10);
71         var date_field_delimiter = /([-.\\/])/.exec(dateFormat)[0];
72         dateFormat = dateFormat.replace(/[^a-zA-Z]/g,'');
73                 
74         var monthPos = dateFormat.search(/m/);
75         var dayPos = dateFormat.search(/d/);
76         var yearPos = dateFormat.search(/Y/);         
77         
78         var dateParams = new Object();
79         dateParams.delim = date_field_delimiter;  
80         dateParams.monthPos = monthPos;
81         dateParams.dayPos = dayPos;
82         dateParams.yearPos = yearPos;
83         
84         Event.on(Dom.get(showButton), "click", function() {
85
86             if (!dialog) {
87                                   
88                 dialog = new YAHOO.widget.SimpleDialog("container_" + showButton, {
89                     visible:false,
90                     context:[showButton, "tl", "bl"],
91                     buttons:[],
92                     draggable:false,
93                     close:true,
94                     zIndex: Calendar.getHighestZIndex(document.body)
95                 });
96                 
97                 dialog.setHeader(SUGAR.language.get('app_strings', 'LBL_MASSUPDATE_DATE'));
98                 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="' + showButton + '_div"></div>';
99                 dialog.setBody(dialogBody);
100                 dialog.render(document.body);
101
102                 //Since the cal div name is dynamic we need to add a custom class to override some default yui css styles
103                 Dom.addClass("container_" + showButton, "cal_panel");
104                 
105                 //Clear the date selection if the user clicks on today.
106                 Event.addListener("callnav_today", "click", function(){ 
107                     calendar.clear();
108                     var now = new Date();
109                     //Reset the input field value
110                     Dom.get(inputField).value = formatSelectedDate(now);
111                     //Highlight the cell
112                     var cellIndex = calendar.getCellIndex(now);
113                     if(cellIndex > -1 )
114                     {
115                         var cell = calendar.cells[cellIndex];
116                         Dom.addClass(cell, calendar.Style.CSS_CELL_SELECTED);
117                     }
118                     //Must return false to prevent onbeforeunload from firing in IE8
119                     return false;
120                 });
121                 
122                 dialog.showEvent.subscribe(function() {
123                     if (YAHOO.env.ua.ie) {
124                         // Since we're hiding the table using yui-overlay-hidden, we 
125                         // want to let the dialog know that the content size has changed, when
126                         // shown
127                         dialog.fireEvent("changeContent");
128                     }
129                 });
130                 
131                 // Hide Calendar if we click anywhere in the document other than the calendar
132                 Event.on(document, "click", function(e) {
133                         
134                     if(!dialog)
135                     {
136                        return;  
137                     }                   
138                         
139                     var el = Event.getTarget(e);                   
140                     var dialogEl = dialog.element;
141                     if (el != dialogEl && !Dom.isAncestor(dialogEl, el) && el != Dom.get(showButton) && !Dom.isAncestor(Dom.get(showButton), el)) {
142                         dialog.hide();
143                     }
144                 });                
145             }
146
147             // Lazy Calendar Creation - Wait to create the Calendar until the first time the button is clicked.
148             if (!calendar) {
149                 var navConfig = {
150                     strings : {
151                         month: SUGAR.language.get('app_strings', 'LBL_CHOOSE_MONTH'),
152                         year: SUGAR.language.get('app_strings', 'LBL_ENTER_YEAR'),
153                         submit: SUGAR.language.get('app_strings', 'LBL_EMAIL_OK'),
154                         cancel: SUGAR.language.get('app_strings', 'LBL_CANCEL_BUTTON_LABEL'),
155                         invalidYear: SUGAR.language.get('app_strings', 'LBL_ENTER_VALID_YEAR')
156                     },
157                     monthFormat: YAHOO.widget.Calendar.SHORT,
158                     initialFocus: "year"
159                 };                      
160                 
161                 calendar = new YAHOO.widget.Calendar(showButton + '_div', {
162                     iframe:false,
163                     hide_blank_weeks:true,
164                     navigator:navConfig
165                 });
166                 
167                 calendar.cfg.setProperty('DATE_FIELD_DELIMITER', date_field_delimiter);
168                 calendar.cfg.setProperty('MDY_DAY_POSITION', dayPos+1);
169                 calendar.cfg.setProperty('MDY_MONTH_POSITION', monthPos+1);
170                 calendar.cfg.setProperty('MDY_YEAR_POSITION', yearPos+1);
171                 
172                 //Configure the month and days label with localization support where defined
173                 if(typeof SUGAR.language.languages['app_list_strings'] != 'undefined' && SUGAR.language.languages['app_list_strings']['dom_cal_month_long'] != 'undefined')
174                 {
175                         if(SUGAR.language.languages['app_list_strings']['dom_cal_month_long'].length == 13)
176                         {
177                            SUGAR.language.languages['app_list_strings']['dom_cal_month_long'].shift();
178                         }
179                         calendar.cfg.setProperty('MONTHS_LONG', SUGAR.language.languages['app_list_strings']['dom_cal_month_long']);
180                 }
181                 
182                 if(typeof SUGAR.language.languages['app_list_strings'] != 'undefined'  && typeof SUGAR.language.languages['app_list_strings']['dom_cal_day_short'] != 'undefined')
183                 {
184                         if(SUGAR.language.languages['app_list_strings']['dom_cal_day_short'].length == 8)
185                         {
186                            SUGAR.language.languages['app_list_strings']['dom_cal_day_short'].shift();
187                         }                       
188                         calendar.cfg.setProperty('WEEKDAYS_SHORT', SUGAR.language.languages['app_list_strings']['dom_cal_day_short']);
189                 }
190
191                 var formatSelectedDate = function(selDate)
192                 {
193                     var monthVal = selDate.getMonth() + 1; //Add one for month value
194                     if(monthVal < 10)
195                     {
196                         monthVal = '0' + monthVal;
197                     }
198
199                     var dateVal = selDate.getDate();
200
201                     if(dateVal < 10)
202                     {
203                         dateVal = '0' + dateVal;
204                     }
205
206                     var yearVal = selDate.getFullYear();
207
208                     selDate = '';
209                     if(monthPos == 0)
210                     {
211                         selDate = monthVal;
212                     }
213                     else if(dayPos == 0)
214                     {
215                         selDate = dateVal;
216                     }
217                     else
218                     {
219                         selDate = yearVal;
220                     }
221
222                     if(monthPos == 1)
223                     {
224                         selDate += date_field_delimiter + monthVal;
225                     }
226                     else if(dayPos == 1)
227                     {
228                         selDate += date_field_delimiter + dateVal;
229                     }
230                     else
231                     {
232                         selDate += date_field_delimiter + yearVal;
233                     }
234
235                     if(monthPos == 2)
236                     {
237                         selDate += date_field_delimiter + monthVal;
238                     }
239                     else if(dayPos == 2)
240                     {
241                         selDate += date_field_delimiter + dateVal;
242                     }
243                     else
244                     {
245                         selDate += date_field_delimiter + yearVal;
246                     }
247
248                     return selDate;
249                 };
250                 
251                 calendar.selectEvent.subscribe(function() {
252                     var input = Dom.get(inputField);
253                                         if (calendar.getSelectedDates().length > 0) {
254
255                         input.value = formatSelectedDate(calendar.getSelectedDates()[0]);
256                         
257                         if(params.comboObject)
258                         {
259                            params.comboObject.update();
260                         }
261                     } else {
262                         input.value = "";
263                     }
264                                         
265                                         //bug 44147 fix
266                     //does not trigger onchange event
267                     if(input.onchange)
268                         input.onchange();
269                     //end bugfix
270                     
271
272                     dialog.hide();
273                                         //Fire any on-change events for this input field
274                                         SUGAR.util.callOnChangeListers(input);
275                 });
276
277                 calendar.renderEvent.subscribe(function() {
278                     // Tell Dialog it's contents have changed, which allows 
279                     // container to redraw the underlay (for IE6/Safari2)
280                     dialog.fireEvent("changeContent");
281                 });
282                
283             }
284             
285             var sanitizeDate = function(date, dateParams){
286                 var dateArray = Array();
287                 var returnArray = Array('','','');
288                 var delimArray = Array(".", "/", "-");
289                 var dateCheck = 0;
290                 
291                 for (var delimCounter = 0; delimCounter < delimArray.length; delimCounter++){
292                         dateArray = date.split(delimArray[delimCounter]);
293                         if(dateArray.length == 3){
294                                 break;
295                         }
296                 }
297                 
298                 //If it's not a valid date format, use the current date.
299                 
300                 //fixing bug #48823: 
301                 //'Stack overflow at line : 80' alert displayed when user clicks on the calendar icon 
302                 if(dateArray.length != 3)
303                 {
304                     var oDate = new Date();
305                     var dateArray = [0,0,0];
306                     dateArray[dateParams.dayPos] = oDate.getDate();
307                     dateArray[dateParams.monthPos] = oDate.getMonth() + 1;
308                     dateArray[dateParams.yearPos] = oDate.getFullYear();
309                 }
310                 
311                 for(var i = 0; i < dateArray.length; i++){
312                         if (dateArray[i] > 32){
313                                 returnArray[dateParams.yearPos] = dateArray[i];
314                                 dateCheck += 1;
315                         }
316                         else if(dateArray[i] <= 12){
317                                 
318                                 if((dateParams.monthPos < dateParams.dayPos) && (returnArray[dateParams.monthPos] == '')){
319                                         returnArray[dateParams.monthPos] = dateArray[i];
320                                         dateCheck += 100;
321                                 }
322                                 else if((dateParams.monthPos > dateParams.dayPos) && (returnArray[dateParams.dayPos] != '')){
323                                         returnArray[dateParams.monthPos] = dateArray[i];
324                                         dateCheck += 100;
325                                         }
326                                 else if((dateParams.dayPos < dateParams.monthPos) && (returnArray[dateParams.dayPos] == '')){
327                                         returnArray[dateParams.dayPos] = dateArray[i];
328                                         dateCheck += 10;
329                                 }
330                                         else if((dateParams.dayPos > dateParams.monthPos) && (returnArray[dateParams.monthPos] != '')){
331                                                         returnArray[dateParams.dayPos] = dateArray[i];
332                                                         dateCheck += 10;
333                                                 }
334                                          
335                         }
336                         else if(dateArray[i] > 12 && dateArray[i] < 32){
337                                 if(returnArray[dateParams.dayPos] != ''){
338                                         returnArray[dateParams.monthPos] = returnArray[dateParams.dayPos];
339                                         dateCheck -= 10;
340                                         dateCheck += 100; 
341                                 }
342                                 returnArray[dateParams.dayPos] = dateArray[i];
343                                 dateCheck += 10;                                
344                         }                       
345                 }
346                 
347                 //if we're not 111, that means we didn't find all date parts
348                 if(dateCheck != 111){
349                         return sanitizeDate("", dateParams);
350                 }
351                 return returnArray.join(dateParams.delim);
352             };
353             
354             var sanitizedDate = sanitizeDate(Dom.get(inputField).value, dateParams);
355             var sanitizedDateArray = sanitizedDate.split(dateParams.delim);
356             calendar.cfg.setProperty("selected", sanitizedDate);
357             calendar.cfg.setProperty("pageDate", sanitizedDateArray[monthPos] + dateParams.delim + sanitizedDateArray[yearPos]);
358                 
359             calendar.render();
360             dialog.show();
361         });
362     }); 
363 };