]> CyberLeo.Net >> Repos - Github/YOURLS.git/blob - js/jquery.cal.js
Remove password verification
[Github/YOURLS.git] / js / jquery.cal.js
1 /**
2         the script only works on "input [type=text]"
3         http://teddevito.com/demos/calendar.php
4 **/
5
6 // don't declare anything out here in the global namespace
7
8 (function($) { // create private scope (inside you can use $ instead of jQuery)
9
10     // functions and vars declared here are effectively 'singletons'.  there will be only a single
11     // instance of them.  so this is a good place to declare any immutable items or stateless
12     // functions.  for example:
13
14         var today = new Date(); // used in defaults
15     var months = 'January,February,March,April,May,June,July,August,September,October,November,December'.split(',');
16     var months = l10n_cal_month;
17         var monthlengths = '31,28,31,30,31,30,31,31,30,31,30,31'.split(',');
18         var dateRegEx = /^\d{1,2}\/\d{1,2}\/\d{2}|\d{4}$/;
19         var yearRegEx = /^\d{4,4}$/;
20
21     // next, declare the plugin function
22     $.fn.simpleDatepicker = function(options) {
23
24         // functions and vars declared here are created each time your plugn function is invoked
25
26         // you could probably refactor your 'build', 'load_month', etc, functions to be passed
27         // the DOM element from below
28
29                 var opts = jQuery.extend({}, jQuery.fn.simpleDatepicker.defaults, options);
30                 
31                 // replaces a date string with a date object in opts.startdate and opts.enddate, if one exists
32                 // populates two new properties with a ready-to-use year: opts.startyear and opts.endyear
33                 
34                 setupYearRange();
35                 /** extracts and setup a valid year range from the opts object **/
36                 function setupYearRange () {
37                         
38                         var startyear, endyear;  
39                         if (opts.startdate.constructor == Date) {
40                                 startyear = opts.startdate.getFullYear();
41                         } else if (opts.startdate) {
42                                 if (yearRegEx.test(opts.startdate)) {
43                                 startyear = opts.startdate;
44                                 } else if (dateRegEx.test(opts.startdate)) {
45                                         opts.startdate = new Date(opts.startdate);
46                                         startyear = opts.startdate.getFullYear();
47                                 } else {
48                                 startyear = today.getFullYear();
49                                 }
50                         } else {
51                                 startyear = today.getFullYear();
52                         }
53                         opts.startyear = startyear;
54                         
55                         if (opts.enddate.constructor == Date) {
56                                 endyear = opts.enddate.getFullYear();
57                         } else if (opts.enddate) {
58                                 if (yearRegEx.test(opts.enddate)) {
59                                         endyear = opts.enddate;
60                                 } else if (dateRegEx.test(opts.enddate)) {
61                                         opts.enddate = new Date(opts.enddate);
62                                         endyear = opts.enddate.getFullYear();
63                                 } else {
64                                         endyear = today.getFullYear();
65                                 }
66                         } else {
67                                 endyear = today.getFullYear();
68                         }
69                         opts.endyear = endyear; 
70                 }
71                 
72                 /** HTML factory for the actual datepicker table element **/
73                 // has to read the year range so it can setup the correct years in our HTML <select>
74                 function newDatepickerHTML () {
75                         
76                         var years = [];
77                         
78                         // process year range into an array
79                         for (var i = 0; i <= opts.endyear - opts.startyear; i ++) years[i] = opts.startyear + i;
80         
81                         // build the table structure
82                         var table = jQuery('<table class="datepicker" cellpadding="0" cellspacing="0"></table>');
83                         table.append('<thead></thead>');
84                         table.append('<tfoot></tfoot>');
85                         table.append('<tbody></tbody>');
86                         
87                                 // month select field
88                                 var monthselect = '<select name="month">';
89                                 for (var i in l10n_cal_month) monthselect += '<option value="'+i+'">'+l10n_cal_month[i]+'</option>';
90                                 monthselect += '</select>';
91                         
92                                 // year select field
93                                 var yearselect = '<select name="year">';
94                                 for (var i in years) yearselect += '<option>'+years[i]+'</option>';
95                                 yearselect += '</select>';
96                         
97                         jQuery("thead",table).append('<tr class="controls"><th colspan="7"><span class="prevMonth">&laquo;</span>&nbsp;'+monthselect+yearselect+'&nbsp;<span class="nextMonth">&raquo;</span></th></tr>');
98                         jQuery("thead",table).append('<tr class="days"><th>'+l10n_cal_days[0]+'</th><th>'+l10n_cal_days[1]+'</th><th>'+l10n_cal_days[2]+'</th><th>'+l10n_cal_days[3]+'</th><th>'+l10n_cal_days[4]+'</th><th>'+l10n_cal_days[5]+'</th><th>'+l10n_cal_days[6]+'</th></tr>');
99                         jQuery("tfoot",table).append('<tr><td colspan="2"><span class="today">'+l10n_cal_today+'</span></td><td colspan="3">&nbsp;</td><td colspan="2"><span class="close">'+l10n_cal_close+'</span></td></tr>');
100                         for (var i = 0; i < 6; i++) jQuery("tbody",table).append('<tr><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr>');   
101                         return table;
102                 }
103                 
104                 /** get the real position of the input (well, anything really) **/
105                 //http://www.quirksmode.org/js/findpos.html
106                 function findPosition (obj) {
107                         var curleft = curtop = 0;
108                         if (obj.offsetParent) {
109                                 do { 
110                                         curleft += obj.offsetLeft;
111                                         curtop += obj.offsetTop;
112                                 } while (obj = obj.offsetParent);
113                                 return [curleft,curtop];
114                         } else {
115                                 return false;
116                         }
117                 }
118                 
119                 /** load the initial date and handle all date-navigation **/
120                 // initial calendar load (e is null)
121                 // prevMonth & nextMonth buttons
122                 // onchange for the select fields
123                 function loadMonth (e, el, datepicker, chosendate) {
124                         
125                         // reference our years for the nextMonth and prevMonth buttons
126                         var mo = jQuery("select[name=month]", datepicker).get(0).selectedIndex;
127                         var yr = jQuery("select[name=year]", datepicker).get(0).selectedIndex;
128                         var yrs = jQuery("select[name=year] option", datepicker).get().length;
129                         
130                         // first try to process buttons that may change the month we're on
131                         if (e && jQuery(e.target).hasClass('prevMonth')) {                              
132                                 if (0 == mo && yr) {
133                                         yr -= 1; mo = 11;
134                                         jQuery("select[name=month]", datepicker).get(0).selectedIndex = 11;
135                                         jQuery("select[name=year]", datepicker).get(0).selectedIndex = yr;
136                                 } else {
137                                         mo -= 1;
138                                         jQuery("select[name=month]", datepicker).get(0).selectedIndex = mo;
139                                 }
140                         } else if (e && jQuery(e.target).hasClass('nextMonth')) {
141                                 if (11 == mo && yr + 1 < yrs) {
142                                         yr += 1; mo = 0;
143                                         jQuery("select[name=month]", datepicker).get(0).selectedIndex = 0;
144                                         jQuery("select[name=year]", datepicker).get(0).selectedIndex = yr;
145                                 } else { 
146                                         mo += 1;
147                                         jQuery("select[name=month]", datepicker).get(0).selectedIndex = mo;
148                                 }
149                         }
150                         
151                         // maybe hide buttons
152                         if (0 == mo && !yr) jQuery("span.prevMonth", datepicker).hide(); 
153                         else jQuery("span.prevMonth", datepicker).show(); 
154                         if (yr + 1 == yrs && 11 == mo) jQuery("span.nextMonth", datepicker).hide(); 
155                         else jQuery("span.nextMonth", datepicker).show(); 
156                         
157                         // clear the old cells
158                         var cells = jQuery("tbody td", datepicker).unbind().empty().removeClass('date');
159                         
160                         // figure out what month and year to load
161                         var m = jQuery("select[name=month]", datepicker).val();
162                         var y = jQuery("select[name=year]", datepicker).val();
163                         var d = new Date(y, m, 1);
164                         var startindex = d.getDay();
165                         var numdays = monthlengths[m];
166                         
167                         // http://en.wikipedia.org/wiki/Leap_year
168                         if (1 == m && ((y%4 == 0 && y%100 != 0) || y%400 == 0)) numdays = 29;
169                         
170                         // test for end dates (instead of just a year range)
171                         if (opts.startdate.constructor == Date) {
172                                 var startMonth = opts.startdate.getMonth();
173                                 var startDate = opts.startdate.getDate();
174                         }
175                         if (opts.enddate.constructor == Date) {
176                                 var endMonth = opts.enddate.getMonth();
177                                 var endDate = opts.enddate.getDate();
178                         }
179                         
180                         // walk through the index and populate each cell, binding events too
181                         for (var i = 0; i < numdays; i++) {
182                         
183                                 var cell = jQuery(cells.get(i+startindex)).removeClass('chosen');
184                                 
185                                 // test that the date falls within a range, if we have a range
186                                 if ( 
187                                         (yr || ((!startDate && !startMonth) || ((i+1 >= startDate && mo == startMonth) || mo > startMonth))) &&
188                                         (yr + 1 < yrs || ((!endDate && !endMonth) || ((i+1 <= endDate && mo == endMonth) || mo < endMonth)))) {
189                                 
190                                         cell
191                                                 .text(i+1)
192                                                 .addClass('date')
193                                                 .hover(
194                                                         function () { jQuery(this).addClass('over'); },
195                                                         function () { jQuery(this).removeClass('over'); })
196                                                 .click(function () {
197                                                         var chosenDateObj = new Date(jQuery("select[name=year]", datepicker).val(), jQuery("select[name=month]", datepicker).val(), jQuery(this).text());
198                                                         closeIt(el, datepicker, chosenDateObj);
199                                                 });
200                                                 
201                                         // highlight the previous chosen date
202                                         if (i+1 == chosendate.getDate() && m == chosendate.getMonth() && y == chosendate.getFullYear()) cell.addClass('chosen');
203                                 }
204                         }
205                 }
206                 
207                 /** closes the datepicker **/
208                 // sets the currently matched input element's value to the date, if one is available
209                 // remove the table element from the DOM
210                 // indicate that there is no datepicker for the currently matched input element
211                 function closeIt (el, datepicker, dateObj) { 
212                         if (dateObj && dateObj.constructor == Date)
213                                 el.val(jQuery.fn.simpleDatepicker.formatOutput(dateObj));
214                         datepicker.remove();
215                         datepicker = null;
216                         jQuery.data(el.get(0), "simpleDatepicker", { hasDatepicker : false });
217                 }
218
219         // iterate the matched nodeset
220         return this.each(function() {
221                         
222             // functions and vars declared here are created for each matched element. so if
223             // your functions need to manage or access per-node state you can defined them
224             // here and use $this to get at the DOM element
225                         
226                         if ( jQuery(this).is('input') && 'text' == jQuery(this).attr('type')) {
227
228                                 var datepicker; 
229                                 jQuery.data(jQuery(this).get(0), "simpleDatepicker", { hasDatepicker : false });
230                                 
231                                 // open a datepicker on the click event
232                                 jQuery(this).click(function (ev) {
233                                                                                          
234                                         var $this = jQuery(ev.target);
235                                         
236                                         if (false == jQuery.data($this.get(0), "simpleDatepicker").hasDatepicker) {
237                                                 
238                                                 // store data telling us there is already a datepicker
239                                                 jQuery.data($this.get(0), "simpleDatepicker", { hasDatepicker : true });
240                                                 
241                                                 // validate the form's initial content for a date
242                                                 var initialDate = $this.val();
243                                                 
244                                                 if (initialDate && dateRegEx.test(initialDate)) {
245                                                         var chosendate = new Date(initialDate);
246                                                 } else if (opts.chosendate.constructor == Date) {
247                                                         var chosendate = opts.chosendate;
248                                                 } else if (opts.chosendate) {
249                                                         var chosendate = new Date(opts.chosendate);
250                                                 } else {
251                                                         var chosendate = today;
252                                                 }
253                                                         
254                                                 // insert the datepicker in the DOM
255                                                 datepicker = newDatepickerHTML();
256                                                 jQuery("body").prepend(datepicker);
257                                                 
258                                                 // position the datepicker
259                                                 var elPos = findPosition($this.get(0));
260                                                 var x = (parseInt(opts.x) ? parseInt(opts.x) : 0) + elPos[0];
261                                                 var y = (parseInt(opts.y) ? parseInt(opts.y) : 0) + elPos[1];
262                                                 jQuery(datepicker).css({ position: 'absolute', left: x, top: y });
263                                         
264                                                 // bind events to the table controls
265                                                 jQuery("span", datepicker).css("cursor","pointer");
266                                                 jQuery("select", datepicker).bind('change', function () { loadMonth (null, $this, datepicker, chosendate); });
267                                                 jQuery("span.prevMonth", datepicker).click(function (e) { loadMonth (e, $this, datepicker, chosendate); });
268                                                 jQuery("span.nextMonth", datepicker).click(function (e) { loadMonth (e, $this, datepicker, chosendate); });
269                                                 jQuery("span.today", datepicker).click(function () { closeIt($this, datepicker, new Date()); });
270                                                 jQuery("span.close", datepicker).click(function () { closeIt($this, datepicker); });
271                                                 
272                                                 // set the initial values for the month and year select fields
273                                                 // and load the first month
274                                                 jQuery("select[name=month]", datepicker).get(0).selectedIndex = chosendate.getMonth();
275                                                 jQuery("select[name=year]", datepicker).get(0).selectedIndex = Math.max(0, chosendate.getFullYear() - opts.startyear);
276                                                 loadMonth(null, $this, datepicker, chosendate);
277                                         }
278                                         
279                                 });
280                         }
281
282         });
283
284     };
285
286     // finally, I like to expose default plugin options as public so they can be manipulated.  one
287     // way to do this is to add a property to the already-public plugin fn
288
289         jQuery.fn.simpleDatepicker.formatOutput = function (dateObj) {
290                 return (dateObj.getMonth() + 1) + "/" + dateObj.getDate() + "/" + dateObj.getFullYear();        
291         };
292         
293         jQuery.fn.simpleDatepicker.defaults = {
294                 // date string matching /^\d{1,2}\/\d{1,2}\/\d{2}|\d{4}$/
295                 chosendate : today,
296                 
297                 // date string matching /^\d{1,2}\/\d{1,2}\/\d{2}|\d{4}$/
298                 // or four digit year
299                 startdate : today.getFullYear(), 
300                 enddate : today.getFullYear() + 1,
301                 
302                 // offset from the top left corner of the input element
303                 x : 1, // must be in px
304                 y : 18 // must be in px
305         };
306
307 })(jQuery);
308
309 // Init the form
310 $(document).ready(function(){
311         $('#date_first').simpleDatepicker({startdate: 2005, enddate: 2100});
312         $('#date_second').simpleDatepicker({startdate: 2005, enddate: 2100});
313         
314         $('#date_filter').change(function(){
315                 var show = $(this).val() == 'between' ? 'inline' : 'none';
316                 $('#date_second').css('display', show);
317                 $('#date_and').css('display', show);
318         });
319 });