]> git.mxchange.org Git - friendica-addons.git/blob - jappixmini/jappix/js/jquery.datepicker.js
Merge pull request #520 from rabuzarus/20180206_-_membersince_frio_support
[friendica-addons.git] / jappixmini / jappix / js / jquery.datepicker.js
1 /*\r
2 \r
3 Jappix - An open social platform\r
4 These are the datepicker JS script\r
5 \r
6 -------------------------------------------------\r
7 \r
8 Licenses: MIT, GPL, AGPL\r
9 Authors: Stefan Petre, Vanaryon\r
10 Last revision: 19/12/10\r
11 \r
12 */\r
13 \r
14 (function ($) {\r
15         var DatePicker = function () {\r
16                 var     ids = {},\r
17                         views = {\r
18                                 years: 'datepickerViewYears',\r
19                                 moths: 'datepickerViewMonths',\r
20                                 days: 'datepickerViewDays'\r
21                         },\r
22                         tpl = {\r
23                                 wrapper: '<div class="datepicker"><div class="datepickerBorderT" /><div class="datepickerBorderB" /><div class="datepickerBorderL" /><div class="datepickerBorderR" /><div class="datepickerBorderTL" /><div class="datepickerBorderTR" /><div class="datepickerBorderBL" /><div class="datepickerBorderBR" /><div class="datepickerContainer"><table cellspacing="0" cellpadding="0"><tbody><tr></tr></tbody></table></div></div>',\r
24                                 head: [\r
25                                         '<td>',\r
26                                         '<table cellspacing="0" cellpadding="0">',\r
27                                                 '<thead>',\r
28                                                         '<tr>',\r
29                                                                 '<th class="datepickerGoPrev"><a href="#"><span><%=prev%></span></a></th>',\r
30                                                                 '<th colspan="6" class="datepickerMonth"><a href="#"><span></span></a></th>',\r
31                                                                 '<th class="datepickerGoNext"><a href="#"><span><%=next%></span></a></th>',\r
32                                                         '</tr>',\r
33                                                         '<tr class="datepickerDoW">',\r
34                                                                 '<th><span><%=week%></span></th>',\r
35                                                                 '<th><span><%=day1%></span></th>',\r
36                                                                 '<th><span><%=day2%></span></th>',\r
37                                                                 '<th><span><%=day3%></span></th>',\r
38                                                                 '<th><span><%=day4%></span></th>',\r
39                                                                 '<th><span><%=day5%></span></th>',\r
40                                                                 '<th><span><%=day6%></span></th>',\r
41                                                                 '<th><span><%=day7%></span></th>',\r
42                                                         '</tr>',\r
43                                                 '</thead>',\r
44                                         '</table></td>'\r
45                                 ],\r
46                                 space : '<td class="datepickerSpace"><div></div></td>',\r
47                                 days: [\r
48                                         '<tbody class="datepickerDays">',\r
49                                                 '<tr>',\r
50                                                         '<th class="datepickerWeek"><a href="#"><span><%=weeks[0].week%></span></a></th>',\r
51                                                         '<td class="<%=weeks[0].days[0].classname%>"><a href="#"><span><%=weeks[0].days[0].text%></span></a></td>',\r
52                                                         '<td class="<%=weeks[0].days[1].classname%>"><a href="#"><span><%=weeks[0].days[1].text%></span></a></td>',\r
53                                                         '<td class="<%=weeks[0].days[2].classname%>"><a href="#"><span><%=weeks[0].days[2].text%></span></a></td>',\r
54                                                         '<td class="<%=weeks[0].days[3].classname%>"><a href="#"><span><%=weeks[0].days[3].text%></span></a></td>',\r
55                                                         '<td class="<%=weeks[0].days[4].classname%>"><a href="#"><span><%=weeks[0].days[4].text%></span></a></td>',\r
56                                                         '<td class="<%=weeks[0].days[5].classname%>"><a href="#"><span><%=weeks[0].days[5].text%></span></a></td>',\r
57                                                         '<td class="<%=weeks[0].days[6].classname%>"><a href="#"><span><%=weeks[0].days[6].text%></span></a></td>',\r
58                                                 '</tr>',\r
59                                                 '<tr>',\r
60                                                         '<th class="datepickerWeek"><a href="#"><span><%=weeks[1].week%></span></a></th>',\r
61                                                         '<td class="<%=weeks[1].days[0].classname%>"><a href="#"><span><%=weeks[1].days[0].text%></span></a></td>',\r
62                                                         '<td class="<%=weeks[1].days[1].classname%>"><a href="#"><span><%=weeks[1].days[1].text%></span></a></td>',\r
63                                                         '<td class="<%=weeks[1].days[2].classname%>"><a href="#"><span><%=weeks[1].days[2].text%></span></a></td>',\r
64                                                         '<td class="<%=weeks[1].days[3].classname%>"><a href="#"><span><%=weeks[1].days[3].text%></span></a></td>',\r
65                                                         '<td class="<%=weeks[1].days[4].classname%>"><a href="#"><span><%=weeks[1].days[4].text%></span></a></td>',\r
66                                                         '<td class="<%=weeks[1].days[5].classname%>"><a href="#"><span><%=weeks[1].days[5].text%></span></a></td>',\r
67                                                         '<td class="<%=weeks[1].days[6].classname%>"><a href="#"><span><%=weeks[1].days[6].text%></span></a></td>',\r
68                                                 '</tr>',\r
69                                                 '<tr>',\r
70                                                         '<th class="datepickerWeek"><a href="#"><span><%=weeks[2].week%></span></a></th>',\r
71                                                         '<td class="<%=weeks[2].days[0].classname%>"><a href="#"><span><%=weeks[2].days[0].text%></span></a></td>',\r
72                                                         '<td class="<%=weeks[2].days[1].classname%>"><a href="#"><span><%=weeks[2].days[1].text%></span></a></td>',\r
73                                                         '<td class="<%=weeks[2].days[2].classname%>"><a href="#"><span><%=weeks[2].days[2].text%></span></a></td>',\r
74                                                         '<td class="<%=weeks[2].days[3].classname%>"><a href="#"><span><%=weeks[2].days[3].text%></span></a></td>',\r
75                                                         '<td class="<%=weeks[2].days[4].classname%>"><a href="#"><span><%=weeks[2].days[4].text%></span></a></td>',\r
76                                                         '<td class="<%=weeks[2].days[5].classname%>"><a href="#"><span><%=weeks[2].days[5].text%></span></a></td>',\r
77                                                         '<td class="<%=weeks[2].days[6].classname%>"><a href="#"><span><%=weeks[2].days[6].text%></span></a></td>',\r
78                                                 '</tr>',\r
79                                                 '<tr>',\r
80                                                         '<th class="datepickerWeek"><a href="#"><span><%=weeks[3].week%></span></a></th>',\r
81                                                         '<td class="<%=weeks[3].days[0].classname%>"><a href="#"><span><%=weeks[3].days[0].text%></span></a></td>',\r
82                                                         '<td class="<%=weeks[3].days[1].classname%>"><a href="#"><span><%=weeks[3].days[1].text%></span></a></td>',\r
83                                                         '<td class="<%=weeks[3].days[2].classname%>"><a href="#"><span><%=weeks[3].days[2].text%></span></a></td>',\r
84                                                         '<td class="<%=weeks[3].days[3].classname%>"><a href="#"><span><%=weeks[3].days[3].text%></span></a></td>',\r
85                                                         '<td class="<%=weeks[3].days[4].classname%>"><a href="#"><span><%=weeks[3].days[4].text%></span></a></td>',\r
86                                                         '<td class="<%=weeks[3].days[5].classname%>"><a href="#"><span><%=weeks[3].days[5].text%></span></a></td>',\r
87                                                         '<td class="<%=weeks[3].days[6].classname%>"><a href="#"><span><%=weeks[3].days[6].text%></span></a></td>',\r
88                                                 '</tr>',\r
89                                                 '<tr>',\r
90                                                         '<th class="datepickerWeek"><a href="#"><span><%=weeks[4].week%></span></a></th>',\r
91                                                         '<td class="<%=weeks[4].days[0].classname%>"><a href="#"><span><%=weeks[4].days[0].text%></span></a></td>',\r
92                                                         '<td class="<%=weeks[4].days[1].classname%>"><a href="#"><span><%=weeks[4].days[1].text%></span></a></td>',\r
93                                                         '<td class="<%=weeks[4].days[2].classname%>"><a href="#"><span><%=weeks[4].days[2].text%></span></a></td>',\r
94                                                         '<td class="<%=weeks[4].days[3].classname%>"><a href="#"><span><%=weeks[4].days[3].text%></span></a></td>',\r
95                                                         '<td class="<%=weeks[4].days[4].classname%>"><a href="#"><span><%=weeks[4].days[4].text%></span></a></td>',\r
96                                                         '<td class="<%=weeks[4].days[5].classname%>"><a href="#"><span><%=weeks[4].days[5].text%></span></a></td>',\r
97                                                         '<td class="<%=weeks[4].days[6].classname%>"><a href="#"><span><%=weeks[4].days[6].text%></span></a></td>',\r
98                                                 '</tr>',\r
99                                                 '<tr>',\r
100                                                         '<th class="datepickerWeek"><a href="#"><span><%=weeks[5].week%></span></a></th>',\r
101                                                         '<td class="<%=weeks[5].days[0].classname%>"><a href="#"><span><%=weeks[5].days[0].text%></span></a></td>',\r
102                                                         '<td class="<%=weeks[5].days[1].classname%>"><a href="#"><span><%=weeks[5].days[1].text%></span></a></td>',\r
103                                                         '<td class="<%=weeks[5].days[2].classname%>"><a href="#"><span><%=weeks[5].days[2].text%></span></a></td>',\r
104                                                         '<td class="<%=weeks[5].days[3].classname%>"><a href="#"><span><%=weeks[5].days[3].text%></span></a></td>',\r
105                                                         '<td class="<%=weeks[5].days[4].classname%>"><a href="#"><span><%=weeks[5].days[4].text%></span></a></td>',\r
106                                                         '<td class="<%=weeks[5].days[5].classname%>"><a href="#"><span><%=weeks[5].days[5].text%></span></a></td>',\r
107                                                         '<td class="<%=weeks[5].days[6].classname%>"><a href="#"><span><%=weeks[5].days[6].text%></span></a></td>',\r
108                                                 '</tr>',\r
109                                         '</tbody>'\r
110                                 ],\r
111                                 months: [\r
112                                         '<tbody class="<%=className%>">',\r
113                                                 '<tr>',\r
114                                                         '<td colspan="2"><a href="#"><span><%=data[0]%></span></a></td>',\r
115                                                         '<td colspan="2"><a href="#"><span><%=data[1]%></span></a></td>',\r
116                                                         '<td colspan="2"><a href="#"><span><%=data[2]%></span></a></td>',\r
117                                                         '<td colspan="2"><a href="#"><span><%=data[3]%></span></a></td>',\r
118                                                 '</tr>',\r
119                                                 '<tr>',\r
120                                                         '<td colspan="2"><a href="#"><span><%=data[4]%></span></a></td>',\r
121                                                         '<td colspan="2"><a href="#"><span><%=data[5]%></span></a></td>',\r
122                                                         '<td colspan="2"><a href="#"><span><%=data[6]%></span></a></td>',\r
123                                                         '<td colspan="2"><a href="#"><span><%=data[7]%></span></a></td>',\r
124                                                 '</tr>',\r
125                                                 '<tr>',\r
126                                                         '<td colspan="2"><a href="#"><span><%=data[8]%></span></a></td>',\r
127                                                         '<td colspan="2"><a href="#"><span><%=data[9]%></span></a></td>',\r
128                                                         '<td colspan="2"><a href="#"><span><%=data[10]%></span></a></td>',\r
129                                                         '<td colspan="2"><a href="#"><span><%=data[11]%></span></a></td>',\r
130                                                 '</tr>',\r
131                                         '</tbody>'\r
132                                 ]\r
133                         },\r
134                         defaults = {\r
135                                 flat: false,\r
136                                 starts: 1,\r
137                                 prev: '&#9664;',\r
138                                 next: '&#9654;',\r
139                                 lastSel: false,\r
140                                 mode: 'single',\r
141                                 view: 'days',\r
142                                 calendars: 1,\r
143                                 format: 'Y-m-d',\r
144                                 position: 'bottom',\r
145                                 eventName: 'click',\r
146                                 onRender: function(){return {};},\r
147                                 onChange: function(){return true;},\r
148                                 onShow: function(){return true;},\r
149                                 onBeforeShow: function(){return true;},\r
150                                 onHide: function(){return true;},\r
151                                 locale: {\r
152                                         days: [_e("Sunday"), _e("Monday"), _e("Tuesday"), _e("Wednesday"), _e("Thursday"), _e("Friday"), _e("Saturday"), _e("Sunday")],\r
153                                         daysShort: [cut(_e("Sunday"), 3), cut(_e("Monday"), 3), cut(_e("Tuesday"), 3), cut(_e("Wednesday"), 3), cut(_e("Thursday"), 3), cut(_e("Friday"), 3), cut(_e("Saturday"), 3), cut(_e("Sunday"), 3)],\r
154                                         daysMin: [cut(_e("Sunday"), 2), cut(_e("Monday"), 2), cut(_e("Tuesday"), 2), cut(_e("Wednesday"), 2), cut(_e("Thursday"), 2), cut(_e("Friday"), 2), cut(_e("Saturday"), 2), cut(_e("Sunday"), 2)],\r
155                                         months: [_e("January"), _e("February"), _e("March"), _e("April"), _e("May"), _e("June"), _e("July"), _e("August"), _e("September"), _e("October"), _e("November"), _e("December")],\r
156                                         monthsShort: [cut(_e("January"), 3), cut(_e("February"), 3), cut(_e("March"), 3), cut(_e("April"), 3), cut(_e("May"), 3), cut(_e("June"), 3), cut(_e("July"), 3), cut(_e("August"), 3), cut(_e("September"), 3), cut(_e("October"), 3), cut(_e("November"), 3), cut(_e("December"), 3)],\r
157                                         weekMin: ''\r
158                                 }\r
159                         },\r
160                         fill = function(el) {\r
161                                 var options = $(el).data('datepicker');\r
162                                 var cal = $(el);\r
163                                 var currentCal = Math.floor(options.calendars/2), date, data, dow, month, cnt = 0, week, days, indic, indic2, html, tblCal;\r
164                                 cal.find('td>table tbody').remove();\r
165                                 for (var i = 0; i < options.calendars; i++) {\r
166                                         date = new Date(options.current);\r
167                                         date.addMonths(-currentCal + i);\r
168                                         tblCal = cal.find('table').eq(i+1);\r
169                                         switch (tblCal[0].className) {\r
170                                                 case 'datepickerViewDays':\r
171                                                         dow = formatDate(date, 'B, Y');\r
172                                                         break;\r
173                                                 case 'datepickerViewMonths':\r
174                                                         dow = date.getFullYear();\r
175                                                         break;\r
176                                                 case 'datepickerViewYears':\r
177                                                         dow = (date.getFullYear()-6) + ' - ' + (date.getFullYear()+5);\r
178                                                         break;\r
179                                         } \r
180                                         tblCal.find('thead tr:first th:eq(1) span').text(dow);\r
181                                         dow = date.getFullYear()-6;\r
182                                         data = {\r
183                                                 data: [],\r
184                                                 className: 'datepickerYears'\r
185                                         }\r
186                                         for ( var j = 0; j < 12; j++) {\r
187                                                 data.data.push(dow + j);\r
188                                         }\r
189                                         html = tmpl(tpl.months.join(''), data);\r
190                                         date.setDate(1);\r
191                                         data = {weeks:[], test: 10};\r
192                                         month = date.getMonth();\r
193                                         var dow = (date.getDay() - options.starts) % 7;\r
194                                         date.addDays(-(dow + (dow < 0 ? 7 : 0)));\r
195                                         week = -1;\r
196                                         cnt = 0;\r
197                                         while (cnt < 42) {\r
198                                                 indic = parseInt(cnt/7,10);\r
199                                                 indic2 = cnt%7;\r
200                                                 if (!data.weeks[indic]) {\r
201                                                         week = date.getWeekNumber();\r
202                                                         data.weeks[indic] = {\r
203                                                                 week: week,\r
204                                                                 days: []\r
205                                                         };\r
206                                                 }\r
207                                                 data.weeks[indic].days[indic2] = {\r
208                                                         text: date.getDate(),\r
209                                                         classname: []\r
210                                                 };\r
211                                                 if (month != date.getMonth()) {\r
212                                                         data.weeks[indic].days[indic2].classname.push('datepickerNotInMonth');\r
213                                                 }\r
214                                                 if (date.getDay() == 0) {\r
215                                                         data.weeks[indic].days[indic2].classname.push('datepickerSunday');\r
216                                                 }\r
217                                                 if (date.getDay() == 6) {\r
218                                                         data.weeks[indic].days[indic2].classname.push('datepickerSaturday');\r
219                                                 }\r
220                                                 var fromUser = options.onRender(date);\r
221                                                 var val = date.valueOf();\r
222                                                 if (fromUser.selected || options.date == val || $.inArray(val, options.date) > -1 || (options.mode == 'range' && val >= options.date[0] && val <= options.date[1])) {\r
223                                                         data.weeks[indic].days[indic2].classname.push('datepickerSelected');\r
224                                                 }\r
225                                                 if (fromUser.disabled) {\r
226                                                         data.weeks[indic].days[indic2].classname.push('datepickerDisabled');\r
227                                                 }\r
228                                                 if (fromUser.className) {\r
229                                                         data.weeks[indic].days[indic2].classname.push(fromUser.className);\r
230                                                 }\r
231                                                 data.weeks[indic].days[indic2].classname = data.weeks[indic].days[indic2].classname.join(' ');\r
232                                                 cnt++;\r
233                                                 date.addDays(1);\r
234                                         }\r
235                                         html = tmpl(tpl.days.join(''), data) + html;\r
236                                         data = {\r
237                                                 data: options.locale.monthsShort,\r
238                                                 className: 'datepickerMonths'\r
239                                         };\r
240                                         html = tmpl(tpl.months.join(''), data) + html;\r
241                                         tblCal.append(html);\r
242                                 }\r
243                         },\r
244                         parseDate = function (date, format) {\r
245                                 if (date.constructor == Date) {\r
246                                         return new Date(date);\r
247                                 }\r
248                                 var parts = date.split(/\W+/);\r
249                                 var against = format.split(/\W+/), d, m, y, h, min, now = new Date();\r
250                                 for (var i = 0; i < parts.length; i++) {\r
251                                         switch (against[i]) {\r
252                                                 case 'd':\r
253                                                 case 'e':\r
254                                                         d = parseInt(parts[i],10);\r
255                                                         break;\r
256                                                 case 'm':\r
257                                                         m = parseInt(parts[i], 10)-1;\r
258                                                         break;\r
259                                                 case 'Y':\r
260                                                 case 'y':\r
261                                                         y = parseInt(parts[i], 10);\r
262                                                         y += y > 100 ? 0 : (y < 29 ? 2000 : 1900);\r
263                                                         break;\r
264                                                 case 'H':\r
265                                                 case 'I':\r
266                                                 case 'k':\r
267                                                 case 'l':\r
268                                                         h = parseInt(parts[i], 10);\r
269                                                         break;\r
270                                                 case 'P':\r
271                                                 case 'p':\r
272                                                         if (/pm/i.test(parts[i]) && h < 12) {\r
273                                                                 h += 12;\r
274                                                         } else if (/am/i.test(parts[i]) && h >= 12) {\r
275                                                                 h -= 12;\r
276                                                         }\r
277                                                         break;\r
278                                                 case 'M':\r
279                                                         min = parseInt(parts[i], 10);\r
280                                                         break;\r
281                                         }\r
282                                 }\r
283                                 return new Date(\r
284                                         y === undefined ? now.getFullYear() : y,\r
285                                         m === undefined ? now.getMonth() : m,\r
286                                         d === undefined ? now.getDate() : d,\r
287                                         h === undefined ? now.getHours() : h,\r
288                                         min === undefined ? now.getMinutes() : min,\r
289                                         0\r
290                                 );\r
291                         },\r
292                         formatDate = function(date, format) {\r
293                                 var m = date.getMonth();\r
294                                 var d = date.getDate();\r
295                                 var y = date.getFullYear();\r
296                                 var wn = date.getWeekNumber();\r
297                                 var w = date.getDay();\r
298                                 var s = {};\r
299                                 var hr = date.getHours();\r
300                                 var pm = (hr >= 12);\r
301                                 var ir = (pm) ? (hr - 12) : hr;\r
302                                 var dy = date.getDayOfYear();\r
303                                 if (ir == 0) {\r
304                                         ir = 12;\r
305                                 }\r
306                                 var min = date.getMinutes();\r
307                                 var sec = date.getSeconds();\r
308                                 var parts = format.split(''), part;\r
309                                 for ( var i = 0; i < parts.length; i++ ) {\r
310                                         part = parts[i];\r
311                                         switch (parts[i]) {\r
312                                                 case 'a':\r
313                                                         part = date.getDayName();\r
314                                                         break;\r
315                                                 case 'A':\r
316                                                         part = date.getDayName(true);\r
317                                                         break;\r
318                                                 case 'b':\r
319                                                         part = date.getMonthName();\r
320                                                         break;\r
321                                                 case 'B':\r
322                                                         part = date.getMonthName(true);\r
323                                                         break;\r
324                                                 case 'C':\r
325                                                         part = 1 + Math.floor(y / 100);\r
326                                                         break;\r
327                                                 case 'd':\r
328                                                         part = (d < 10) ? ("0" + d) : d;\r
329                                                         break;\r
330                                                 case 'e':\r
331                                                         part = d;\r
332                                                         break;\r
333                                                 case 'H':\r
334                                                         part = (hr < 10) ? ("0" + hr) : hr;\r
335                                                         break;\r
336                                                 case 'I':\r
337                                                         part = (ir < 10) ? ("0" + ir) : ir;\r
338                                                         break;\r
339                                                 case 'j':\r
340                                                         part = (dy < 100) ? ((dy < 10) ? ("00" + dy) : ("0" + dy)) : dy;\r
341                                                         break;\r
342                                                 case 'k':\r
343                                                         part = hr;\r
344                                                         break;\r
345                                                 case 'l':\r
346                                                         part = ir;\r
347                                                         break;\r
348                                                 case 'm':\r
349                                                         part = (m < 9) ? ("0" + (1+m)) : (1+m);\r
350                                                         break;\r
351                                                 case 'M':\r
352                                                         part = (min < 10) ? ("0" + min) : min;\r
353                                                         break;\r
354                                                 case 'p':\r
355                                                 case 'P':\r
356                                                         part = pm ? "PM" : "AM";\r
357                                                         break;\r
358                                                 case 's':\r
359                                                         part = Math.floor(date.getTime() / 1000);\r
360                                                         break;\r
361                                                 case 'S':\r
362                                                         part = (sec < 10) ? ("0" + sec) : sec;\r
363                                                         break;\r
364                                                 case 'u':\r
365                                                         part = w + 1;\r
366                                                         break;\r
367                                                 case 'w':\r
368                                                         part = w;\r
369                                                         break;\r
370                                                 case 'y':\r
371                                                         part = ('' + y).substr(2, 2);\r
372                                                         break;\r
373                                                 case 'Y':\r
374                                                         part = y;\r
375                                                         break;\r
376                                         }\r
377                                         parts[i] = part;\r
378                                 }\r
379                                 return parts.join('');\r
380                         },\r
381                         extendDate = function(options) {\r
382                                 if (Date.prototype.tempDate) {\r
383                                         return;\r
384                                 }\r
385                                 Date.prototype.tempDate = null;\r
386                                 Date.prototype.months = options.months;\r
387                                 Date.prototype.monthsShort = options.monthsShort;\r
388                                 Date.prototype.days = options.days;\r
389                                 Date.prototype.daysShort = options.daysShort;\r
390                                 Date.prototype.getMonthName = function(fullName) {\r
391                                         return this[fullName ? 'months' : 'monthsShort'][this.getMonth()];\r
392                                 };\r
393                                 Date.prototype.getDayName = function(fullName) {\r
394                                         return this[fullName ? 'days' : 'daysShort'][this.getDay()];\r
395                                 };\r
396                                 Date.prototype.addDays = function (n) {\r
397                                         this.setDate(this.getDate() + n);\r
398                                         this.tempDate = this.getDate();\r
399                                 };\r
400                                 Date.prototype.addMonths = function (n) {\r
401                                         if (this.tempDate == null) {\r
402                                                 this.tempDate = this.getDate();\r
403                                         }\r
404                                         this.setDate(1);\r
405                                         this.setMonth(this.getMonth() + n);\r
406                                         this.setDate(Math.min(this.tempDate, this.getMaxDays()));\r
407                                 };\r
408                                 Date.prototype.addYears = function (n) {\r
409                                         if (this.tempDate == null) {\r
410                                                 this.tempDate = this.getDate();\r
411                                         }\r
412                                         this.setDate(1);\r
413                                         this.setFullYear(this.getFullYear() + n);\r
414                                         this.setDate(Math.min(this.tempDate, this.getMaxDays()));\r
415                                 };\r
416                                 Date.prototype.getMaxDays = function() {\r
417                                         var tmpDate = new Date(Date.parse(this)),\r
418                                                 d = 28, m;\r
419                                         m = tmpDate.getMonth();\r
420                                         d = 28;\r
421                                         while (tmpDate.getMonth() == m) {\r
422                                                 d ++;\r
423                                                 tmpDate.setDate(d);\r
424                                         }\r
425                                         return d - 1;\r
426                                 };\r
427                                 Date.prototype.getFirstDay = function() {\r
428                                         var tmpDate = new Date(Date.parse(this));\r
429                                         tmpDate.setDate(1);\r
430                                         return tmpDate.getDay();\r
431                                 };\r
432                                 Date.prototype.getWeekNumber = function() {\r
433                                         var tempDate = new Date(this);\r
434                                         tempDate.setDate(tempDate.getDate() - (tempDate.getDay() + 6) % 7 + 3);\r
435                                         var dms = tempDate.valueOf();\r
436                                         tempDate.setMonth(0);\r
437                                         tempDate.setDate(4);\r
438                                         return Math.round((dms - tempDate.valueOf()) / (604800000)) + 1;\r
439                                 };\r
440                                 Date.prototype.getDayOfYear = function() {\r
441                                         var now = new Date(this.getFullYear(), this.getMonth(), this.getDate(), 0, 0, 0);\r
442                                         var then = new Date(this.getFullYear(), 0, 0, 0, 0, 0);\r
443                                         var time = now - then;\r
444                                         return Math.floor(time / 24*60*60*1000);\r
445                                 };\r
446                         },\r
447                         layout = function (el) {\r
448                                 var options = $(el).data('datepicker');\r
449                                 var cal = $('#' + options.id);\r
450                                 if (!options.extraHeight) {\r
451                                         var divs = $(el).find('div');\r
452                                         options.extraHeight = divs.get(0).offsetHeight + divs.get(1).offsetHeight;\r
453                                         options.extraWidth = divs.get(2).offsetWidth + divs.get(3).offsetWidth;\r
454                                 }\r
455                                 var tbl = cal.find('table:first').get(0);\r
456                                 var width = tbl.offsetWidth;\r
457                                 var height = tbl.offsetHeight;\r
458                                 cal.css({\r
459                                         width: width + options.extraWidth + 'px',\r
460                                         height: height + options.extraHeight + 'px'\r
461                                 }).find('div.datepickerContainer').css({\r
462                                         width: width + 'px',\r
463                                         height: height + 'px'\r
464                                 });\r
465                         },\r
466                         click = function(ev) {\r
467                                 if ($(ev.target).is('span')) {\r
468                                         ev.target = ev.target.parentNode;\r
469                                 }\r
470                                 var el = $(ev.target);\r
471                                 if (el.is('a')) {\r
472                                         ev.target.blur();\r
473                                         if (el.hasClass('datepickerDisabled')) {\r
474                                                 return false;\r
475                                         }\r
476                                         var options = $(this).data('datepicker');\r
477                                         var parentEl = el.parent();\r
478                                         var tblEl = parentEl.parent().parent().parent();\r
479                                         var tblIndex = $('table', this).index(tblEl.get(0)) - 1;\r
480                                         var tmp = new Date(options.current);\r
481                                         var changed = false;\r
482                                         var fillIt = false;\r
483                                         if (parentEl.is('th')) {\r
484                                                 if (parentEl.hasClass('datepickerWeek') && options.mode == 'range' && !parentEl.next().hasClass('datepickerDisabled')) {\r
485                                                         var val = parseInt(parentEl.next().text(), 10);\r
486                                                         tmp.addMonths(tblIndex - Math.floor(options.calendars/2));\r
487                                                         if (parentEl.next().hasClass('datepickerNotInMonth')) {\r
488                                                                 tmp.addMonths(val > 15 ? -1 : 1);\r
489                                                         }\r
490                                                         tmp.setDate(val);\r
491                                                         options.date[0] = (tmp.setHours(0,0,0,0)).valueOf();\r
492                                                         tmp.setHours(23,59,59,0);\r
493                                                         tmp.addDays(6);\r
494                                                         options.date[1] = tmp.valueOf();\r
495                                                         fillIt = true;\r
496                                                         changed = true;\r
497                                                         options.lastSel = false;\r
498                                                 } else if (parentEl.hasClass('datepickerMonth')) {\r
499                                                         tmp.addMonths(tblIndex - Math.floor(options.calendars/2));\r
500                                                         switch (tblEl.get(0).className) {\r
501                                                                 case 'datepickerViewDays':\r
502                                                                         tblEl.get(0).className = 'datepickerViewMonths';\r
503                                                                         el.find('span').text(tmp.getFullYear());\r
504                                                                         break;\r
505                                                                 case 'datepickerViewMonths':\r
506                                                                         tblEl.get(0).className = 'datepickerViewYears';\r
507                                                                         el.find('span').text((tmp.getFullYear()-6) + ' - ' + (tmp.getFullYear()+5));\r
508                                                                         break;\r
509                                                                 case 'datepickerViewYears':\r
510                                                                         tblEl.get(0).className = 'datepickerViewDays';\r
511                                                                         el.find('span').text(formatDate(tmp, 'B, Y'));\r
512                                                                         break;\r
513                                                         }\r
514                                                 } else if (parentEl.parent().parent().is('thead')) {\r
515                                                         switch (tblEl.get(0).className) {\r
516                                                                 case 'datepickerViewDays':\r
517                                                                         options.current.addMonths(parentEl.hasClass('datepickerGoPrev') ? -1 : 1);\r
518                                                                         break;\r
519                                                                 case 'datepickerViewMonths':\r
520                                                                         options.current.addYears(parentEl.hasClass('datepickerGoPrev') ? -1 : 1);\r
521                                                                         break;\r
522                                                                 case 'datepickerViewYears':\r
523                                                                         options.current.addYears(parentEl.hasClass('datepickerGoPrev') ? -12 : 12);\r
524                                                                         break;\r
525                                                         }\r
526                                                         fillIt = true;\r
527                                                 }\r
528                                         } else if (parentEl.is('td') && !parentEl.hasClass('datepickerDisabled')) {\r
529                                                 switch (tblEl.get(0).className) {\r
530                                                         case 'datepickerViewMonths':\r
531                                                                 options.current.setMonth(tblEl.find('tbody.datepickerMonths td').index(parentEl));\r
532                                                                 options.current.setFullYear(parseInt(tblEl.find('thead th.datepickerMonth span').text(), 10));\r
533                                                                 options.current.addMonths(Math.floor(options.calendars/2) - tblIndex);\r
534                                                                 tblEl.get(0).className = 'datepickerViewDays';\r
535                                                                 break;\r
536                                                         case 'datepickerViewYears':\r
537                                                                 options.current.setFullYear(parseInt(el.text(), 10));\r
538                                                                 tblEl.get(0).className = 'datepickerViewMonths';\r
539                                                                 break;\r
540                                                         default:\r
541                                                                 var val = parseInt(el.text(), 10);\r
542                                                                 tmp.addMonths(tblIndex - Math.floor(options.calendars/2));\r
543                                                                 if (parentEl.hasClass('datepickerNotInMonth')) {\r
544                                                                         tmp.addMonths(val > 15 ? -1 : 1);\r
545                                                                 }\r
546                                                                 tmp.setDate(val);\r
547                                                                 switch (options.mode) {\r
548                                                                         case 'multiple':\r
549                                                                                 val = (tmp.setHours(0,0,0,0)).valueOf();\r
550                                                                                 if ($.inArray(val, options.date) > -1) {\r
551                                                                                         $.each(options.date, function(nr, dat){\r
552                                                                                                 if (dat == val) {\r
553                                                                                                         options.date.splice(nr,1);\r
554                                                                                                         return false;\r
555                                                                                                 }\r
556                                                                                         });\r
557                                                                                 } else {\r
558                                                                                         options.date.push(val);\r
559                                                                                 }\r
560                                                                                 break;\r
561                                                                         case 'range':\r
562                                                                                 if (!options.lastSel) {\r
563                                                                                         options.date[0] = (tmp.setHours(0,0,0,0)).valueOf();\r
564                                                                                 }\r
565                                                                                 val = (tmp.setHours(23,59,59,0)).valueOf();\r
566                                                                                 if (val < options.date[0]) {\r
567                                                                                         options.date[1] = options.date[0] + 86399000;\r
568                                                                                         options.date[0] = val - 86399000;\r
569                                                                                 } else {\r
570                                                                                         options.date[1] = val;\r
571                                                                                 }\r
572                                                                                 options.lastSel = !options.lastSel;\r
573                                                                                 break;\r
574                                                                         default:\r
575                                                                                 options.date = tmp.valueOf();\r
576                                                                                 break;\r
577                                                                 }\r
578                                                                 break;\r
579                                                 }\r
580                                                 fillIt = true;\r
581                                                 changed = true;\r
582                                         }\r
583                                         if (fillIt) {\r
584                                                 fill(this);\r
585                                         }\r
586                                         if (changed) {\r
587                                                 options.onChange.apply(this, prepareDate(options));\r
588                                         }\r
589                                 }\r
590                                 return false;\r
591                         },\r
592                         prepareDate = function (options) {\r
593                                 var tmp;\r
594                                 if (options.mode == 'single') {\r
595                                         tmp = new Date(options.date);\r
596                                         return [formatDate(tmp, options.format), tmp, options.el];\r
597                                 } else {\r
598                                         tmp = [[],[], options.el];\r
599                                         $.each(options.date, function(nr, val){\r
600                                                 var date = new Date(val);\r
601                                                 tmp[0].push(formatDate(date, options.format));\r
602                                                 tmp[1].push(date);\r
603                                         });\r
604                                         return tmp;\r
605                                 }\r
606                         },\r
607                         getViewport = function () {\r
608                                 var m = document.compatMode == 'CSS1Compat';\r
609                                 return {\r
610                                         l : window.pageXOffset || (m ? document.documentElement.scrollLeft : document.body.scrollLeft),\r
611                                         t : window.pageYOffset || (m ? document.documentElement.scrollTop : document.body.scrollTop),\r
612                                         w : window.innerWidth || (m ? document.documentElement.clientWidth : document.body.clientWidth),\r
613                                         h : window.innerHeight || (m ? document.documentElement.clientHeight : document.body.clientHeight)\r
614                                 };\r
615                         },\r
616                         isChildOf = function(parentEl, el, container) {\r
617                                 if (parentEl == el) {\r
618                                         return true;\r
619                                 }\r
620                                 if (parentEl.contains) {\r
621                                         return parentEl.contains(el);\r
622                                 }\r
623                                 if ( parentEl.compareDocumentPosition ) {\r
624                                         return !!(parentEl.compareDocumentPosition(el) & 16);\r
625                                 }\r
626                                 var prEl = el.parentNode;\r
627                                 while(prEl && prEl != container) {\r
628                                         if (prEl == parentEl)\r
629                                                 return true;\r
630                                         prEl = prEl.parentNode;\r
631                                 }\r
632                                 return false;\r
633                         },\r
634                         show = function (ev) {\r
635                                 var cal = $('#' + $(this).data('datepickerId'));\r
636                                 if (!cal.is(':visible')) {\r
637                                         var calEl = cal.get(0);\r
638                                         fill(calEl);\r
639                                         var options = cal.data('datepicker');\r
640                                         options.onBeforeShow.apply(this, [cal.get(0)]);\r
641                                         var pos = $(this).offset();\r
642                                         var viewPort = getViewport();\r
643                                         var top = pos.top;\r
644                                         var left = pos.left;\r
645                                         var oldDisplay = $.curCSS(calEl, 'display');\r
646                                         cal.css({\r
647                                                 visibility: 'hidden',\r
648                                                 display: 'block'\r
649                                         });\r
650                                         layout(calEl);\r
651                                         switch (options.position){\r
652                                                 case 'top':\r
653                                                         top -= calEl.offsetHeight;\r
654                                                         break;\r
655                                                 case 'left':\r
656                                                         left -= calEl.offsetWidth;\r
657                                                         break;\r
658                                                 case 'right':\r
659                                                         left += this.offsetWidth;\r
660                                                         break;\r
661                                                 case 'bottom':\r
662                                                         top += this.offsetHeight;\r
663                                                         break;\r
664                                         }\r
665                                         if (top + calEl.offsetHeight > viewPort.t + viewPort.h) {\r
666                                                 top = pos.top  - calEl.offsetHeight;\r
667                                         }\r
668                                         if (top < viewPort.t) {\r
669                                                 top = pos.top + this.offsetHeight + calEl.offsetHeight;\r
670                                         }\r
671                                         if (left + calEl.offsetWidth > viewPort.l + viewPort.w) {\r
672                                                 left = pos.left - calEl.offsetWidth;\r
673                                         }\r
674                                         if (left < viewPort.l) {\r
675                                                 left = pos.left + this.offsetWidth\r
676                                         }\r
677                                         cal.css({\r
678                                                 visibility: 'visible',\r
679                                                 display: 'block',\r
680                                                 top: top + 'px',\r
681                                                 left: left + 'px'\r
682                                         });\r
683                                         if (options.onShow.apply(this, [cal.get(0)]) != false) {\r
684                                                 cal.show();\r
685                                         }\r
686                                         $(document).bind('mousedown', {cal: cal, trigger: this}, hide);\r
687                                 }\r
688                                 return false;\r
689                         },\r
690                         hide = function (ev) {\r
691                                 if (ev.target != ev.data.trigger && !isChildOf(ev.data.cal.get(0), ev.target, ev.data.cal.get(0))) {\r
692                                         if (ev.data.cal.data('datepicker').onHide.apply(this, [ev.data.cal.get(0)]) != false) {\r
693                                                 ev.data.cal.hide();\r
694                                         }\r
695                                         $(document).unbind('mousedown', hide);\r
696                                 }\r
697                         };\r
698                 return {\r
699                         init: function(options){\r
700                                 options = $.extend({}, defaults, options||{});\r
701                                 extendDate(options.locale);\r
702                                 options.calendars = Math.max(1, parseInt(options.calendars,10)||1);\r
703                                 options.mode = /single|multiple|range/.test(options.mode) ? options.mode : 'single';\r
704                                 return this.each(function(){\r
705                                         if (!$(this).data('datepicker')) {\r
706                                                 options.el = this;\r
707                                                 if (options.date.constructor == String) {\r
708                                                         options.date = parseDate(options.date, options.format);\r
709                                                         options.date.setHours(0,0,0,0);\r
710                                                 }\r
711                                                 if (options.mode != 'single') {\r
712                                                         if (options.date.constructor != Array) {\r
713                                                                 options.date = [options.date.valueOf()];\r
714                                                                 if (options.mode == 'range') {\r
715                                                                         options.date.push(((new Date(options.date[0])).setHours(23,59,59,0)).valueOf());\r
716                                                                 }\r
717                                                         } else {\r
718                                                                 for (var i = 0; i < options.date.length; i++) {\r
719                                                                         options.date[i] = (parseDate(options.date[i], options.format).setHours(0,0,0,0)).valueOf();\r
720                                                                 }\r
721                                                                 if (options.mode == 'range') {\r
722                                                                         options.date[1] = ((new Date(options.date[1])).setHours(23,59,59,0)).valueOf();\r
723                                                                 }\r
724                                                         }\r
725                                                 } else {\r
726                                                         options.date = options.date.valueOf();\r
727                                                 }\r
728                                                 if (!options.current) {\r
729                                                         options.current = new Date();\r
730                                                 } else {\r
731                                                         options.current = parseDate(options.current, options.format);\r
732                                                 } \r
733                                                 options.current.setDate(1);\r
734                                                 options.current.setHours(0,0,0,0);\r
735                                                 var id = 'datepicker_' + parseInt(Math.random() * 1000), cnt;\r
736                                                 options.id = id;\r
737                                                 $(this).data('datepickerId', options.id);\r
738                                                 var cal = $(tpl.wrapper).attr('id', id).bind('click', click).data('datepicker', options);\r
739                                                 if (options.className) {\r
740                                                         cal.addClass(options.className);\r
741                                                 }\r
742                                                 var html = '';\r
743                                                 for (var i = 0; i < options.calendars; i++) {\r
744                                                         cnt = options.starts;\r
745                                                         if (i > 0) {\r
746                                                                 html += tpl.space;\r
747                                                         }\r
748                                                         html += tmpl(tpl.head.join(''), {\r
749                                                                         week: options.locale.weekMin,\r
750                                                                         prev: options.prev,\r
751                                                                         next: options.next,\r
752                                                                         day1: options.locale.daysMin[(cnt++)%7],\r
753                                                                         day2: options.locale.daysMin[(cnt++)%7],\r
754                                                                         day3: options.locale.daysMin[(cnt++)%7],\r
755                                                                         day4: options.locale.daysMin[(cnt++)%7],\r
756                                                                         day5: options.locale.daysMin[(cnt++)%7],\r
757                                                                         day6: options.locale.daysMin[(cnt++)%7],\r
758                                                                         day7: options.locale.daysMin[(cnt++)%7]\r
759                                                                 });\r
760                                                 }\r
761                                                 cal\r
762                                                         .find('tr:first').append(html)\r
763                                                                 .find('table').addClass(views[options.view]);\r
764                                                 fill(cal.get(0));\r
765                                                 if (options.flat) {\r
766                                                         cal.appendTo(this).show().css('position', 'relative');\r
767                                                         layout(cal.get(0));\r
768                                                 } else {\r
769                                                         cal.appendTo(document.body);\r
770                                                         $(this).bind(options.eventName, show);\r
771                                                 }\r
772                                         }\r
773                                 });\r
774                         },\r
775                         showPicker: function() {\r
776                                 return this.each( function () {\r
777                                         if ($(this).data('datepickerId')) {\r
778                                                 show.apply(this);\r
779                                         }\r
780                                 });\r
781                         },\r
782                         hidePicker: function() {\r
783                                 return this.each( function () {\r
784                                         if ($(this).data('datepickerId')) {\r
785                                                 $('#' + $(this).data('datepickerId')).hide();\r
786                                         }\r
787                                 });\r
788                         },\r
789                         setDate: function(date, shiftTo){\r
790                                 return this.each(function(){\r
791                                         if ($(this).data('datepickerId')) {\r
792                                                 var cal = $('#' + $(this).data('datepickerId'));\r
793                                                 var options = cal.data('datepicker');\r
794                                                 options.date = date;\r
795                                                 if (options.date.constructor == String) {\r
796                                                         options.date = parseDate(options.date, options.format);\r
797                                                         options.date.setHours(0,0,0,0);\r
798                                                 }\r
799                                                 if (options.mode != 'single') {\r
800                                                         if (options.date.constructor != Array) {\r
801                                                                 options.date = [options.date.valueOf()];\r
802                                                                 if (options.mode == 'range') {\r
803                                                                         options.date.push(((new Date(options.date[0])).setHours(23,59,59,0)).valueOf());\r
804                                                                 }\r
805                                                         } else {\r
806                                                                 for (var i = 0; i < options.date.length; i++) {\r
807                                                                         options.date[i] = (parseDate(options.date[i], options.format).setHours(0,0,0,0)).valueOf();\r
808                                                                 }\r
809                                                                 if (options.mode == 'range') {\r
810                                                                         options.date[1] = ((new Date(options.date[1])).setHours(23,59,59,0)).valueOf();\r
811                                                                 }\r
812                                                         }\r
813                                                 } else {\r
814                                                         options.date = options.date.valueOf();\r
815                                                 }\r
816                                                 if (shiftTo) {\r
817                                                         options.current = new Date (options.mode != 'single' ? options.date[0] : options.date);\r
818                                                 }\r
819                                                 fill(cal.get(0));\r
820                                         }\r
821                                 });\r
822                         },\r
823                         getDate: function(formated) {\r
824                                 if (this.size() > 0) {\r
825                                         return prepareDate($('#' + $(this).data('datepickerId')).data('datepicker'))[formated ? 0 : 1];\r
826                                 }\r
827                         },\r
828                         clear: function(){\r
829                                 return this.each(function(){\r
830                                         if ($(this).data('datepickerId')) {\r
831                                                 var cal = $('#' + $(this).data('datepickerId'));\r
832                                                 var options = cal.data('datepicker');\r
833                                                 if (options.mode != 'single') {\r
834                                                         options.date = [];\r
835                                                         fill(cal.get(0));\r
836                                                 }\r
837                                         }\r
838                                 });\r
839                         },\r
840                         fixLayout: function(){\r
841                                 return this.each(function(){\r
842                                         if ($(this).data('datepickerId')) {\r
843                                                 var cal = $('#' + $(this).data('datepickerId'));\r
844                                                 var options = cal.data('datepicker');\r
845                                                 if (options.flat) {\r
846                                                         layout(cal.get(0));\r
847                                                 }\r
848                                         }\r
849                                 });\r
850                         }\r
851                 };\r
852         }();\r
853         $.fn.extend({\r
854                 DatePicker: DatePicker.init,\r
855                 DatePickerHide: DatePicker.hidePicker,\r
856                 DatePickerShow: DatePicker.showPicker,\r
857                 DatePickerSetDate: DatePicker.setDate,\r
858                 DatePickerGetDate: DatePicker.getDate,\r
859                 DatePickerClear: DatePicker.clear,\r
860                 DatePickerLayout: DatePicker.fixLayout\r
861         });\r
862 })(jQuery);\r
863 \r
864 (function(){\r
865   var cache = {};\r
866  \r
867   this.tmpl = function tmpl(str, data){\r
868     // Figure out if we're getting a template, or if we need to\r
869     // load the template - and be sure to cache the result.\r
870     var fn = !/\W/.test(str) ?\r
871       cache[str] = cache[str] ||\r
872         tmpl(document.getElementById(str).innerHTML) :\r
873      \r
874       // Generate a reusable function that will serve as a template\r
875       // generator (and which will be cached).\r
876       new Function("obj",\r
877         "var p=[],print=function(){p.push.apply(p,arguments);};" +\r
878        \r
879         // Introduce the data as local variables using with(){}\r
880         "with(obj){p.push('" +\r
881        \r
882         // Convert the template into pure JavaScript\r
883         str\r
884           .replace(/[\r\t\n]/g, " ")\r
885           .split("<%").join("\t")\r
886           .replace(/((^|%>)[^\t]*)'/g, "$1\r")\r
887           .replace(/\t=(.*?)%>/g, "',$1,'")\r
888           .split("\t").join("');")\r
889           .split("%>").join("p.push('")\r
890           .split("\r").join("\\'")\r
891       + "');}return p.join('');");\r
892    \r
893     // Provide some basic currying to the user\r
894     return data ? fn( data ) : fn;\r
895   };\r
896 })();\r