Flex AdvancedDataGridで、ItemRenderer(TextInput)をタブ移動しながら金額をカンマ区切りにするサンプル ホームページ制作 | 墨田区

Flex AdvancedDataGridで、ItemRenderer(TextInput)をタブ移動しながら金額をカンマ区切りにするサンプル

LINEで送る
Pocket

FLEX(AIR)で、一覧表示を作る場合、DataGrid を利用しますね。しかし、ヘッダ部分をグループ化して表示したい ( Excelでいうセル結合した状態のようなもの ) などのニーズがあった場合、DataGrid ではなく、AdvancedDataGrid を利用します。今回は、この AdvancedDataGrid と、Itemrenderer を使って、「タブ移動しながら数値の入力を行い、カンマ区切り表示するサンプル」をご紹介します。

サンプル


別ウィンドウで表示する場合は こちら をクリックしてください。




【PR】マジか?!「アレ」してるLINEスタンプっていったい・・・



ソース

それでは、実際のソースを見ながら解説してきます。

NumericTextInputRenderer.as

数値入力用の ItemRenderer です。
package
{
	import flash.events.Event;
	import flash.events.FocusEvent;

	import mx.containers.HBox;
	import mx.controls.AdvancedDataGrid;
	import mx.controls.dataGridClasses.DataGridListData;
	import mx.controls.listClasses.BaseListData;
	import mx.controls.listClasses.IDropInListItemRenderer;
	import mx.controls.listClasses.IListItemRenderer;
	import mx.managers.IFocusManager;
	import mx.managers.IFocusManagerComponent;

	/**
	 * 数値入力レンダラー
	 */
	public class NumericTextInputRenderer extends HBox implements IListItemRenderer, IDropInListItemRenderer, IFocusManagerComponent
	{
		/**
		 * コンストラクタ
		 */
		public function NumericTextInputRenderer()
		{
			super();
		}

		/**
		 * NumericTextInput
		 */
		private var textInput:NumericTextInput = null;

		/**
		 * listData
		 */
		private var _listData:BaseListData;

		[Bindable("dataChange")]
		[Inspectable(environment="none")]
		public function get listData():BaseListData {
			return this._listData;
		}

		public function set listData(value:BaseListData):void {
			this._listData = value;
		}

		/**
		 * TextInputのID
		 */
		private var _tid:String = "";

		public function get tid():String {
			return this._tid;
		}
		public function set tid(tid:String):void {
			this._tid = tid;
		}

		/**
		 *  @private
		 *  Create components that are children of this Container.
		 */
		override protected function createChildren():void
		{
			super.createChildren();

			this.textInput = new NumericTextInput();
			this.textInput.width = 100;
			this.textInput.maxChars = 16;
			this.textInput.imeMode = "ALPHANUMERIC_HALF";
			this.textInput.precision = 0;	// 小数点以下の表示桁数
			this.id = _tid;
			this.textInput.addEventListener(FocusEvent.FOCUS_OUT, function(event:FocusEvent):void {
				if ( event.currentTarget.text == "" )
					return;
				var dgOwner:AdvancedDataGrid = event.currentTarget.owner.owner as AdvancedDataGrid;
				var idx:int = dgOwner.selectedIndex;
				data[DataGridListData(_listData).dataField] = event.currentTarget.text;
				dgOwner.dataProvider[idx][DataGridListData(_listData).dataField] = event.currentTarget.text;
				dgOwner.validateNow();
				dgOwner.dispatchEvent(event);
			});
			addChild(this.textInput);
		}

		/**
		 * 表示処理
		 */
		override protected function commitProperties():void
		{
			super.commitProperties();
			if ( data != null )
				this.textInput.text = data[DataGridListData(_listData).dataField];
		}

		/**
		 * フォーカスセット
		 */
		override public function setFocus():void
		{
			var fm:IFocusManager = this.focusManager;
			if (IFocusManagerComponent(this.textInput) != fm.getFocus())
				fm.setFocus(IFocusManagerComponent(this.textInput));
		}
	}
}

カスタムコンポーネントで、TAB キー押下時にフォーカスを移動するためには、カスタムコンテナに IFocusManagerComponent インタフェースを実装します。

createChildren

createChildren メソッドをオーバーライドし、子コンポーネントである、NumericTextInput を生成します。NumericTextInput については、こちら を参照ください。
フォーカスアウト時に、入力データをリストデータに書き換えるために、FOCUS_OUT イベントを追加しています。

commitProperties

