TextInputのバイト数による入力制限
Flex4
/**
* Copyright propg ( http://wonderfl.net/user/propg )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/jwQh
*/
<?xml version="1.0" encoding="utf-8"?>
<s:Application
xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
creationComplete="OnCreationCompleteHandler(event)">
<s:layout>
<s:VerticalLayout paddingBottom="10" paddingLeft="10" paddingRight="10" paddingTop="10"/>
</s:layout>
<fx:Style>
@namespace s "library://ns.adobe.com/flex/spark";
@namespace mx "library://ns.adobe.com/flex/mx";
@namespace controls "nt.controls.*";
@namespace controls1 "labo.controls.*";
@namespace code "http://code.google.com/p/flexlib/";
s|Application {
backgroundColor: #AAAAFF;
}
global {
font-family: "MS Gothic", Verdana, Arial, Helvetica, sans-serif;
fontSize:20px;
}
</fx:Style>
<fx:Script>
<![CDATA[
import spark.events.TextOperationEvent;
private function OnCreationCompleteHandler(event:Event):void {
}
private var previousValue:String = "";
private var previousCursorPosition:int = 0;
private var previousByteLength:int = 0;
/** 入力可能な最大文字数(バイト数) 0以上の値を指定したときのみ機能する */
public var maxByteChars:int = 10;
private function input1OnChangeHandler(event:TextOperationEvent):void {
if (maxByteChars > -1) {
var target:TextInput = event.currentTarget as TextInput;
var text:String = target.text;
var currentCursorPosition:int = target.selectionAnchorPosition;
var byteLength:int = getByteLength(text);
messageLabel.text = byteLength + "bytes";
if (byteLength > maxByteChars) {
// 末尾にカーソルがあった場合は、末尾にカーソルを充てる
if (currentCursorPosition == text.length) {
target.text = substrB(text, maxByteChars);
target.selectRange(target.text.length, target.text.length);
} else {
// 文字列の中間にカーソルがあった場合
target.text = previousValue;
target.selectRange(currentCursorPosition-1, currentCursorPosition-1);
}
}
previousValue = target.text;
previousCursorPosition = target.selectionAnchorPosition;
previousByteLength = getByteLength(target.text);
}
}
/**
* 指定した文字列のバイト数を取得する(全角と半角で異なる) <br/>
* (ShiftJISコード換算での値)
*/
private function getByteLength(source:String):int {
var bytes:ByteArray = new ByteArray();
bytes.writeMultiByte(source, "Shift_JIS");
return bytes.length;
}
/**
* 部分文字列を取得する<br/>
* 文字数はバイトで指定する
*/
private function substrB(source:String, length:int):String {
var result:String = "";
var currentByteLength:int = 0;
for (var i:int = 0; i < source.length; i++) {
var c:String = source.charAt(i);
if (isHalfByteChar(c)) {
currentByteLength += 1;
} else {
currentByteLength += 2;
}
if (currentByteLength <= length) {
result += c;
} else {
break;
}
}
return result;
}
/**
* 指定した1文字が半角かどうかを取得する
*
* @param source チェック対象の文字
* @param position チェックする位置 指定しなければ1文字目
* @return true:半角 false:全角
*/
private function isHalfByteChar(source:String, position:int = 0):Boolean {
// 文字のコードを取得
var charCode:Number = source.charCodeAt(position);
if (charCode <= 255 || charCode >= 0xFF61 && charCode <= 0xFF9F) {
// 半角
return true;
} else {
// 全角
return false;
}
}
]]>
</fx:Script>
<fx:Declarations>
</fx:Declarations>
<s:Label text="▼入力してください"/>
<s:HGroup verticalAlign="middle">
<s:TextInput id="input1" change="input1OnChangeHandler(event)" imeMode="JAPANESE_HIRAGANA" focusIn="{IME.enabled = true}"/>
<s:Label id="messageLabel" text="0bytes"/>
</s:HGroup>
</s:Application>