You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1 line
13 KiB
JavaScript

class AbstractSmartDatePart{constructor(a,b){this._state=AbstractSmartDatePart.STATE_NONE,this._cleanedValue="",this._parsedValue="",this._scanned="",this._placeholder=a,this._static=b}state(){return this._state}isNoState(){return this._state===AbstractSmartDatePart.STATE_NONE}isIncomplete(){return this._state===AbstractSmartDatePart.STATE_INCOMPLETE}isComplete(){return this._state===AbstractSmartDatePart.STATE_COMPLETE}resetState(){this._state=AbstractSmartDatePart.STATE_NONE}cleanedValue(){return this._cleanedValue}parsedValue(){return this._parsedValue}placeHolder(){return this._placeholder}isStatic(){return this._static}_isNumericSymbol(a){return"0"<=a&&"9">=a}check(a){return!1}}AbstractSmartDatePart.STATE_NONE=0,AbstractSmartDatePart.STATE_INCOMPLETE=1,AbstractSmartDatePart.STATE_COMPLETE=2;class SmartDateStaticPart extends AbstractSmartDatePart{constructor(a){super(a,!0),this._cleanedValue=a}parse(a){let b=a.value(),c=a.valueIndex();for(;c<b.length&&!this._isNumericSymbol(b[c]);)c++;return this._parsedValue=b.substring(a.valueIndex(),c),this._state=AbstractSmartDatePart.STATE_COMPLETE,a.setValueIndex(c),!0}}class AbstractSmartDateNumericPart extends AbstractSmartDatePart{constructor(a,b){super(a,!1),this._numericValue=0,this._size=b}numericValue(){return this._numericValue}formatDate(a){return""}formatValue(a){let b=this._correctValue(a)+"";return"0"==b?b:b.length>this._size?b.substring(0,this._size):b.length<this._size?b.padStart(this._size,"0"):b}_correctValue(a){return Math.round(a)}scanStringNumber(a){let b=a.valueIndex(),c=a.value();for(;b<c.length&&this._isNumericSymbol(c[b]);)b++;let d=c.substring(a.valueIndex(),b);return a.setValueIndex(b),d}calculateNumericValue(a,b){for(var c=0,d=0,e=0;c<a.length&&0===a[c];)c++;for(d=c;d<a.length&&e<b;)e=10*e+ +a[d],d++;return e>b&&d--,+a.substring(c,d)}scanValue(a,b){let c=a.valueIndex(),d=a.value(),e=0;for(;c<d.length&&this._isNumericSymbol(d[c])&&e<b;)e=10*e+ +d[c],c++;e>b&&c--;let f=d.substring(a.valueIndex(),c);return a.setValueIndex(c),f}_defineParsingState(a,b){return 0<this._numericValue&&(this._parsedValue.length>=this._size||!b)?void(this._state=AbstractSmartDatePart.STATE_COMPLETE):10*this._numericValue>a?void(this._state=AbstractSmartDatePart.STATE_COMPLETE):void(this._state=AbstractSmartDatePart.STATE_INCOMPLETE)}_defineCleanValue(){return this._cleanedValue="",this.isNoState()?void 0:this.isComplete()?void(this._cleanedValue=this.formatValue(this._numericValue)):void(0<this._parsedValue.length&&(this._cleanedValue=this._numericValue+""))}}class SmartDateDayPart extends AbstractSmartDateNumericPart{constructor(){super(SmartDateFormat.DAY_PLACEHOLDER,2),this.maximalValue=SmartDateDayPart.MAXIMAL_VALUE}resetState(){super.resetState(),this.maximalValue=SmartDateDayPart.MAXIMAL_VALUE}setMaximalValue(a){a!=a||a<SmartDateDayPart.MAXIMAL_VALUE_LOW_LIMIT||SmartDateDayPart.MAXIMAL_VALUE_HIGH_LIMIT<a||(this.maximalValue=a,this._numericValue<=this.maximalValue||(this._numericValue=this.maximalValue,this._defineCleanValue()))}resetMaximalValue(){this.maximalValue=SmartDateDayPart.MAXIMAL_VALUE}formatDate(a){return this.formatValue(a.getDate())}parse(a){this._parsedValue=this.scanStringNumber(a),this._numericValue=this.calculateNumericValue(this._parsedValue,this.maximalValue),this._defineParsingState(this.maximalValue,a.isOver()),this._defineCleanValue()}}SmartDateDayPart.MAXIMAL_VALUE_LOW_LIMIT=28,SmartDateDayPart.MAXIMAL_VALUE_HIGH_LIMIT=31,SmartDateDayPart.MAXIMAL_VALUE=SmartDateDayPart.MAXIMAL_VALUE_HIGH_LIMIT;class SmartDateMonthPart extends AbstractSmartDateNumericPart{constructor(){super(SmartDateFormat.MONTH_PLACEHOLDER,2)}formatDate(a){return this.formatValue(a.getMonth()+1)}parse(a){this._parsedValue=this.scanStringNumber(a),this._numericValue=this.calculateNumericValue(this._parsedValue,SmartDateMonthPart.MAXIMAL_VALUE),this._defineParsingState(SmartDateMonthPart.MAXIMAL_VALUE,a.isOver()),this._defineCleanValue()}}SmartDateMonthPart.MAXIMAL_VALUE=12;class SmartDateYearPart extends AbstractSmartDateNumericPart{constructor(){super(SmartDateFormat.YEAR_PLACEHOLDER,4)}formatDate(a){return this.formatValue(a.getFullYear())}parse(a){this._parsedValue=this.scanStringNumber(a),this._numericValue=+this._parsedValue,this._defineParsingState(),this._numericValue>SmartDateYearPart.MAXIMAL_VALUE&&(this._numericValue=SmartDateYearPart.MAXIMAL_VALUE),this.isComplete()&&this._numericValue<SmartDateYearPart.MINIMAL_VALUE&&(this._numericValue=SmartDateYearPart.MINIMAL_VALUE),this._defineCleanValue()}_defineParsingState(){return 0<this._numericValue&&this._parsedValue.length>=this._size?void(this._state=AbstractSmartDatePart.STATE_COMPLETE):void(this._state=AbstractSmartDatePart.STATE_INCOMPLETE)}_defineCleanValue(){this._cleanedValue=0<this._numericValue?this._numericValue+"":""}}SmartDateYearPart.MINIMAL_VALUE=1e3,SmartDateYearPart.MAXIMAL_VALUE=9999;class SmartDateParseState{constructor(){this._value="",this._valueIndex=0}start(a){this._value=a,this._valueIndex=0}current(){return this.isOver()?"":this._value[this._valueIndex]}next(){return!this.isOver()&&(this._valueIndex++,!this.isOver())}isOver(){return this._valueIndex>=this._value.length}value(){return this._value}valueIndex(){return this._valueIndex}setValueIndex(a){this._valueIndex<a&&(this._valueIndex=a)}}class SmartDateFormat{constructor(a){this._day=null,this._month=null,this._year=null,this.loadFormat(a),this._parseState=new SmartDateParseState}loadFormat(a){let b=0,c=a.toLowerCase();for(this._format=a,this._parts=[];b<a.length;)b=this._scanPart(b,a,c)}_scanPart(a,b,c){switch(c[a]){case SmartDateFormat.DAY_ANCHOR:return this._scanDay(a,c);case SmartDateFormat.MONTH_ANCHOR:return this._scanMonth(a,c);case SmartDateFormat.YEAR_ANCHOR:return this._scanYear(a,c);}return this._scanStatic(a,b,c)}_scanDay(a,b){return this._checkLastIsStatic(),this._day=new SmartDateDayPart,this._parts.push(this._day),this._avoidAnchor(SmartDateFormat.DAY_ANCHOR,a,b)}_scanMonth(a,b){return this._checkLastIsStatic(),this._month=new SmartDateMonthPart,this._parts.push(this._month),this._avoidAnchor(SmartDateFormat.MONTH_ANCHOR,a,b)}_scanYear(a,b){return this._checkLastIsStatic(),this._year=new SmartDateYearPart,this._parts.push(this._year),this._avoidAnchor(SmartDateFormat.YEAR_ANCHOR,a,b)}_avoidAnchor(a,b,c){let d=b;for(;d<c.length&&c[d]===a;)d++;return d}_checkLastIsStatic(){if(0!==this._parts.length&&!this._parts[this._parts.length-1].isStatic())throw new Error("Dynamic date parts must be separated by static substrings")}_scanStatic(a,b,c){let d=a;for(;d<b.length&&this._isStaticAnchorSymbol(c[d]);)d++;return this._parts.push(new SmartDateStaticPart(b.substring(a,d))),d}_isStaticAnchorSymbol(a){return a!==SmartDateFormat.DAY_ANCHOR&&a!==SmartDateFormat.MONTH_ANCHOR&&a!==SmartDateFormat.YEAR_ANCHOR}getPlaceHolder(){let a="";for(let b=0;b<this._parts.length;b++)a+=this._parts[b].placeHolder();return a}formatDate(a){var b="";for(let c=0;c<this._parts.length;c++)b+=this._parts[c].isStatic()?this._parts[c].placeHolder():this._parts[c].formatDate(a);return b}parse(a,b){this._resetParseState(),this._parseState.start(a),this._parseParts(b),this._correctDate()}_resetParseState(){for(let a=0;a<this._parts.length;a++)this._parts[a].resetState()}_parseParts(a){for(let b=0;b<this._parts.length&&(a||!this._parseState.isOver());){if(this._parts[b].parse(this._parseState),!this._parts[b].isComplete())return;b++}}_correctDate(){this._day.isComplete()&&this._month.isComplete()&&this._day.setMaximalValue(this._getMonthSize(this._month.numericValue()-1,!this._year.isComplete()||this._isLeaPYear(this._year.numericValue())))}getParsedDate(){return this.isComplete()?new Date(this._year.numericValue(),this._month.numericValue()-1,this._day.numericValue()):null}_getMonthSize(a,b){return 0>a||a>=SmartDateMonthPart.MAXIMAL_VALUE?SmartDateMonthPart.MAXIMAL_VALUE:1===a&&b?SmartDateFormat.BASIC_MONTH_SIZES[a]+1:SmartDateFormat.BASIC_MONTH_SIZES[a]}_isLeaPYear(a){return 0==a%4&&(0!=a%100||0==a%400)}getCorrectedValue(){let a=0,b="";for(;a<this._parts.length&&!this._parts[a].isNoState();)b+=this._parts[a].cleanedValue(),a++;return b}isComplete(){return this._parts[this._parts.length-1].isComplete()}}SmartDateFormat.DAY_ANCHOR="d",SmartDateFormat.DAY_PLACEHOLDER="\u0414\u0414",SmartDateFormat.MONTH_ANCHOR="m",SmartDateFormat.MONTH_PLACEHOLDER="\u041C\u041C",SmartDateFormat.YEAR_ANCHOR="y",SmartDateFormat.YEAR_PLACEHOLDER="\u0413\u0413\u0413\u0413",SmartDateFormat.BASIC_MONTH_SIZES=[31,28,31,30,31,30,31,31,30,31,30,31];class SmartDateField{constructor(a,b){this._dateYmdParser=/^([0-9]{4})[,._\/-]+([0-9]{1,2})[,._\/-]+([0-9]{1,2})$/,this._dateDmyParser=/^([0-9]{1,2})[,._\/-]+([0-9]{1,2})[,._\/-]+([0-9]{4})$/,this._loadOptions(b),this._formatter=new SmartDateFormat(this._format,this._minimalDate,this._maximalDate),this._lastCorrectValue=null===this._defaultDate?null:this._formatter.formatDate(this._defaultDate),this._initField(a),this._subscribeEvents()}_loadDefaultOptions(){this._format="d.m.y",this._minimalDate=new Date(1900,0,1),this._maximalDate=new Date(2099,11,31),this._defaultDate=null}_loadOptions(a){if(this._loadDefaultOptions(),"object"==typeof a&&null!=a){if("string"==typeof a.format&&0<=a.format.indexOf("d")&&0<=a.format.indexOf("m")&&0<=a.format.indexOf("y")&&(this._format=a.format),"undefined"!=typeof a.minimal){let b=this._parseDateValue(a.minimal);this._minimalDate=b}if("undefined"!=typeof a.maximal){let b=this._parseDateValue(a.maximal);this._maximalDate=b}if("undefined"!=typeof a.default){let b=this._parseDateValue(a.default);this._defaultDate=b}this._correctDateOptions()}}_correctDateOptions(){if(this._minimalDate.valueOf()>this._maximalDate.valueOf()){let a=this._minimalDate;this._minimalDate=this._maximalDate,this._maximalDate=a}null===this._defaultDate||(this._defaultDate.valueOf()<this._minimalDate.valueOf()&&(this._defaultDate=this._minimalDate),this._defaultDate.valueOf()>this._maximalDate.valueOf()&&(this._defaultDate=this._maximalDate))}_parseDateValue(a){if("object"==typeof a&&null!==a&&a instanceof Date)return a;if("string"!=typeof a||""===a.trim())return null;let b=this._dateYmdParser.exec(a);return null===b?(b=this._dateDmyParser.exec(a),null===b?null:new Date(+b[3],+b[2]-1,+b[1])):new Date(+b[1],+b[2]-1,+b[3])}_initField(a){this._field=a,this._field.placeholder=this._formatter.getPlaceHolder(),this._isEmptyValue(this._field.value)?this._field.value=null===this._defaultDate?"":this._formatter.formatDate(this._defaultDate):this.correctValue(!0)}_subscribeEvents(){let a=this,b=function(b){(null===b||"keyup"!==b.type)&&a.correctValue(!0);a._isServiceCode(b.keyCode)||(27===b.keyCode&&a.returnLastCorrectValue(),a.correctValue(!0))};this._field.addEventListener("change",b),this._field.addEventListener("keyup",b),this._field.addEventListener("blur",function(){a.correctValue(!0),a._isEmptyValue(a._field.value)||a.returnLastCorrectValue()})}_isServiceCode(a){return 8===a||46===a||16===a||17===a||18===a||20===a||35===a||36===a||37===a||39===a||46===a}_isEmptyValue(a){return""===a.trim()}getDefaultValue(){return null===this._defaultDate?"":this._formatter.formatDate(this._defaultDate)}correctValue(a){this._formatter.parse(this._field.value,a);let b=this._getLimitedParsedValue();this._formatter.isComplete()&&(this._lastCorrectValue=b);this._field.value===b||this._setValueToField(b)}setValue(a){let b=this._parseDateValue(a);null===b||b.valueOf()<this._minimalDate.valueOf()||b.valueOf()>this._maximalDate.valueOf()||(this._lastCorrectValue=this._formatter.formatDate(b),this._field.value=this._lastCorrectValue)}_getLimitedParsedValue(){if(!this._formatter.isComplete())return this._formatter.getCorrectedValue();let a=this._formatter.getParsedDate();if(a.valueOf()<this._minimalDate.valueOf())return this._formatter.formatDate(this._minimalDate);return a.valueOf()>this._maximalDate.valueOf()?this._formatter.formatDate(this._maximalDate):this._formatter.getCorrectedValue()}_setValueToField(a){let b=this._field.selectionStart,c=b===this._field.value.length;this._field.value=a,!c&&b<this._field.value.length&&(this._field.selectionStart=b,this._field.selectionEnd=b)}returnLastCorrectValue(){null!==this._lastCorrectValue&&(this._field.value=this._lastCorrectValue)}}SmartDateField.initBy=function(a){return SmartDateField.initFor(document.getElementById(a))},SmartDateField.initFor=function(a,b){"object"!=typeof a||null===a||"input"!==a.tagName.toLowerCase()||"text"!==a.type.toLowerCase()||"object"==typeof a._smartDate&&null!==a._smartDate&&a._smartDate instanceof SmartDateField||(a._smartDate=new SmartDateField(a,b))},jQuery.fn.smartdate=function(a){let b=[],c=null;for(let d=0;d<this.length;d++)c=SmartDateField.initFor(this[d],a),null!==c&&b.push(c);return jQuery(this)},jQuery.fn.setDateValue=function(a){for(let b=0;b<this.length;b++)"object"==typeof this[b]._smartDate&&null!==this[b]._smartDate&&this[b]._smartDate instanceof SmartDateField&&this[b]._smartDate.setValue(a);return jQuery(this)};