commitProperties メソッドをオーバーライドします。リストデータに
値が存在する場合は、TextInput に表示します。

setFocus

IFocusManager を利用し、フォーカスセットをおこないます。

CharacterTextInputRenderer.as

文字列入力用の ItemRenderer です。
package
{
	import mx.containers.HBox;
	import mx.controls.dataGridClasses.DataGridListData;
	import mx.controls.listClasses.BaseListData;
	import mx.controls.listClasses.IDropInListItemRenderer;
	import mx.controls.listClasses.IListItemRenderer;
	import mx.managers.IFocusManager;
	import mx.managers.IFocusManagerComponent;


	/**
	 * 文字列入力レンダラー
	 */
	public class CharacterTextInputRenderer extends HBox implements IListItemRenderer, IDropInListItemRenderer, IFocusManagerComponent
	{
		/**
		 * コンストラクタ
		 */
		public function CharacterTextInputRenderer()
		{
			super();
		}

		private var textInput:CharacterTextInput = null;

		/**
		 * listData
		 */
		private var _listData:BaseListData;

		[Bindable("dataChange")]
		[Inspectable(environment="none")]
		public function get listData():BaseListData
		{
			return this._listData;
		}

		public function set listData(value:BaseListData):void
		{
			this._listData = value;
		}

		/**
		 * TextInputのID
		 */
		private var _tid:String = "";

		public function get tid():String {
			return this._tid;
		}
		public function set tid(tid:String):void {
			this._tid = tid;
		}

		/**
		 *  @private
		 *  Create components that are children of this Container.
		 */
		override protected function createChildren():void
		{
			super.createChildren();

			this.textInput = new CharacterTextInput();
			this.textInput.width = 150;
			this.textInput.maxChars = 80;
			addChild(this.textInput);
		}

		/**
		 * 表示処理
		 */
		override protected function commitProperties():void
		{
			super.commitProperties();
			if ( data != null )
				this.textInput.text = data[DataGridListData(_listData).dataField];
		}

		/**
		 * フォーカスセット
		 */
		override public function setFocus():void
		{
			var fm:IFocusManager = this.focusManager;
			if (IFocusManagerComponent(this.textInput) != fm.getFocus())
				fm.setFocus(IFocusManagerComponent(this.textInput));
		}
	}
}
NumericTextInputRenderer.as とやっていることは同じですので、説明は割愛します。
子コンポーネントとして利用している CharacterTextInput については、こちら を参照ください。

AdvancedDataGridInputTest.mxml

