[ Index ] |
PHP Cross Reference of vtigercrm-6.1.0 |
[Summary view] [Print] [Text view]
1 /** 2 * @version: 1.0 3 * @author: Dan Grossman http://www.dangrossman.info/ 4 * @date: 2012-08-20 5 * @copyright: Copyright (c) 2012 Dan Grossman. All rights reserved. 6 * @license: Licensed under Apache License v2.0. See http://www.apache.org/licenses/LICENSE-2.0 7 * @website: http://www.improvely.com/ 8 */ 9 !function ($) { 10 11 var DateRangePicker = function (element, options, cb) { 12 var hasOptions = typeof options == 'object' 13 var localeObject; 14 15 //state 16 this.startDate = Date.today(); 17 this.endDate = Date.today(); 18 this.changed = false; 19 this.ranges = {}; 20 this.opens = 'right'; 21 this.cb = function () { }; 22 this.format = 'MM/dd/yyyy'; 23 this.locale = { 24 applyLabel:"Apply", 25 fromLabel:"From", 26 toLabel:"To", 27 customRangeLabel:"Custom Range", 28 daysOfWeek:['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr','Sa'] 29 }; 30 31 localeObject = this.locale; 32 33 this.leftCalendar = { 34 month: Date.today().set({ day: 1, month: this.startDate.getMonth(), year: this.startDate.getFullYear() }), 35 calendar: Array() 36 }; 37 38 this.rightCalendar = { 39 month: Date.today().set({ day: 1, month: this.endDate.getMonth(), year: this.endDate.getFullYear() }), 40 calendar: Array() 41 }; 42 43 //element that triggered the date range picker 44 this.element = $(element); 45 46 if (this.element.hasClass('pull-right')) 47 this.opens = 'left'; 48 49 if (this.element.is('input')) { 50 this.element.on({ 51 click: $.proxy(this.show, this), 52 focus: $.proxy(this.show, this), 53 blur: $.proxy(this.hide, this) 54 }); 55 } else { 56 this.element.on('click', $.proxy(this.show, this)); 57 } 58 59 if (hasOptions) { 60 if(typeof options.locale == 'object') { 61 $.each(localeObject, function (property, value) { 62 localeObject[property] = options.locale[property] || value; 63 }); 64 } 65 } 66 67 var DRPTemplate = '<div class="daterangepicker dropdown-menu">' + 68 '<div class="calendar left"></div>' + 69 '<div class="calendar right"></div>' + 70 '<div class="ranges">' + 71 '<div class="range_inputs">' + 72 '<div style="float: left">' + 73 '<label for="daterangepicker_start">' + this.locale.fromLabel + '</label>' + 74 '<input class="input-mini" type="text" name="daterangepicker_start" value="" disabled="disabled" />' + 75 '</div>' + 76 '<div style="float: left; padding-left: 12px">' + 77 '<label for="daterangepicker_end">' + this.locale.toLabel + '</label>' + 78 '<input class="input-mini" type="text" name="daterangepicker_end" value="" disabled="disabled" />' + 79 '</div>' + 80 '<button class="btn btn-small btn-success" disabled="disabled">' + this.locale.applyLabel + '</button>' + 81 '</div>' + 82 '</div>' + 83 '</div>'; 84 85 //the date range picker 86 this.container = $(DRPTemplate).appendTo('body'); 87 88 89 if (hasOptions) { 90 if (typeof options.ranges == 'object') { 91 for (var range in options.ranges) { 92 93 var start = options.ranges[range][0]; 94 var end = options.ranges[range][1]; 95 96 if (typeof start == 'string') 97 start = Date.parse(start); 98 if (typeof end == 'string') 99 end = Date.parse(end); 100 101 this.ranges[range] = [start, end]; 102 } 103 104 var list = '<ul>'; 105 for (var range in this.ranges) { 106 list += '<li>' + range + '</li>'; 107 } 108 list += '<li>' + this.locale.customRangeLabel + '</li>'; 109 list += '</ul>'; 110 this.container.find('.ranges').prepend(list); 111 } 112 113 if (typeof options.format == 'string') 114 this.format = options.format; 115 116 if (typeof options.startDate == 'string') 117 this.startDate = Date.parse(options.startDate, this.format); 118 119 if (typeof options.endDate == 'string') 120 this.endDate = Date.parse(options.endDate, this.format); 121 122 123 if (typeof options.opens == 'string') 124 this.opens = options.opens; 125 } 126 127 if (this.opens == 'right') { 128 //swap calendar positions 129 var left = this.container.find('.calendar.left'); 130 var right = this.container.find('.calendar.right'); 131 left.removeClass('left').addClass('right'); 132 right.removeClass('right').addClass('left'); 133 } 134 135 if (typeof options == 'undefined' || typeof options.ranges == 'undefined') 136 this.container.find('.calendar').show(); 137 138 if (typeof cb == 'function') 139 this.cb = cb; 140 141 this.container.addClass('opens' + this.opens); 142 143 //event listeners 144 this.container.on('mousedown', $.proxy(this.mousedown, this)); 145 this.container.find('.calendar').on('click', '.prev', $.proxy(this.clickPrev, this)); 146 this.container.find('.calendar').on('click', '.next', $.proxy(this.clickNext, this)); 147 this.container.find('.ranges').on('click', 'button', $.proxy(this.clickApply, this)); 148 149 this.container.find('.calendar').on('click', 'td', $.proxy(this.clickDate, this)); 150 this.container.find('.calendar').on('mouseenter', 'td', $.proxy(this.enterDate, this)); 151 this.container.find('.calendar').on('mouseleave', 'td', $.proxy(this.updateView, this)); 152 153 this.container.find('.ranges').on('click', 'li', $.proxy(this.clickRange, this)); 154 this.container.find('.ranges').on('mouseenter', 'li', $.proxy(this.enterRange, this)); 155 this.container.find('.ranges').on('mouseleave', 'li', $.proxy(this.updateView, this)); 156 157 this.element.on('keyup', $.proxy(this.updateFromControl, this)); 158 159 this.updateView(); 160 this.updateCalendars(); 161 162 }; 163 164 DateRangePicker.prototype = { 165 166 constructor: DateRangePicker, 167 168 mousedown: function (e) { 169 e.stopPropagation(); 170 e.preventDefault(); 171 }, 172 173 updateView: function () { 174 this.leftCalendar.month.set({ month: this.startDate.getMonth(), year: this.startDate.getFullYear() }); 175 this.rightCalendar.month.set({ month: this.endDate.getMonth(), year: this.endDate.getFullYear() }); 176 177 this.container.find('input[name=daterangepicker_start]').val(this.startDate.toString(this.format)); 178 this.container.find('input[name=daterangepicker_end]').val(this.endDate.toString(this.format)); 179 180 if (this.startDate.equals(this.endDate) || this.startDate.isBefore(this.endDate)) { 181 this.container.find('button').removeAttr('disabled'); 182 } else { 183 this.container.find('button').attr('disabled', 'disabled'); 184 } 185 }, 186 187 updateFromControl: function () { 188 if (!this.element.is('input')) return; 189 190 var dateString = this.element.val().split(" - "); 191 var start = Date.parseExact(dateString[0], this.format); 192 var end = Date.parseExact(dateString[1], this.format); 193 194 if (start == null || end == null) return; 195 if (end.isBefore(start)) return; 196 197 this.startDate = start; 198 this.endDate = end; 199 200 this.updateView(); 201 this.cb(this.startDate, this.endDate); 202 this.updateCalendars(); 203 }, 204 205 notify: function () { 206 this.updateView(); 207 208 if (this.element.is('input')) { 209 this.element.val(this.startDate.toString(this.format) + ' - ' + this.endDate.toString(this.format)); 210 } 211 this.cb(this.startDate, this.endDate); 212 }, 213 214 move: function () { 215 if (this.opens == 'left') { 216 this.container.css({ 217 top: this.element.offset().top + this.element.outerHeight(), 218 right: $(window).width() - this.element.offset().left - this.element.outerWidth(), 219 left: 'auto' 220 }); 221 } else { 222 this.container.css({ 223 top: this.element.offset().top + this.element.outerHeight(), 224 left: this.element.offset().left, 225 right: 'auto' 226 }); 227 } 228 }, 229 230 show: function (e) { 231 this.container.show(); 232 this.move(); 233 234 if (e) { 235 e.stopPropagation(); 236 e.preventDefault(); 237 } 238 239 this.changed = false; 240 241 $(document).on('mousedown', $.proxy(this.hide, this)); 242 }, 243 244 hide: function (e) { 245 this.container.hide(); 246 $(document).off('mousedown', this.hide); 247 248 if (this.changed) 249 this.notify(); 250 }, 251 252 enterRange: function (e) { 253 var label = e.target.innerHTML; 254 if (label == this.locale.customRangeLabel) { 255 this.updateView(); 256 } else { 257 var dates = this.ranges[label]; 258 this.container.find('input[name=daterangepicker_start]').val(dates[0].toString(this.format)); 259 this.container.find('input[name=daterangepicker_end]').val(dates[1].toString(this.format)); 260 } 261 }, 262 263 clickRange: function (e) { 264 var label = e.target.innerHTML; 265 if (label == this.locale.customRangeLabel) { 266 this.container.find('.calendar').show(); 267 } else { 268 var dates = this.ranges[label]; 269 270 this.startDate = dates[0]; 271 this.endDate = dates[1]; 272 273 this.leftCalendar.month.set({ month: this.startDate.getMonth(), year: this.startDate.getFullYear() }); 274 this.rightCalendar.month.set({ month: this.endDate.getMonth(), year: this.endDate.getFullYear() }); 275 this.updateCalendars(); 276 277 this.changed = true; 278 279 this.container.find('.calendar').hide(); 280 this.hide(); 281 } 282 }, 283 284 clickPrev: function (e) { 285 var cal = $(e.target).parents('.calendar'); 286 if (cal.hasClass('left')) { 287 this.leftCalendar.month.add({ months: -1 }); 288 } else { 289 this.rightCalendar.month.add({ months: -1 }); 290 } 291 this.updateCalendars(); 292 }, 293 294 clickNext: function (e) { 295 var cal = $(e.target).parents('.calendar'); 296 if (cal.hasClass('left')) { 297 this.leftCalendar.month.add({ months: 1 }); 298 } else { 299 this.rightCalendar.month.add({ months: 1 }); 300 } 301 this.updateCalendars(); 302 }, 303 304 enterDate: function (e) { 305 306 var title = $(e.target).attr('title'); 307 var row = title.substr(1, 1); 308 var col = title.substr(3, 1); 309 var cal = $(e.target).parents('.calendar'); 310 311 if (cal.hasClass('left')) { 312 this.container.find('input[name=daterangepicker_start]').val(this.leftCalendar.calendar[row][col].toString(this.format)); 313 } else { 314 this.container.find('input[name=daterangepicker_end]').val(this.rightCalendar.calendar[row][col].toString(this.format)); 315 } 316 317 }, 318 319 clickDate: function (e) { 320 var title = $(e.target).attr('title'); 321 var row = title.substr(1, 1); 322 var col = title.substr(3, 1); 323 var cal = $(e.target).parents('.calendar'); 324 325 if (cal.hasClass('left')) { 326 startDate = this.leftCalendar.calendar[row][col]; 327 endDate = this.endDate; 328 } else { 329 startDate = this.startDate; 330 endDate = this.rightCalendar.calendar[row][col]; 331 } 332 333 cal.find('td').removeClass('active'); 334 335 if (startDate.equals(endDate) || startDate.isBefore(endDate)) { 336 $(e.target).addClass('active'); 337 if (!startDate.equals(this.startDate) || !endDate.equals(this.endDate)) 338 this.changed = true; 339 this.startDate = startDate; 340 this.endDate = endDate; 341 } 342 }, 343 344 clickApply: function (e) { 345 this.hide(); 346 }, 347 348 updateCalendars: function () { 349 350 this.leftCalendar.calendar = this.buildCalendar(this.leftCalendar.month.getMonth(), this.leftCalendar.month.getFullYear()); 351 this.rightCalendar.calendar = this.buildCalendar(this.rightCalendar.month.getMonth(), this.rightCalendar.month.getFullYear()); 352 this.container.find('.calendar.left').html(this.renderCalendar(this.leftCalendar.calendar, this.startDate)); 353 this.container.find('.calendar.right').html(this.renderCalendar(this.rightCalendar.calendar, this.endDate)); 354 355 }, 356 357 buildCalendar: function (month, year) { 358 359 var firstDay = Date.today().set({ day: 1, month: month, year: year }); 360 var lastMonth = firstDay.clone().add(-1).day().getMonth(); 361 var lastYear = firstDay.clone().add(-1).day().getFullYear(); 362 363 var daysInMonth = Date.getDaysInMonth(year, month); 364 var daysInLastMonth = Date.getDaysInMonth(lastYear, lastMonth); 365 366 var dayOfWeek = firstDay.getDay(); 367 368 //initialize a 6 rows x 7 columns array for the calendar 369 var calendar = Array(); 370 for (var i = 0; i < 6; i++) { 371 calendar[i] = Array(); 372 } 373 374 //populate the calendar with date objects 375 var startDay = daysInLastMonth - dayOfWeek + 1; 376 if (dayOfWeek == 0) 377 startDay = daysInLastMonth - 6; 378 379 var curDate = Date.today().set({ day: startDay, month: lastMonth, year: lastYear }); 380 for (var i = 0, col = 0, row = 0; i < 42; i++, col++, curDate = curDate.clone().add(1).day()) { 381 if (i > 0 && col % 7 == 0) { 382 col = 0; 383 row++; 384 } 385 calendar[row][col] = curDate; 386 } 387 388 return calendar; 389 390 }, 391 392 renderCalendar: function (calendar, selected) { 393 394 var html = '<table class="table-condensed">'; 395 html += '<thead>'; 396 html += '<tr>'; 397 html += '<th class="prev"><i class="icon-arrow-left"></i></th>'; 398 html += '<th colspan="5">' + calendar[1][1].toString("MMMM yyyy") + '</th>'; 399 html += '<th class="next"><i class="icon-arrow-right"></i></th>'; 400 html += '</tr>'; 401 html += '<tr>'; 402 403 $.each(this.locale.daysOfWeek, function (index, dayOfWeek) { 404 html += '<th>' + dayOfWeek + '</th>'; 405 }); 406 407 html += '</tr>'; 408 html += '</thead>'; 409 html += '<tbody>'; 410 411 for (var row = 0; row < 6; row++) { 412 html += '<tr>'; 413 for (var col = 0; col < 7; col++) { 414 var cname = (calendar[row][col].getMonth() == calendar[1][1].getMonth()) ? '' : 'off'; 415 if (calendar[row][col].equals(selected)) 416 cname = 'active'; 417 var title = 'r' + row + 'c' + col; 418 html += '<td class="' + cname + '" title="' + title + '">' + calendar[row][col].getDate() + '</td>'; 419 } 420 html += '</tr>'; 421 } 422 423 html += '</tbody>'; 424 html += '</table>'; 425 426 return html; 427 428 } 429 430 }; 431 432 $.fn.daterangepicker = function (options, cb) { new DateRangePicker(this, options, cb); }; 433 434 } (window.jQuery);
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 |