/*********************************************************/ /* vlaCalendar version 2.1 for mootools release 1.2 */ /*********************************************************/ var vlaCalendar = new Class({ 'slideDuration': 500, 'fadeDuration': 500, 'transition': Fx.Transitions.Quart.easeOut, 'startMonday': false, 'filePath': '/script/mootools/vlaCalendar/inc/', 'defaultView': 'month', 'style': '', 'lang': 'pl', initialize: function(_container, _options) { //Add the provided options to this object by extending if(_options) Object.append(this, _options); this.loading = false; this.container = _container = $(_container); var _class = this; //Insert the base into the container and initialize elements var pars = 'defaultView='+ this.defaultView; if(this.picker) { if(typeOf(this.prefillDate) == 'object' && this.getInputDate(this.prefillDate)) pars += '&pickedDate='+ this.getInputDate(this.prefillDate); if(this.linkWithInput) pars += '&gotoPickedDate=1'; } this.u('base', pars, function() { _class.mainLoader = _container.getElement('div[class=container]'); _class.label = _container.getElement('span[class=label]'); _class.arrowLeft = _container.getElement('div[class=arrowLeft]'); _class.arrowRight = _container.getElement('div[class=arrowRight]'); _class.initializeCalendarFunctions(); //Prefill/load picker date elements if(_class.picker) { if(typeOf(_class.prefillDate) == 'object' && _class.getInputDate(_class.prefillDate)) _class.pick(_class.prefillDate); else if(_class.prefillDate == true) _class.pick(JSON.decode(_class.label.getProperty('date'))); } }, _container); }, initializeCalendarFunctions: function() { this.resetArrows(); //Retrieve data (label, timestamp etc) which are stored as a Json string in the table attribute summary var vars = JSON.decode(this.mainLoader.getElement('table').getProperty('summary')); var _class = this; //Change the label this.label.removeClass('noHover').set('html', vars.label) .onclick = vars.parent ? function() { _class.u(vars.parent, 'ts=' + vars.ts + '&parent=' + vars.current, function() { _class.fade() }) } : null; //Hide arrows if necessary and add arrow click events if(vars.hide_left_arrow) this.hideLeftArrow(); else if(vars.hide_right_arrow) this.hideRightArrow(); this.arrowLeft.onclick = function() { _class.u(vars.current, 'ts=' + vars.pr_ts, function() { _class.slideLeft() }) } this.arrowRight.onclick = function() { _class.u(vars.current, 'ts=' + vars.nx_ts, function() { _class.slideRight() }) } //Add cell click events var clickables = this.mainLoader.getElements('td'); switch(vars.current) { case 'month': if(this.picker) { clickables.each(function(_clickable) { _clickable.onclick = function() { _class.pick(JSON.decode(_clickable.getProperty('date'))); _class.mainLoader.getElements('td').each(function(_clickable) { _clickable.removeClass('selected') }); this.addClass('selected'); } }); } break; case 'year': clickables.each(function(_clickable) { _clickable.onclick = function() { _class.u('month', 'ts=' + _clickable.getProperty('ts'), function() { _class.fade() }) } }); break; case 'decade': this.label.addClass('noHover'); clickables.each(function(_clickable) { _clickable.onclick = function() { _class.u('year', 'ts=' + _clickable.getProperty('ts') + '&m_ts=' + _clickable.getProperty('m_ts'), function() { _class.fade() }) } }); break; } }, //Ajax updater function which handles all requests u: function(_url, _pars, _onComplete, _id) { if(!this.loading && !this.transitioning) { var _class = this; this.loading = true; var element = $(_id ? _id : this.mainLoader); _pars += '&picker=' + (this.picker ? 1 : 0) + '&startMonday=' + (this.startMonday ? 1 : 0) + '&style=' + this.style + '&lang=' + this.lang; if(this.picker && this.getInputDate()) _pars += '&pickedDate='+ this.getInputDate(); new Request({ method: 'post', url: this.filePath + _url + '.php', onComplete: function(data) { element.set('html', data); _onComplete(); _class.loading = false; } }).send(_pars); } }, slideLeft: function() { var _class = this; this.initializeCalendarFunctions(); }, slideRight: function() { var _class = this; this.initializeCalendarFunctions(); }, fade: function(overRuleTrans) { var _class = this; this.initializeCalendarFunctions(); }, resetArrows: function() { this.arrowLeft.setStyle('visibility', 'visible'); this.arrowRight.setStyle('visibility', 'visible'); }, hideLeftArrow: function() { this.arrowLeft.setStyle('visibility', 'hidden'); }, hideRightArrow: function() { this.arrowRight.setStyle('visibility', 'hidden'); } }); var vlaDatePicker = new Class({ Extends: vlaCalendar, 'separateInput': false, 'prefillDate': true, 'linkWithInput': true, 'leadingZero': true, 'twoDigitYear': false, 'separator': '/', 'format': 'd/m/y', 'openWith': null, 'alignX': 'right', 'alignY': 'inputTop', 'offset': { 'x': 0, 'y': 0 }, 'style': '', 'ieTransitionColor' : '#ffffff', 'toggleDuration': 350, initialize: function(_element, _options) { //Add the provided options to this object by extending if(_options) Object.append(this, _options); this.element = $(_element); if(!this.element) throw 'No (existing) element to create a datepicker for specified: new vlaDatePicker(ELEMENT, [options])'; //Check if the user wants multiple input if(this.separateInput) { this.element.day = this.element.getElement('input[name='+ this.separateInput.day +']'); this.element.month = this.element.getElement('input[name='+ this.separateInput.month +']'); this.element.year = this.element.getElement('input[name='+ this.separateInput.year +']'); } //Create the picker and calendar and inject in in the body this.picker = new Element('div', { 'class': 'vlaCalendarPicker' + (this.style != '' ? ' ' + this.style : '') }).inject($(document.body),'top'); this.pickerContent = new Element('div', { 'class': 'pickerBackground' }).inject(this.picker,'top'); this.parent(this.pickerContent); //Add events for showing and hiding the picker var _class = this; (this.openWith ? $(this.openWith) : this.element) .addEvent('focus', function() { _class.show(); }) .addEvent('click', function() { _class.openWith ? _class.toggle() : _class.show() }) .addEvent('change', function() { _class.hide(); }); //If the datepicker is visible an outside click makes it hide document.addEvent('mousedown', function(e) { if(_class.outsideHide && _class.outsideClick(e, _class.picker)) { _class.hide(); } }); document.addEvent('keydown', function(e) { if(_class.outsideHide && _class.outsideClick(e, _class.picker)) { _class.hide(); } }); //_class.hide() //linkWithInput if(this.linkWithInput) { if(this.separateInput) { this.element.day.addEvent('keyup', function() { _class.linkedUpdate() }); this.element.month.addEvent('keyup', function() { _class.linkedUpdate() }); this.element.year.addEvent('keyup', function() { _class.linkedUpdate() }); } else { this.element.addEvent('keyup', function() { _class.linkedUpdate() }); } } this.visible = false; this.outsideHide = false; }, //Position the picker position: function() { var top, left; switch(this.alignX) { case 'left': left = this.element.getLeft(); break; case 'center': var pickerMiddle = this.pickerContent.getStyle('width').toInt() / 2; if(pickerMiddle == 0) pickerMiddle = 83; left = this.element.getLeft() + (this.element.getSize().x / 2) - pickerMiddle - ((parseInt(this.pickerContent.getStyle('padding-left')) + parseInt(this.pickerContent.getStyle('padding-right'))) / 2); break; case 'right': default: left = this.element.getLeft() + this.element.getSize().x; break; } switch(this.alignY) { case 'bottom': top = this.getPos(this.element).y + this.element.getSize().y; break; case 'top': top = this.getPos(this.element).y - parseInt(this.pickerContent.getStyle('height')) - (parseInt(this.pickerContent.getStyle('padding-top')) + parseInt(this.pickerContent.getStyle('padding-bottom'))); break; case 'inputTop': default: top = this.getPos(this.element).y; } if(this.isNumber(this.offset.x)) left += this.offset.x; if(this.isNumber(this.offset.y)) top += this.offset.y; this.picker.setStyles({ 'top': top, 'left': left }); }, show: function() { this.position(); if(!this.visible) { this.visible = true; var _class = this; this.picker.setStyles({ 'opacity': 1, 'display': 'inline' }); _class.outsideHide = true; } }, hide: function() { if(this.visible) { this.visible = false; var _class = this; _class.picker.setStyle('display', 'none'); _class.outsideHide = false; } }, toggle: function() { if(this.visible) this.hide(); else this.show(); }, pick: function(_date) { if(this.leadingZero) { if(_date.day < 10) _date.day = '0' + _date.day; if(_date.month < 10) _date.month = '0' + _date.month; } if(this.twoDigitYear) _date.year = _date.year.toString().substring(2, 4); if(this.separateInput) { if(this.element.day) this.element.day.set('value', _date.day); if(this.element.month) this.element.month.set('value', _date.month); if(this.element.year) this.element.year.set('value', _date.year); this.hide(); } else { switch(this.format) { case "m/d/y": this.element.set('value', _date.month + this.separator + _date.day + this.separator + _date.year); break; case "y/m/d": this.element.set('value', _date.year + this.separator + _date.month + this.separator + _date.day); break; case "y/d/m": this.element.set('value', _date.year + this.separator + _date.day + this.separator + _date.month); break; case "d/m/y": default: this.element.set('value', _date.day + this.separator + _date.month + this.separator + _date.year); } this.hide(); } this.element.fireEvent('change'); }, getInputDate: function(_date) { var day, month, year; if(_date) { day = _date.day; month = _date.month; year = _date.year; } else if(this.separateInput) { day = this.element.day.get('value').toInt(); month = this.element.month.get('value').toInt(); year = this.element.year.get('value').toInt(); } else { var date = this.element.get('value').split(this.separator); if(date.length != 3) return null; switch(this.format) { case "m/d/y": day = date[1]; month = date[0]; year = date[2]; break; case "y/m/d": day = date[2]; month = date[1]; year = date[0]; break; case "y/d/m": day = date[1]; month = date[2]; year = date[0]; break; case "d/m/y": default: day = date[0]; month = date[1]; year = date[2]; } } if( !this.isNumber(day) || !this.isNumber(month) || !this.isNumber(year) || day == 0 || month == 0 || year == '0' || (this.twoDigitYear && year > 99) || (!this.twoDigitYear && year < 1979) || (!this.twoDigitYear && year > 2030) || month > 12 || day > 31 ) return null; if(this.twoDigitYear && this.isNumber(year) && year < 100) { year = year.toInt(); if(year < 10) year = '200'+ year; else if(year < 70) year = '20'+ year; else if(year > 69) year = '19'+ year; else year = new Date().getFullYear(); } return day +'/'+ month +'/'+ year; }, //This function is being called on keyup event if linkWithInput is set to true and when a date is picked //If the full date is inserted the picker will change itself to that specific date (month view) linkedUpdate: function() { var _class = this; var date = this.getInputDate(); if(date && this.pickedDate != date) { this.u('month', 'gotoPickedDate=1', function() { _class.fade(true) }); this.pickedDate = date; } }, outsideClick: function(_event, _element) { var mousePos = this.getMousePos(_event); var elementData = _element.getCoordinates(); return (mousePos.x > elementData.left && mousePos.x < (elementData.left + elementData.width)) && (mousePos.y > elementData.top && mousePos.y < (elementData.top + elementData.height)) ? false : true; }, getMousePos: function(_event) { if(document.all) { return { 'x': window.event.clientX + window.getScrollLeft(), 'y': window.event.clientY + window.getScrollTop() }; } else { return { 'x': _event.page['x'], 'y': _event.page['y'] }; } }, isNumber: function(_number) { if(_number == '') return false; return (_number >= 0) || (_number < 0) ? true : false; }, //Retrieving positition funtions (like getCoordinates, getTop etc) don't seem to return correct values in some situations in mootools 1.2; //Opera returns wrong values, IE returns too small values. This function returns the correct coordinates. getPos: function(_element) { var x, y = 0; if(_element.offsetParent) { do { x += _element.offsetLeft; y += _element.offsetTop; } while(_element = _element.offsetParent); } else if(_element.x) { x += _element.x; y += _element.y; } return { 'x': x, 'y': y }; } });