[ Index ] |
PHP Cross Reference of vtigercrm-6.1.0 |
[Summary view] [Print] [Text view]
1 /** 2 * -------------------------------------------------------------------- 3 * jQuery-Plugin "daterangepicker.jQuery.js" 4 * by Scott Jehl, [email protected] 5 * reference article: http://www.filamentgroup.com/lab/update_date_range_picker_with_jquery_ui/ 6 * demo page: http://www.filamentgroup.com/examples/daterangepicker/ 7 * 8 * Copyright (c) 2010 Filament Group, Inc 9 * Dual licensed under the MIT (filamentgroup.com/examples/mit-license.txt) and GPL (filamentgroup.com/examples/gpl-license.txt) licenses. 10 * 11 * Dependencies: jquery, jquery UI datepicker, date.js, jQuery UI CSS Framework 12 13 * 12.15.2010 Made some fixes to resolve breaking changes introduced by jQuery UI 1.8.7 14 * -------------------------------------------------------------------- 15 */ 16 jQuery.fn.daterangepicker = function(settings){ 17 var rangeInput = jQuery(this); 18 19 //defaults 20 var options = jQuery.extend({ 21 presetRanges: [ 22 {text: 'Today', dateStart: 'today', dateEnd: 'today' }, 23 {text: 'Last 7 days', dateStart: 'today-7days', dateEnd: 'today' }, 24 {text: 'Month to date', dateStart: function(){ return Date.parse('today').moveToFirstDayOfMonth(); }, dateEnd: 'today' }, 25 {text: 'Year to date', dateStart: function(){ var x= Date.parse('today'); x.setMonth(0); x.setDate(1); return x; }, dateEnd: 'today' }, 26 //extras: 27 {text: 'The previous Month', dateStart: function(){ return Date.parse('1 month ago').moveToFirstDayOfMonth(); }, dateEnd: function(){ return Date.parse('1 month ago').moveToLastDayOfMonth(); } } 28 //{text: 'Tomorrow', dateStart: 'Tomorrow', dateEnd: 'Tomorrow' }, 29 //{text: 'Ad Campaign', dateStart: '03/07/08', dateEnd: 'Today' }, 30 //{text: 'Last 30 Days', dateStart: 'Today-30', dateEnd: 'Today' }, 31 //{text: 'Next 30 Days', dateStart: 'Today', dateEnd: 'Today+30' }, 32 //{text: 'Our Ad Campaign', dateStart: '03/07/08', dateEnd: '07/08/08' } 33 ], 34 //presetRanges: array of objects for each menu preset. 35 //Each obj must have text, dateStart, dateEnd. dateStart, dateEnd accept date.js string or a function which returns a date object 36 presets: { 37 specificDate: 'Specific Date', 38 allDatesBefore: 'All Dates Before', 39 allDatesAfter: 'All Dates After', 40 dateRange: 'Date Range' 41 }, 42 rangeStartTitle: 'Start date', 43 rangeEndTitle: 'End date', 44 nextLinkText: 'Next', 45 prevLinkText: 'Prev', 46 doneButtonText: 'Done', 47 earliestDate: Date.parse('-15years'), //earliest date allowed 48 latestDate: Date.parse('+15years'), //latest date allowed 49 constrainDates: false, 50 rangeSplitter: '-', //string to use between dates in single input 51 dateFormat: 'm/d/yy', // date formatting. Available formats: http://docs.jquery.com/UI/Datepicker/%24.datepicker.formatDate 52 closeOnSelect: true, //if a complete selection is made, close the menu 53 arrows: false, 54 appendTo: 'body', 55 onClose: function(){}, 56 onOpen: function(){}, 57 onChange: function(){}, 58 datepickerOptions: null //object containing native UI datepicker API options 59 }, settings); 60 61 62 63 //custom datepicker options, extended by options 64 var datepickerOptions = { 65 onSelect: function(dateText, inst) { 66 $(this).trigger('constrainOtherPicker'); 67 68 var rangeA = fDate( rp.find('.range-start').datepicker('getDate') ); 69 var rangeB = fDate( rp.find('.range-end').datepicker('getDate') ); 70 71 if(rp.find('.ui-daterangepicker-specificDate').is('.ui-state-active')){ 72 rangeB = rangeA; 73 } 74 75 //send back to input or inputs 76 if(rangeInput.length == 2){ 77 rangeInput.eq(0).val(rangeA); 78 rangeInput.eq(1).val(rangeB); 79 } 80 else{ 81 rangeInput.val((rangeA != rangeB) ? rangeA+' '+ options.rangeSplitter +' '+rangeB : rangeA); 82 } 83 //if closeOnSelect is true 84 if(options.closeOnSelect){ 85 if(!rp.find('li.ui-state-active').is('.ui-daterangepicker-dateRange') && !rp.is(':animated') ){ 86 hideRP(); 87 } 88 } 89 options.onChange(); 90 }, 91 defaultDate: +0 92 }; 93 94 //change event fires both when a calendar is updated or a change event on the input is triggered 95 rangeInput.bind('change', options.onChange); 96 97 //datepicker options from options 98 options.datepickerOptions = (settings) ? jQuery.extend(datepickerOptions, settings.datepickerOptions) : datepickerOptions; 99 100 //Capture Dates from input(s) 101 var inputDateA, inputDateB = Date.parse('today'); 102 var inputDateAtemp, inputDateBtemp; 103 if(rangeInput.size() == 2){ 104 inputDateAtemp = Date.parse( rangeInput.eq(0).val() ); 105 inputDateBtemp = Date.parse( rangeInput.eq(1).val() ); 106 if(inputDateAtemp == null){inputDateAtemp = inputDateBtemp;} 107 if(inputDateBtemp == null){inputDateBtemp = inputDateAtemp;} 108 } 109 else { 110 //if(rangeInput.val()){ 111 inputDateAtemp = Date.parse( rangeInput.val().split(options.rangeSplitter)[0] ); 112 inputDateBtemp = Date.parse( rangeInput.val().split(options.rangeSplitter)[1] ); 113 if(inputDateBtemp == null){inputDateBtemp = inputDateAtemp;} //if one date, set both 114 //} 115 } 116 if(inputDateAtemp != null){inputDateA = inputDateAtemp;} 117 if(inputDateBtemp != null){inputDateB = inputDateBtemp;} 118 119 120 //build picker and 121 var rp = jQuery('<div class="ui-daterangepicker ui-widget ui-helper-clearfix ui-widget-content ui-corner-all"></div>'); 122 var rpPresets = (function(){ 123 var ul = jQuery('<ul class="ui-widget-content"></ul>').appendTo(rp); 124 jQuery.each(options.presetRanges,function(){ 125 jQuery('<li class="ui-daterangepicker-'+ this.text.replace(/ /g, '') +' ui-corner-all"><a href="#">'+ this.text +'</a></li>') 126 .data('dateStart', this.dateStart) 127 .data('dateEnd', this.dateEnd) 128 .appendTo(ul); 129 }); 130 var x=0; 131 jQuery.each(options.presets, function(key, value) { 132 jQuery('<li class="ui-daterangepicker-'+ key +' preset_'+ x +' ui-helper-clearfix ui-corner-all"><span class="ui-icon ui-icon-triangle-1-e"></span><a href="#">'+ value +'</a></li>') 133 .appendTo(ul); 134 x++; 135 }); 136 137 ul.find('li').hover( 138 function(){ 139 jQuery(this).addClass('ui-state-hover'); 140 }, 141 function(){ 142 jQuery(this).removeClass('ui-state-hover'); 143 }) 144 .click(function(){ 145 rp.find('.ui-state-active').removeClass('ui-state-active'); 146 jQuery(this).addClass('ui-state-active'); 147 clickActions(jQuery(this),rp, rpPickers, doneBtn); 148 return false; 149 }); 150 return ul; 151 })(); 152 153 //function to format a date string 154 function fDate(date){ 155 if(date == null || !date.getDate()){return '';} 156 var day = date.getDate(); 157 var month = date.getMonth(); 158 var year = date.getFullYear(); 159 month++; // adjust javascript month 160 var dateFormat = options.dateFormat; 161 return jQuery.datepicker.formatDate( dateFormat, date ); 162 } 163 164 165 jQuery.fn.restoreDateFromData = function(){ 166 if(jQuery(this).data('saveDate')){ 167 jQuery(this).datepicker('setDate', jQuery(this).data('saveDate')).removeData('saveDate'); 168 } 169 return this; 170 } 171 jQuery.fn.saveDateToData = function(){ 172 if(!jQuery(this).data('saveDate')){ 173 jQuery(this).data('saveDate', jQuery(this).datepicker('getDate') ); 174 } 175 return this; 176 } 177 178 //show, hide, or toggle rangepicker 179 function showRP(){ 180 if(rp.data('state') == 'closed'){ 181 positionRP(); 182 rp.fadeIn(300).data('state', 'open'); 183 options.onOpen(); 184 } 185 } 186 function hideRP(){ 187 if(rp.data('state') == 'open'){ 188 rp.fadeOut(300).data('state', 'closed'); 189 options.onClose(); 190 } 191 } 192 function toggleRP(){ 193 if( rp.data('state') == 'open' ){ hideRP(); } 194 else { showRP(); } 195 } 196 function positionRP(){ 197 var relEl = riContain || rangeInput; //if arrows, use parent for offsets 198 var riOffset = relEl.offset(), 199 side = 'left', 200 val = riOffset.left, 201 offRight = jQuery(window).width() - val - relEl.outerWidth(); 202 203 if(val > offRight){ 204 side = 'right', val = offRight; 205 } 206 207 rp.parent().css(side, val).css('top', riOffset.top + relEl.outerHeight()); 208 } 209 210 211 212 //preset menu click events 213 function clickActions(el, rp, rpPickers, doneBtn){ 214 215 if(el.is('.ui-daterangepicker-specificDate')){ 216 //Specific Date (show the "start" calendar) 217 doneBtn.hide(); 218 rpPickers.show(); 219 rp.find('.title-start').text( options.presets.specificDate ); 220 rp.find('.range-start').restoreDateFromData().css('opacity',1).show(400); 221 rp.find('.range-end').restoreDateFromData().css('opacity',0).hide(400); 222 setTimeout(function(){doneBtn.fadeIn();}, 400); 223 } 224 else if(el.is('.ui-daterangepicker-allDatesBefore')){ 225 //All dates before specific date (show the "end" calendar and set the "start" calendar to the earliest date) 226 doneBtn.hide(); 227 rpPickers.show(); 228 rp.find('.title-end').text( options.presets.allDatesBefore ); 229 rp.find('.range-start').saveDateToData().datepicker('setDate', options.earliestDate).css('opacity',0).hide(400); 230 rp.find('.range-end').restoreDateFromData().css('opacity',1).show(400); 231 setTimeout(function(){doneBtn.fadeIn();}, 400); 232 } 233 else if(el.is('.ui-daterangepicker-allDatesAfter')){ 234 //All dates after specific date (show the "start" calendar and set the "end" calendar to the latest date) 235 doneBtn.hide(); 236 rpPickers.show(); 237 rp.find('.title-start').text( options.presets.allDatesAfter ); 238 rp.find('.range-start').restoreDateFromData().css('opacity',1).show(400); 239 rp.find('.range-end').saveDateToData().datepicker('setDate', options.latestDate).css('opacity',0).hide(400); 240 setTimeout(function(){doneBtn.fadeIn();}, 400); 241 } 242 else if(el.is('.ui-daterangepicker-dateRange')){ 243 //Specific Date range (show both calendars) 244 doneBtn.hide(); 245 rpPickers.show(); 246 rp.find('.title-start').text(options.rangeStartTitle); 247 rp.find('.title-end').text(options.rangeEndTitle); 248 rp.find('.range-start').restoreDateFromData().css('opacity',1).show(400); 249 rp.find('.range-end').restoreDateFromData().css('opacity',1).show(400); 250 setTimeout(function(){doneBtn.fadeIn();}, 400); 251 } 252 else { 253 //custom date range specified in the options (no calendars shown) 254 doneBtn.hide(); 255 rp.find('.range-start, .range-end').css('opacity',0).hide(400, function(){ 256 rpPickers.hide(); 257 }); 258 var dateStart = (typeof el.data('dateStart') == 'string') ? Date.parse(el.data('dateStart')) : el.data('dateStart')(); 259 var dateEnd = (typeof el.data('dateEnd') == 'string') ? Date.parse(el.data('dateEnd')) : el.data('dateEnd')(); 260 rp.find('.range-start').datepicker('setDate', dateStart).find('.ui-datepicker-current-day').trigger('click'); 261 rp.find('.range-end').datepicker('setDate', dateEnd).find('.ui-datepicker-current-day').trigger('click'); 262 } 263 264 return false; 265 } 266 267 268 //picker divs 269 var rpPickers = jQuery('<div class="ranges ui-widget-header ui-corner-all ui-helper-clearfix"><div class="range-start"><span class="title-start">Start Date</span></div><div class="range-end"><span class="title-end">End Date</span></div></div>').appendTo(rp); 270 rpPickers.find('.range-start, .range-end') 271 .datepicker(options.datepickerOptions); 272 273 274 rpPickers.find('.range-start').datepicker('setDate', inputDateA); 275 rpPickers.find('.range-end').datepicker('setDate', inputDateB); 276 277 rpPickers.find('.range-start, .range-end') 278 .bind('constrainOtherPicker', function(){ 279 if(options.constrainDates){ 280 //constrain dates 281 if($(this).is('.range-start')){ 282 rp.find('.range-end').datepicker( "option", "minDate", $(this).datepicker('getDate')); 283 } 284 else{ 285 rp.find('.range-start').datepicker( "option", "maxDate", $(this).datepicker('getDate')); 286 } 287 } 288 }) 289 .trigger('constrainOtherPicker'); 290 291 var doneBtn = jQuery('<button class="btnDone ui-state-default ui-corner-all">'+ options.doneButtonText +'</button>') 292 .click(function(){ 293 rp.find('.ui-datepicker-current-day').trigger('click'); 294 hideRP(); 295 }) 296 .hover( 297 function(){ 298 jQuery(this).addClass('ui-state-hover'); 299 }, 300 function(){ 301 jQuery(this).removeClass('ui-state-hover'); 302 } 303 ) 304 .appendTo(rpPickers); 305 306 307 308 309 //inputs toggle rangepicker visibility 310 jQuery(this).click(function(){ 311 toggleRP(); 312 return false; 313 }); 314 //hide em all 315 rpPickers.hide().find('.range-start, .range-end, .btnDone').hide(); 316 317 rp.data('state', 'closed'); 318 319 //Fixed for jQuery UI 1.8.7 - Calendars are hidden otherwise! 320 rpPickers.find('.ui-datepicker').css("display","block"); 321 322 //inject rp 323 jQuery(options.appendTo).append(rp); 324 325 //wrap and position 326 rp.wrap('<div class="ui-daterangepickercontain"></div>'); 327 328 //add arrows (only available on one input) 329 if(options.arrows && rangeInput.size()==1){ 330 var prevLink = jQuery('<a href="#" class="ui-daterangepicker-prev ui-corner-all" title="'+ options.prevLinkText +'"><span class="ui-icon ui-icon-circle-triangle-w">'+ options.prevLinkText +'</span></a>'); 331 var nextLink = jQuery('<a href="#" class="ui-daterangepicker-next ui-corner-all" title="'+ options.nextLinkText +'"><span class="ui-icon ui-icon-circle-triangle-e">'+ options.nextLinkText +'</span></a>'); 332 333 jQuery(this) 334 .addClass('ui-rangepicker-input ui-widget-content') 335 .wrap('<div class="ui-daterangepicker-arrows ui-widget ui-widget-header ui-helper-clearfix ui-corner-all"></div>') 336 .before( prevLink ) 337 .before( nextLink ) 338 .parent().find('a').click(function(){ 339 var dateA = rpPickers.find('.range-start').datepicker('getDate'); 340 var dateB = rpPickers.find('.range-end').datepicker('getDate'); 341 var diff = Math.abs( new TimeSpan(dateA - dateB).getTotalMilliseconds() ) + 86400000; //difference plus one day 342 if(jQuery(this).is('.ui-daterangepicker-prev')){ diff = -diff; } 343 344 rpPickers.find('.range-start, .range-end ').each(function(){ 345 var thisDate = jQuery(this).datepicker( "getDate"); 346 if(thisDate == null){return false;} 347 jQuery(this).datepicker( "setDate", thisDate.add({milliseconds: diff}) ).find('.ui-datepicker-current-day').trigger('click'); 348 }); 349 return false; 350 }) 351 .hover( 352 function(){ 353 jQuery(this).addClass('ui-state-hover'); 354 }, 355 function(){ 356 jQuery(this).removeClass('ui-state-hover'); 357 }); 358 359 var riContain = rangeInput.parent(); 360 } 361 362 363 jQuery(document).click(function(){ 364 if (rp.is(':visible')) { 365 hideRP(); 366 } 367 }); 368 369 rp.click(function(){return false;}).hide(); 370 return this; 371 } 372 373 374
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Fri Nov 28 20:08:37 2014 | Cross-referenced by PHPXref 0.7.1 |