// DateSelector Class v1 // Author: Serge I. Zolotukhin ( serge@design.ru, http://serge.design.ru/ ) // Updated: 2003-04-21 /* * Constructor */ function DateSelector( sName, sValue, sPath ) { var oSelf = this // Путь к картинкам this.sClassPath = sPath // Нода из BuildSelector() this.oSelector = null // Название месяцев this.aMonths = new Array('Январь', 'Февраль', 'Март', 'Апрель', 'Май', 'Июнь', 'Июль', 'Август', 'Сентябрь', 'Октябрь', 'Ноябрь', 'Декабрь'); this.bMonths = new Array ('января', 'февраля', 'марта', 'апреля', 'мая', 'июня', 'июля', 'августа', 'сентября', 'октября', 'ноября', 'декабря'); // Корневой элемент контрола this.oNode = document.createElement('table') this.oNode.className = 'DS_Control' // input[@type='text'] в документе this.oInput = this.oNode.insertRow(-1).insertCell(-1).appendChild( this.CreateElement('input', 'text') ) this.oInput.parentNode.style.borderRightWidth = '0' this.oInput.name = sName + '_INPUT' this.oInput.value = sValue this.oInput.onblur = function() { oSelf.ParseStrToValue(oSelf.oInput.value) } this.oInput.onclick = function() { oSelf.HideSelector() } // Кнопка this.oButton = this.oNode.rows[this.oNode.rows.length-1].insertCell(-1).appendChild( document.createElement('div') ) this.oButton.parentNode.style.borderLeftWidth = '0' this.oButton.appendChild( document.createElement('img') ) this.oButton.lastChild.src = this.sClassPath + 'dateselector_ar-d.gif' this.oButton.onclick = function(oEvent) { if( !oSelf.oSelector ) { oSelf.ShowSelector(oSelf.iYear, oSelf.iMonth) } else { oSelf.HideSelector() } try { event.cancelBubble = true } catch (oException) { oEvent.stopPropagation() } } // input[@type='hidden'] в документе this.oHidden = this.oNode.lastChild.lastChild.lastChild.appendChild( this.CreateElement('input', 'hidden') ) this.oHidden.name = sName // Автозакрывание селектора document.onclick = function() { oSelf.HideSelector() } // Текущее значение даты this.ParseStrToValue(this.oInput.value) this.sClientName = this.GetClientName() return this } /* * Private */ // Установить внутренние значения даты DateSelector.prototype.SetValue = function( iYear, iMonth, iDay ) { if( ( (iYear > 9 && iYear < 100) || (iYear > 999 && iYear < 10000) ) && ( iMonth > 0 && iMonth < 13 ) && ( iDay <= this.GetDaysCountByMonth(iYear, iMonth) ) ) { this.iYear = iYear this.iMonth = iMonth this.iDay = iDay //this.oInput.value = iDay + ' ' + this.bMonths[iMonth-1].toLowerCase() + ' ' + iYear; //substr(0,3) this.oInput.value = iDay + '.' + iMonth + '.' + iYear; //substr(0,3) this.oHidden.value = iYear + '-' + iMonth + '-' + iDay } else { this.oInput.value = this.iDay + '.' + this.iMonth + '.' + this.iYear; //substr(0,3) //this.oInput.value = this.iDay + ' ' + this.aMonths[this.iMonth-1].toLowerCase() + ' ' + this.iYear; //substr(0,3) this.oHidden.value = this.iYear + '-' + this.iMonth + '-' + this.iDay } } // Отпарсить строку и попробовать получить три int: iYear, iMonth, iDay DateSelector.prototype.ParseStrToValue = function( sStr ) { var re, aResult // '2003-4-16' re = /^(\d{2,4})\-(\d{1,2})\-(\d{1,2})$/ aResult = re.exec(sStr) if( aResult ) { this.SetValue( aResult[1], aResult[2], aResult[3] ) return true } // '16.4.2003', '16/4/2003', '16 4 2003' re = /^(\d{1,2})[\.\/\s](\d{1,2})[\.\/\s](\d{2,4})$/ aResult = re.exec(sStr) if( aResult ) { this.SetValue( aResult[3], aResult[2], aResult[1] ) return true } // '16-апр-2003', '16 апр 2003' re = /^(\d{1,2})[\s\.\-]([a-я]+)[\s\.\-](\d{2,4})$/i aResult = re.exec(sStr) if( aResult ) { for( var i=0; i 12 ) ? Math.abs( iMonth-12 ) : iMonth } // Вернуть "правильное" значение года по месяцу, т.е. вместо 2003(13) -- 2004(1) DateSelector.prototype.GetYearNumber = function( iYear, iMonth ) { if ( iMonth < 1 ) return ( iYear-1 ) if ( iMonth > 12 ) return ( parseInt(iYear)+1 ) return iYear } // Приделать ноду с Selector к контролу DateSelector.prototype.ShowSelector = function( iYear, iMonth ) { if ( !this.oSelector ) { this.oButton.className = 'Pushed' this.oSelector = this.BuildSelector( this.BuildYearMonthSelector(iYear, iMonth), this.BuildDaySelector(iYear, iMonth) ) this.oNode.parentNode.appendChild( this.oSelector ) } } // Убить ноду с Selector DateSelector.prototype.HideSelector = function() { if ( this.oSelector && this.oSelector.parentNode ) { this.oButton.className = '' this.oSelector.parentNode.removeChild(this.oSelector) this.oSelector = null } } // "Перерисовать" ноду с Selector к контролу DateSelector.prototype.RedrawSelector = function( iYear, iMonth ) { this.HideSelector() this.ShowSelector(iYear, iMonth) } // Сгенерить ноду с выбором даты DateSelector.prototype.BuildSelector = function( oYearMonthSelector, oDaySelector ) { var oNode = document.createElement('div') oNode.appendChild( document.createElement('fieldset') ) oNode.lastChild.appendChild(oYearMonthSelector) oNode.lastChild.appendChild(oDaySelector) oNode.className = 'DS_Selector' // Эта заплатка сделана потому, что Moz и MSIE по-разному трактуют CSS oNode.style.width = ( this.sClientName == 'msie' ) ? '1%' : '' return oNode } // Сгенерить ноду с выбором месяца и года. Текущие значения установить в iYear, iMonth // Такая замороченная нода получилась coz of moz DateSelector.prototype.BuildYearMonthSelector = function( iYear, iMonth ) { var oCurrentRow, oNode var oSelf = this oNode = document.createElement('div') oNode.className = 'DS_YearmonthSelector' oNode.appendChild( document.createElement('table') ) oCurrentRow = oNode.lastChild.insertRow(-1) oCurrentRow.insertCell(-1).appendChild( document.createElement('img') ) oCurrentRow.lastChild.lastChild.src = this.sClassPath + 'dateselector_ar-l.gif' oCurrentRow.lastChild.lastChild.alt = this.aMonths[ this.GetMonthNumber(iMonth-1) - 1 ] + ' ' + this.GetYearNumber(iYear, iMonth-1) oCurrentRow.lastChild.lastChild.setAttribute('month', this.GetMonthNumber(iMonth-1)) oCurrentRow.lastChild.lastChild.setAttribute('year', this.GetYearNumber(iYear, iMonth-1)) oCurrentRow.lastChild.lastChild.onclick = function() { oSelf.RedrawSelector( this.getAttribute('year'), this.getAttribute('month') ) } oCurrentRow.insertCell(-1).appendChild( document.createTextNode( this.aMonths[iMonth-1] + ' ' + iYear ) ) oCurrentRow.lastChild.style.textAlign = 'center' oCurrentRow.insertCell(-1).appendChild( document.createElement('img') ) oCurrentRow.lastChild.style.textAlign = 'right' oCurrentRow.lastChild.lastChild.src = this.sClassPath + 'dateselector_ar-r.gif' oCurrentRow.lastChild.lastChild.alt = this.aMonths[ this.GetMonthNumber(parseInt(iMonth)+1) - 1 ] + ' ' + this.GetYearNumber(iYear, parseInt(iMonth)+1) oCurrentRow.lastChild.lastChild.setAttribute('month', this.GetMonthNumber(parseInt(iMonth)+1)) oCurrentRow.lastChild.lastChild.setAttribute('year', this.GetYearNumber(iYear, parseInt(iMonth)+1)) oCurrentRow.lastChild.lastChild.onclick = function() { oSelf.RedrawSelector( this.getAttribute('year'), this.getAttribute('month') ) } return oNode } // Сгенерить ноду с выбором дня месяца iMonth года iYear DateSelector.prototype.BuildDaySelector = function( iYear, iMonth ) { var oNode, i, j, oCurrentRow var oSelf = this var aDayOfWeekTitles = new Array('пн','вт','ср','чт','пт','сб','вс') var dFirstDay = new Date(iYear,iMonth-1,0) var iDaysCount = this.GetDaysCountByMonth(iYear,iMonth) oNode = document.createElement('table') oNode.className = 'DS_DaySelector' // Нужно отбить позицию до требумого дня недели oCurrentRow = oNode.insertRow(-1) for ( i=0; i') } else { var oElement = document.createElement(sNodeName) oElement.setAttribute('type', sTypeAttr) return oElement } }