/*Controls.Register(function() { inputs=$$('input.Masked'); for(i=0; i$1'); mask = mask + ' '; this.rightHalf.innerHTML = mask; }, OnBlur: function(evt) { this.OnInput(); HideTip(); var nSep; for (nSep = 0; nSep < this.mask.length && !this.IsSpecial(nSep); ++nSep) {} if (this.curValue.length <= nSep) { this.curValue = ''; this.input.value = this.curValue; } this.clearError(); this.UpdateHalves(); if(this.lastReported!=this.input.value) { new AEvent("CHANGE", {}, this); this.lastReported=this.input.value; } }, OnFocus: function(evt) { HideTip(); this.OnInput(); var nSep; for (nSep = 0; nSep < this.mask.length && !this.IsSpecial(nSep); ++nSep) {} if (this.curValue.length < nSep) { this.curValue = this.mask.substring(0, nSep); this.input.value = this.curValue; } this.UpdateHalves(); }, OnKeyDown: function(evt) { if (evt.altKey || evt.ctrlKey) return; var key = evt.keyCode; HideTip(); var p2 = getSelectionStart(this.input) var pos = getSelectionEnd(this.input); var ch; if (key == 27) { // escape evt.stop(); this.input.blur(); this.input.focus(); return; } else if (key == 8) { // backspace if (pos == 0 || p2 != pos) return; var nDeleted = 1; while (!this.IsSpecial(pos - nDeleted) && nDeleted < pos) { nDeleted++; } this.input.value = this.input.value.substring(0, pos - nDeleted) + this.input.value.substring(pos); setCaretPosition(this.input, pos - nDeleted); this.OnInput(); evt.stop(); return false; } else if (key == 46) { // delete if (pos == 0 || p2 != pos) return; var nDeleted = 1; while (!this.IsSpecial(pos + nDeleted - 1) && (pos + nDeleted <= this.input.value.length)) { nDeleted++; } var nDeletedOnLeft = 1; while (nDeletedOnLeft < pos) { if (this.IsSpecial(pos - nDeletedOnLeft)) { nDeletedOnLeft = 0; break; } nDeletedOnLeft++; } this.input.value = this.input.value.substring(0, pos - nDeletedOnLeft) + this.input.value.substring(pos + nDeleted); setCaretPosition(this.input, pos - nDeletedOnLeft); this.OnInput(); evt.stop(); return false; } if (!Prototype.Browser.WebKit) return this.OnKeyPress(evt); }, OnKeyPress: function(evt) { if (evt.altKey || evt.ctrlKey) return; var key = evt.keyCode; HideTip(); var pos = getSelectionEnd(this.input); if ((key > 46 || key == 0) && evt.which) { ch = String.fromCharCode(evt.which); if (this.ValidateAt(pos, ch) === -1) { evt.stop(); return false; } this.input.value = this.input.value + ch; setCaretPosition(this.input, pos + 1); this.OnInput(); evt.stop(); return false; } }, SetCaretPos: function(pos) { var num = 0; var i; for (i = this.input.value.length; i > 0; i--) { if (num == pos) break; if (this.IsSpecial(i - 1)) num++; } setCaretPosition(this.input, i); }, GetCaretPos: function() { // count of non-separators to the right of the caret var num = 0; var i; var sel = getSelectionEnd(this.input); var len = this.input.value.length; for (i = len - 1; i >= sel; i--) { if (this.IsSpecial(this.curValue.length + i - len)) num++; } return num; }, OnInput: function(evt) { var newVal = this.input.value; var oldValue = this.curValue; if (newVal == oldValue) return; this.inputFull = false; var caretPos = this.GetCaretPos(); var i; for (i = 0; i < this.curValue.length && i < newVal.length; i++) { if (newVal.charAt(i) != this.curValue.charAt(i)) { break; } } var start = i; var tail = (this.curValue.length > newVal.length ? newVal.substring(i) : this.curValue.substring(i)); var tailStart = this.curValue.length - tail.length; if (this.curValue.length < newVal.length && start != this.curValue.length && tail == newVal.substr(newVal.length - tail.length)) { // Insertion into the middle this.curValue = this.curValue.substring(0, start); newVal = this.curValue; var numInserted = this.input.value.length - tail.length - start; newVal = newVal + this.input.value.substr(start, numInserted); } else if (this.curValue.length > newVal.length && start != newVal.length && tail == this.curValue.substr(tailStart)) { // Deletion from the middle this.curValue = this.curValue.substring(0, start); newVal = this.curValue; } else { // Appending to the string / deletion from the end this.curValue = this.curValue.substring(0, start); tail = ''; } var error = false; for (i = start; i < newVal.length; ++i) { if (!this.InputSymbol(newVal.charAt(i)) && (!this.resumeOnErrors || evt === null)) { error = true; if (tail != '') { this.curValue = oldValue; tail = ''; } break; } } for (i = 0; i < tail.length; ++i) { if (this.IsSpecial(i + tailStart) && !this.InputSymbol(tail.charAt(i)) && (!this.resumeOnErrors || evt === null)) { error = true; this.curValue = oldValue; break; } } this.AppendSeparators(); this.inputFull = (this.mask.length <= this.curValue.length) if (!error) HideTip(); this.input.value = this.curValue; this.SetCaretPos(caretPos); this.UpdateHalves(); new AEvent("INPUT", {}, this); }, IsSpecial: function(pos) { return this.IsSpecialChar(this.mask.charAt(pos)); }, IsSpecialChar: function(ch) { return "#?Aa".indexOf(ch) != -1; }, AppendSeparators: function() { while (this.mask.length > this.curValue.length) { var maskChar = this.mask.charAt(this.curValue.length); if (this.IsSpecialChar(maskChar)) break; this.curValue = this.curValue + maskChar; } }, // -1 = invald, 0 = separator, or corresponding mask char ValidateAt: function(pos, sym) { if (this.mask.charAt(pos - 1) == 'y') { pos--; } while (pos <= this.mask.length && !this.IsSpecial(pos) ) { pos++; } var maskChar = this.mask.charAt(pos); var sepMatched = false; var numMatched = ("#mdy".indexOf(maskChar) != -1 && sym.search(/[0-9]/) != -1); var letterMatched = ( (maskChar == 'A' || maskChar == 'a') && sym.search(/[a-zA-Z]/) != -1); var anyMatched = (maskChar == '?'); var nonSepMatched = (numMatched || letterMatched || anyMatched); if (!nonSepMatched) { for (i = pos - 1; i > 0; i--) { var prevChar = this.mask.charAt(i); if (this.IsSpecialChar(prevChar)) { break; } else if (prevChar == sym) { sepMatched = true; break; } } } if (this.inputFull || this.mask.length <= pos || !nonSepMatched && !sepMatched) { this.raiseError(); return -1; } return (nonSepMatched ? maskChar : 0); }, InputSymbol: function(sym) { this.AppendSeparators(); var valid = this.ValidateAt(this.curValue.length, sym); if (valid === -1) return false; else if (valid === 0) return true; else if (valid == 'A') { this.curValue = this.curValue + sym.toUpperCase(); } else if (valid == 'M') { this.curValue = this.curValue + '0' + sym; } else if (valid == 'D') { this.curValue = this.curValue + '0' + sym; } else this.curValue = this.curValue + sym; this.AppendSeparators(); return true; }, SetValue: function(value) { var v; if (value instanceof Optional && value.Value() != undefined) { v = value.Value(); } else if (typeof(value) == 'string' && value!=undefined) { v = value; } else v = ''; this.curValue = v; if(this.curValue==undefined) this.curValue=''; // dirty hack TODO: remove it this.input.value=this.curValue; this.UpdateHalves(); this.lastReported=this.input.value; }, Value: function() { if(this.curValue===null || this.curValue===undefined) return null; if (this.curValue === "") return optional(undefined); return optional(this.curValue.toString()); }, ID: function() { return this.ID_; }, SetAttribute: function(sName, sValue) { if (sName=='visibility') { sValue = (sValue || "yes"); if (sValue == 'yes') this.input.writeAttribute('disabled', false); else this.input.writeAttribute('disabled', 'disabled'); this.wrapper.writeAttribute(sName, sValue); this.visibility = sValue; } this.input.writeAttribute(sName, sValue); }, SetTabOrder: function(nTabBase) { this.input.writeAttribute('tabindex', nTabBase); return ++nTabBase; }, /** @private */ raiseError: function() { var tip=this.input.readAttribute('tip'); if (tip) ShowTip(this.input, tip); if(this.blinkAnimation) { this.blinkAnimation.stop(); this.blinkAnimation=undefined; } var origBG=this.wrapper.getStyle('backgroundColor'); this.wrapper.addClassName('Masked_error'); var errBG=this.wrapper.getStyle('backgroundColor'); this.blinkAnimation = new Animation(this.wrapper, 6); this.blinkAnimation.addAnimation('backgroundColor', getHexRGBColor(errBG), getHexRGBColor(origBG)); this.blinkAnimation.run(); var self=this; this.blinkAnimation.onfinish = function() { self.clearError(); }.bind(this) }, /** @private */ clearError: function() { if(this.blinkAnimation) this.blinkAnimation.stop(); this.wrapper.removeClassName('Masked_error'); this.wrapper.setStyle({'backgroundColor': ''}); this.blinkAnimation=undefined; } })