<?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"
					   width="544"
					   height="312"
					   xmlns:local="*"
					   initialize="onInit()">
	<fx:Script>
		<![CDATA[
			import mx.collections.ArrayCollection;
			import mx.events.AdvancedDataGridEvent;
			import mx.events.AdvancedDataGridEventReason;
			import mx.formatters.NumberFormatter;
			import mx.utils.ObjectProxy;
			/**
			 * 初期化
			 */
			protected function onInit():void {
				StyleManager.getStyleManager(null).loadStyleDeclarations("css/blue.swf");
				companyName.setFocus();
			}

			[Bindable]
			private var arr:Array = [
				{ no: "1", debitAccountsTitle: "現金", debitPrice: "20,000", creditAccountsTitle: "当座預金", creditPrice: "20,000" },
				{ no: "2", debitAccountsTitle: "受取手形", debitPrice: "30,000", creditAccountsTitle: "売掛金", creditPrice: "30,000" },
				{ no: "3", debitAccountsTitle: "仮払金", debitPrice: "70,000", creditAccountsTitle: "現金", creditPrice: "70,000" },
				{ no: "4", debitAccountsTitle: "仕入", debitPrice: "100,000", creditAccountsTitle: "支払手形", creditPrice: "100,000" },
				{ no: "5", debitAccountsTitle: "売掛金", debitPrice: "200,000", creditAccountsTitle: "売上高", creditPrice: "200,000" },
			];

			private function summary():void {
				errorMsg.text = "";
				var debitTotal:Number = 0;
				var creditTotal:Number = 0;
				for ( var i:int = 0; i < arr.length; i++ ) {
					debitTotal += Number(dataList.dataProvider[i].debitPrice.replace(new RegExp(",", "g"), ""));
					creditTotal += Number(dataList.dataProvider[i].creditPrice.replace(new RegExp(",", "g"), ""));
				}
				debitPriceTotal.text = format(debitTotal.toString());
				creditPriceTotal.text = format(creditTotal.toString());

				if ( debitPriceTotal.text != creditPriceTotal.text )
					errorMsg.text = "借方と貸方の合計金額が一致しません"

			}

			private function format(text:String):String {
				var nf:NumberFormatter = new NumberFormatter();
				nf.useThousandsSeparator = true;
				nf.useNegativeSign = true;
				return nf.format(text);
			}
		]]>
	</fx:Script>
	<fx:Declarations>
		<fx:Component id="debitAccountsTitleRenderer">
			<local:CharacterTextInputRenderer horizontalGap="0" borderStyle="none" color="0x000000" horizontalScrollPolicy="off" tid="debitAccountsTitle" />
		</fx:Component>
		<fx:Component id="debitPriceRenderer">
			<local:NumericTextInputRenderer horizontalGap="0" borderStyle="none" color="0x000000" horizontalScrollPolicy="off" textAlign="right" tid="debitPrice" />
		</fx:Component>
		<fx:Component id="creditAccountsTitleRenderer">
			<local:CharacterTextInputRenderer horizontalGap="0" borderStyle="none" color="0x000000" horizontalScrollPolicy="off" tid="creditAccountsTitle" />
		</fx:Component>
		<fx:Component id="creditPriceRenderer">
			<local:NumericTextInputRenderer horizontalGap="0" borderStyle="none" color="0x000000" horizontalScrollPolicy="off" textAlign="right" tid="creditPrice" />
		</fx:Component>
	</fx:Declarations>
	<mx:VBox width="100%" >
		<mx:HBox width="100%">
			<mx:FormItem width="100%" label="会社名">
				<local:CharacterTextInput id="companyName" text="saka-en." width="100%" maxChars="40" />
			</mx:FormItem>
		</mx:HBox>
		<mx:AdvancedDataGrid id="dataList" width="100%" initialize="dataList.dataProvider=arr" rowCount="7" allowMultipleSelection="true" editable="true" itemEditEnd="event.reason = AdvancedDataGridEventReason.CANCELLED" >
			<mx:groupedColumns>
				<mx:AdvancedDataGridColumn dataField="no" width="35" headerText="No." textAlign="right" editable="false"/>
				<mx:AdvancedDataGridColumnGroup headerText="借方">
					<mx:AdvancedDataGridColumn dataField="debitAccountsTitle" width="150" headerText="勘定科目"  itemRenderer="{debitAccountsTitleRenderer}" rendererIsEditor="true" editable="true" />
					<mx:AdvancedDataGridColumn dataField="debitPrice" width="100" headerText="金額" itemRenderer="{debitPriceRenderer}" rendererIsEditor="true" editable="true" />
				</mx:AdvancedDataGridColumnGroup>
				<mx:AdvancedDataGridColumnGroup headerText="貸方">
					<mx:AdvancedDataGridColumn dataField="creditAccountsTitle" width="150" headerText="勘定科目" itemRenderer="{creditAccountsTitleRenderer}" rendererIsEditor="true" editable="true" />
					<mx:AdvancedDataGridColumn dataField="creditPrice" width="100" headerText="金額" itemRenderer="{creditPriceRenderer}" rendererIsEditor="true" editable="true" />
				</mx:AdvancedDataGridColumnGroup>
			</mx:groupedColumns>
		</mx:AdvancedDataGrid>
		<mx:HBox width="100%">
			<mx:FormItem width="100%" label="借方計">
				<mx:HBox width="100%" styleName="total">
					<mx:Spacer width="100%" />
					<mx:Text id="debitPriceTotal" text="0" />
				</mx:HBox>
			</mx:FormItem>
			<mx:FormItem width="100%" label="貸方計">
				<mx:HBox width="100%" styleName="total">
					<mx:Spacer width="100%" />
					<mx:Text id="creditPriceTotal" text="0" />
				</mx:HBox>
			</mx:FormItem>
		</mx:HBox>
		<mx:HBox width="100%">
			<mx:Button id="sum" label="総額表示" click="summary()" />
			<mx:HBox width="100%" styleName="errorMsgBox">
				<mx:Text id="errorMsg" height="20"  />
			</mx:HBox>
		</mx:HBox>
	</mx:VBox>
</s:Application>

ダウンロード

サンプルソースは、こちら からダウンロードできます。

おつかれさまでした。

LINEで送る
Pocket

この記事がお役に立ちましたら シェア をお願いいたします。

コメントを残す

お名前 (必須)
メールアドレス
(アドレスは公開されません)

コメント(必須)

Trackback URL