【actionscript 3.0】テキストフィールドの入力で半角、全角区別して文字数制限

actionscript 3.0のテキストフィールドの入力で文字数でなく半角、全角で文字数制限したいという事で作りました。重要なのはByteArray.writeMultiByte(value:String, charSet:String)だけで、charSetを”shift-jis”にすると(確証はないが)半角と全角を判別できるみたい。私はFlashのIDE上に配置されたオブジェクトでなるべく解決したいのでProxyクラスを継承するやり方で実装しました。なのでTextFieldクラスを継承してnewでインスタンスを作ってステージ上に配置してやった方がスマートだとは思います。内部でイベントも持ってしまっているのであまり良いやり方ではないのも分かっていますがやりたい事は実現できているので一応クラス載せます。
※.maxCharsと同様スクリプトでの文字数などの制限はしていません。テキスト入力があった時のみの制御しかしていません。
TextFieldProxyクラス

package {

	import flash.utils.Proxy;
	import flash.utils.flash_proxy;
	import flash.text.TextField;
	import flash.utils.ByteArray;
	import flash.events.Event;
	import flash.events.TextEvent;

	public dynamic class TextFieldProxy extends Proxy {

		private const _charset:String = "shift-jis";
		private var _textField:TextField;
		private var _maxBytes:uint;
		private var _oldCaretIndex:uint;
		private var _oldText:String;

		public function set maxBytes(value:uint):void {
			_maxBytes = value;
			_textField.addEventListener(TextEvent.TEXT_INPUT, onInput);
			_textField.addEventListener(Event.CHANGE, onChange);
		}

		public function get maxBytes():uint {
			return _maxBytes;
		}

		public function get bytes():uint {
			var byteArray:ByteArray = new ByteArray();
			byteArray.writeMultiByte(_textField.text, _charset);
			var length:uint = byteArray.length;
			byteArray.clear();
			return length;
		}

	    public function TextFieldProxy(textField:TextField) {
	       _textField = textField;
	    }

	    override flash_proxy function callProperty(methodName:*, ... args):* {
	        return _textField[methodName].apply(_textField, args);
	    }

	    override flash_proxy function getProperty(name:*):* {
	        return _textField[name];
	    }

	    override flash_proxy function setProperty(name:*, value:*):void {
	        _textField[name] = value;
	    }

		public function onInput(event:TextEvent):void {
			(event.target as TextField).replaceSelectedText("");
			_oldText = (event.target as TextField).text;
			_oldCaretIndex = (event.target as TextField).caretIndex;
		}

		public function onChange(event:Event):void {
			var newText:String = (event.target as TextField).text;
			var newByteArray:ByteArray = new ByteArray();
			newByteArray.writeMultiByte(newText, _charset);
			if(newByteArray.length > _maxBytes) {
				var addStr:String = newText.substr(_oldCaretIndex, newText.length - _oldText.length);
				var addByteArray:ByteArray = new ByteArray();
				addByteArray.writeMultiByte(addStr, _charset);
				addByteArray.position = 0;
				addStr = addByteArray.readMultiByte(_maxBytes - (newByteArray.length - addByteArray.length), _charset);
				(event.target as TextField).text = _oldText.slice(0, _oldCaretIndex) + addStr + _oldText.slice(_oldCaretIndex, _oldText.length);
				_oldCaretIndex += addStr.length;
				if(!(event.target as TextField).multiline) {
					(event.target as TextField).setSelection(0, 0);
				}
				(event.target as TextField).setSelection(_oldCaretIndex, _oldCaretIndex);
				addByteArray.clear();
			}
			newByteArray.clear();
		}
	}
}
実装
//TextField txt1;
//TextField label1;
//TextField txt2;
//TextField label2;

txt1.text = "";
txt1.background = true;
txt1.backgroundColor = 0xF2F2F2;
txt2.text = "";
txt2.background = true;
txt2.backgroundColor = 0xF2F2F2;

var txtProxy1:TextFieldProxy = new TextFieldProxy(txt1);
txtProxy1.maxBytes = 10;
txtProxy1.addEventListener(Event.CHANGE, onChange);
label1.text = txtProxy1.bytes + "/" + txtProxy1.maxBytes;

var txtProxy2:TextFieldProxy = new TextFieldProxy(txt2);
txtProxy2.maxBytes = 30;
txtProxy2.addEventListener(Event.CHANGE, onChange);
label2.text = txtProxy2.bytes + "/" + txtProxy2.maxBytes;

function onChange(event:Event):void {
	switch(event.target) {
		case txt1:
			label1.text = txtProxy1.bytes + "/" + txtProxy1.maxBytes;
			break;
		case txt2:
			label2.text = txtProxy2.bytes + "/" + txtProxy2.maxBytes;
			break;
	}	
}
サンプル
This movie requires Flash Player 10

データ一式(Flash CS4以上)
ダウンロード

関連記事

  1. コメントはまだありません。

  1. トラックバックはまだありません。