[ Index ]

PHP Cross Reference of YOURLS

title

Body

[close]

/js/ -> jquery.cal.js (source)

   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  });


Generated: Tue Jan 21 05:10:11 2025 Cross-referenced by PHPXref 0.7.1