📄 maskedtextinput.as
字号:
/**
* @private
* Returns true if the text field is left incomplete.
*/
private function isWorkingIncomplete(len:Number = -1):Boolean
{
if(len == -1)
len = actualLength;
for(var i:int=0;i<len;i++)
{
if(_working[i] == " " && maskMap[i][1])
{
return true;
}
}
return false;
}
/**
* @private
* Handle the text entered by the user or specified in the
* text property.
*/
private function handleInput(input:String,event:Event = null):void
{
for(var i:int = 0;i<input.length;i++)
{
var c:String = input.charAt(i);
var m:String;
if(_position >= actualLength)
return;
var pos:Number = (_position < 0) ? 0:((_position >= actualLength)?actualLength-1:_position);
if(pos < actualLength && maskMap[pos][0] != null)
m = maskMap[pos][0];
else
{
if(event != null)
event.preventDefault();
return;
}
// Flag set to false if the character is not accepted
var bAdvance:Boolean = true;
// Check the character entered with the mask character at that position
switch(m)
{
case "#":
// if the character is a digit, accept it
if( isDigit(c) ) {
allowChar(c);
} else {
//event.preventDefault();
bAdvance = false;
}
break;
case "A":
// if the character is an alphabet,
// convert it to upper case and accept it.
if( isLetter(c) ) {
allowChar(c.toUpperCase());
} else {
//event.preventDefault();
bAdvance = false;
}
break;
case "a":
// if the character is an alphabet,
// convert it to lower case and accept it.
if( isLetter(c) ) {
allowChar(c.toLowerCase());
} else {
//event.preventDefault();
bAdvance = false;
}
break;
case "B":
// if the character is an alphabet, accept it.
if( isLetter(c) ) {
allowChar(c);
} else {
//event.preventDefault();
bAdvance = false;
}
break;
case ".":
// if the character is not a digit, accept it.
if( isDigit(c) ) {
//event.preventDefault();
bAdvance = false;
} else {
allowChar(c);
}
break;
case "*":
// if the character is a digit or an alphabet, accept it.
if( isDigit(c) || isLetter(c) ) {
allowChar(c);
} else {
//event.preventDefault();
bAdvance = false;
}
break;
default:
break;
}
if( bAdvance ) {
// If embeded hints are displayed then update the
// UITextField corresponding to the embeded hints
if(dateField)
{
var s:String = embedTextField.text == null ? "":embedTextField.text;
if(s.length > 0)
{
s = s.substring(0,_position) + " " + s.substring(_position+1, s.length);
embedTextField.text = s;
}
}
advancePosition();
}
else
{
if(event != null)
event.preventDefault();
}
workingUpdated = true;
invalidateDisplayList();
}
}
/**
* @private
* Moves the insertion point forward (if possible) to the next viable
* input position.
* byArrow denotes that advancePosition is called when
* the user has pressed Arrow key or not.
*/
private function advancePosition(byArrow:Boolean=false) : void
{
var p:Number = _position;
var posChanged:Boolean = false;
while((++p) < actualLength)
{
posChanged = true;
if(p >= actualLength-1)
{
p = actualLength - 1;
break;
}
if(maskMap[p][1])
break;
}
if(posChanged || p == actualLength)
_position = p;
// byArrow denotes that advancePosition is called when
// the user has pressed Arrow key or not
if( p >= actualLength && !byArrow )
{
if(_autoAdvance && !isWorkingIncomplete())
{
// Going to the next field
var obj:UIComponent = UIComponent(focusManager.getNextFocusManagerComponent());
if((obj is MaskedTextInput) || (obj is TextInput) || (obj is TextArea))
obj.setFocus();
}
dispatchEvent(new Event("inputMaskEnd"));
}
setSelection(_position,_position);
}
/**
* @private
* Moves the insertion point backward (if possible) to the previous
* viable input position.
*/
private function retreatPosition() : void
{
var p:Number = _position;
var posChanged:Boolean = false;
while((--p) >= 0 )
{
posChanged = true;
if(p <= 0 || maskMap[p][1])
break;
}
if(posChanged)
_position = p;
setSelection(_position,_position);
}
/**
* @private
* Returns true if the given character is a masking character.
*/
private function isMask( c:String ) : Boolean
{
return (c == "#" || c == "A" || c == "a" || c == "B" || c == "." || c == "*");
}
/**
* @private
* Returns true if the given character is a digit.
*/
private function isDigit( c:String ) : Boolean
{
return ((c >= "0" && c <= "9"));
}
/**
* @private
* Returns true if the given character is an Alphabet.
*/
private function isLetter(c:String):Boolean
{
return (((c >= "a") && (c <= "z")) || ((c >= "A") && (c <= "Z")));
}
/**
* @private
* Inserts the character into the working array.
*/
private function allowChar( c:String ) : void
{
// Commented so that the characeters dont shift to their left when deleting
/* var insertionPossible:Boolean = false;
var i:int = _position;
while((i+1) <= actualLength && maskMap[i][1])
{
if(_working[i] == " " && !(maskMap[i][0] == " "))
{
insertionPossible = true;
break;
}
i++;
}
while(insertionPossible && (i) > _position && maskMap[i][1])
{
_working[i] = _working[i-1];
i--;
} */
_working[_position] = c;
}
/**
* @private
* Modifies the display according to how flags are set: if
* text has been updated, fold the text according to the mask. If
* the mask has been updated, modify the display.
*/
override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
{
if(defaultBehaviour)
{
defaultBehaviour = true;
super.updateDisplayList(unscaledWidth,unscaledHeight);
return ;
}
super.updateDisplayList( unscaledWidth, unscaledHeight );
if( maskUpdated ) {
maskUpdated = false;
_working = [];
for(var i:int=0; i < actualLength; i++) {
var c:String = " ";
if(!maskMap[i][1])
c = maskMap[i][0];
_working.push(c);
}
width = measureText("W").width * actualLength + 2*getStyle("borderThickness") + 5;
workingUpdated = true;
}
if( textUpdated ) {
textUpdated = false;
_working = [];
for(var j:int=0; j < actualLength; j++) {
var ch:String = " ";
if(!maskMap[j][1])
ch = maskMap[j][0];
_working.push(ch);
}
_position = 0;
handleInput(_text);
workingUpdated = true;
}
if( workingUpdated ) {
super.text = _working.join("");
workingUpdated = false;
}
if(fontUpdated)
{
fontUpdated = false;
// Set the font size to 72 if user has specified the
// font size to be greater than 72
if(getStyle("fontSize") > 72)
{
setStyle("fontSize",72);
}
// Check if Monospaced font is used or not
// Set the font to Courier if font used is other then a monospaced font
if(measureText("W").width != measureText("I").width)
{
setStyle("fontFamily","Courier");
}
// Set the width of the control
width = measureText("W").width * actualLength + 2*getStyle("borderThickness") + 5;
}
if(dateField)
{
// when inputMask is changed dynamically,
// then in case of a date mask,
// create the embeded text field for showing
// embeded hints if its not already created.
// If it is created, then just change the embeded hint.
if(!embedTextField)
{
embedTextField = new UITextField();
addChildAt(embedTextField,getChildIndex(textField));
}
embedTextField.text = embedStr;
embedTextField.alpha = 1;
var txtFormat:TextFormat = new TextFormat();
txtFormat.color = 0xFFFFFF;
embedTextField.setTextFormat(txtFormat);
embedTextField.x = textField.x;
embedTextField.y = textField.y;
embedTextField.setActualSize(width,height);
}
else
{
if(embedTextField)
{
embedTextField.text = "";
embedTextField = null;
}
}
// create or updates the control's skin
createSkin();
textField.width += 50;
}
/**
* @private
*/
override protected function measure():void
{
super.measure();
var bm:EdgeMetrics = border && border is RectangularBorder ?
RectangularBorder(border).borderMetrics :
EdgeMetrics.EMPTY;
measuredMinHeight = measureText("Wj").height+4+bm.top+bm.bottom;
measuredHeight = measuredMinHeight;
}
/**
* @private
*/
override public function styleChanged(styleProp:String):void
{
super.styleChanged(styleProp);
// using date mask with validators changes the text color to black,
// in case of a validation failure.
// setting the color of the embeded text field to white.
if(styleProp == "themeColor")
{
if(embedTextField)
embedTextField.setColor(0xFFFFFF);
}
if(styleProp == "fontFamily" || styleProp == "fontSize")
{
fontUpdated = true;
measuredMinHeight = measureText("Wj").height+4;
measuredHeight = measuredMinHeight;
invalidateDisplayList();
}
}
/**
* @private
*/
override public function getStyle(styleProp:String):*
{
if(styleProp == "cellColor")
if(!super.getStyle("cellColor"))
if(required)
return 0xFF0000;
else
return 0x008CEA;
if(styleProp == "errorTextColor")
if(!super.getStyle("errorTextColor"))
return 0xFF0000;
return super.getStyle(styleProp);
}
/**
* @private
*/
private function createSkin():void
{
var skinName:String = backgroundSkinName;
// Has this skin already been created?
var newSkin:IFlexDisplayObject =
IFlexDisplayObject(getChildByName(skinName));
// If not, create it.
if (!newSkin)
{
var newSkinClass:Class = Class(getStyle(skinName));
if (!newSkinClass)
{
newSkinClass = MTISkin;
}
if(newSkinClass)
{
newSkin = IFlexDisplayObject(new newSkinClass());
// Set its name so that we can find it in the future
// using getChildByName().
newSkin.name = skinName;
// Make the getStyle() calls in MTISkin find the styles
// for this control.
var styleableSkin:ISimpleStyleClient = newSkin as ISimpleStyleClient;
if (styleableSkin)
styleableSkin.styleName = this;
if(embedTextField)
addChildAt(DisplayObject(newSkin),getChildIndex(embedTextField));
else
addChild(DisplayObject(newSkin));
// If the skin is programmatic, and we've already been
// initialized, update it now to avoid flicker.
if (newSkin is IInvalidating && initialized)
{
IInvalidating(newSkin).validateNow();
}
else if (newSkin is ProgrammaticSkin && initialized)
{
ProgrammaticSkin(newSkin).invalidateDisplayList();
}
}
}
// If the skin is already created then redraw it
// depending on the characters entered in the text input
else
{
ProgrammaticSkin(newSkin).invalidateDisplayList();
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -