AdvancedDataGridを使ったサンプル応用 その1 -flex 2014/09/06

flexです。
AdvancedDataGridを使ってみました。
使っているバージョンは4.6です。

要件は下の図のような感じ
 確認のために、変なところにボタンをおいてます。

今回、はじめて、 AdvancedDataGridをさわったのですが、いろいろ表現できるコンポーネントですね。びっくりしました。

まあ、僕の不勉強というところで。

とりあえず、コード

<?xml version="1.0" encoding="utf-8"?> <s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:mc="aaa.*" creationComplete="mc.onCreationComplete()"> <fx:Declarations> <mc:ViewHelper id="mc"/> </fx:Declarations> <mx:AdvancedDataGrid id="list" treeColumn="{属性}" editable="true"> <mx:groupedColumns> <mx:AdvancedDataGridColumn id="区分" dataField="区分" width="100" headerText="区分" /> <mx:AdvancedDataGridColumn id="属性" dataField="属性" width="100" headerText="属性" /> <mx:AdvancedDataGridColumn id="名前" dataField="名前" width="100" headerText="名前" /> <mx:AdvancedDataGridColumnGroup id="aaa" headerText="aaa"> <mx:AdvancedDataGridColumnGroup id="aaaG" headerText="階層"> <mx:AdvancedDataGridColumnGroup id="aval1" dataField="av1" headerText="val1" editable="true"/> <mx:AdvancedDataGridColumnGroup id="aval2" dataField="av2" headerText="val2" editable="true"/> </mx:AdvancedDataGridColumnGroup> </mx:AdvancedDataGridColumnGroup> <mx:AdvancedDataGridColumnGroup id="bbb" headerText="bbb"> <mx:AdvancedDataGridColumnGroup id="bbbG" headerText="階層"> <mx:AdvancedDataGridColumnGroup id="bval1" dataField="bv1" headerText="val1" editable="true"/> <mx:AdvancedDataGridColumnGroup id="bval2" dataField="bv2" headerText="val2" editable="true"/> </mx:AdvancedDataGridColumnGroup> </mx:AdvancedDataGridColumnGroup> </mx:groupedColumns> </mx:AdvancedDataGrid> <mx:Button label="Submit" id="btn"/> </s:WindowedApplication>


package aaa { import flash.events.MouseEvent; import mx.collections.ArrayCollection; import mx.collections.HierarchicalData; import mx.controls.Alert; import mx.controls.TextInput; import mx.core.FlexGlobals; import mx.core.IMXMLObject; import mx.events.AdvancedDataGridEvent; import mx.events.CloseEvent; import mx.utils.ObjectUtil; public class ViewHelper implements IMXMLObject { private var view:TestView; private var data:ArrayCollection; public function ViewHelper() { trace("*** コンストラクタ"); } public function initialized(document:Object, id:String):void { trace("*** initialized document:[" + document +"] id:[" + id +"]"); // MXMLへの参照 this.view = TestView(document); } public function onCreationComplete():void { trace("*** onCreationComplete"); // テストデータを作成 this.data = createData(); // テストデータからHierarchicalDataを作成し、設定することで階層表現ができる this.view.list.dataProvider = new HierarchicalData(this.data); // ボタン 確認 イベント設定 this.view.btn.addEventListener( MouseEvent.CLICK , function(event:MouseEvent):void{ trace("*** btn OK!"); // テストデータが書き変わったか調べる trace("*** " + ObjectUtil.toString(data)); } ); /* * ITEM_EDIT_BEGINNING 入力値項目がどうかこのイベントで設定できる */ this.view.list.addEventListener(AdvancedDataGridEvent.ITEM_EDIT_BEGINNING, function(evt:AdvancedDataGridEvent):void { trace("*** ITEM_EDIT_BEGINNING"); // 3列までは入力項目としてあつかわない if (evt.columnIndex < 3) { trace("*** ITEM_EDIT_BEGINNING 入力項目ではない"); evt.preventDefault(); return; } }); /* * ITEM_EDIT_BEGIN 入力項目のTextInputの設定ができる */ this.view.list.addEventListener(AdvancedDataGridEvent.ITEM_EDIT_BEGIN, function(evt:AdvancedDataGridEvent):void { trace("*** ITEM_EDIT_BEGIN"); // // TextInput(evt.item).maxChars = 3;// 3文字制限 }); /* * ITEM_EDIT_END 入力後のチェックを設定できる */ this.view.list.addEventListener(AdvancedDataGridEvent.ITEM_EDIT_END, function(evt:AdvancedDataGridEvent):void { trace("*** ITEM_EDIT_END event reason:[" + evt.reason + "]"); var newVal:String = TextInput(view.list.itemEditorInstance).text; var oldVal:String = evt.currentTarget.editedItemRenderer.data[evt.dataField]; trace("*** ITEM_EDIT_END new:[" + newVal + "] old:[" + oldVal + "]"); // reasonによって対象とするイベントかどうかの判定を行う if (evt.reason == "other") { trace("*** ITEM_EDIT_END returnする reason:[" + evt.reason + "]"); // 編集とは関係ないので、入力値の前の値に戻します。 TextInput(view.list.itemEditorInstance).text = oldVal; return; } // ok文字列、空文字、以外ははじく if(!check(newVal)){ // イベントのデフォルト動作をキャンセル evt.preventDefault(); // 後続のイベントが処理されないようにする // フォーカスが移動しないようにする // evt.stopPropagation(); evt.stopImmediatePropagation(); // 入力値の前の値に戻します。 TextInput(view.list.itemEditorInstance).text = oldVal; // どの入力フィールドかわかるようにする var rowIndex:int = evt.rowIndex; var columnIndex:int = evt.columnIndex; // 警告用のダイアログを表示 // フォーカスを移動させないようにする FlexGlobals.topLevelApplication.callLater(   function ():void { // 匿名(無名)関数 var alert:Alert = Alert.show("入力値が正しくないです。","アラート", Alert.YES ,view,function(evt:CloseEvent):void{ // データグリッドのフォーカスを入力フィールドに戻す view.list.editedItemPosition = {columnIndex:columnIndex, rowIndex:rowIndex}; } );   }  ); } trace("*** ITEM_EDIT_END end "); }); this.view.list.addEventListener(AdvancedDataGridEvent.ITEM_FOCUS_OUT, function(evt:AdvancedDataGridEvent):void { trace("*** ITEM_FOCUS_OUT start "); }); } /** * チェック関数 */ protected function check(val:String):Boolean { // ここにチェック処理を書いていく // 空文字 if (val == "") { return true; } // ok文字列 if (val == "ok") { return true; } // 数値チェック if (!isNaN(Number(val))){ return true; } return false; } /** * テストデータ作成 */ protected function createData():ArrayCollection { return new ArrayCollection([{区分:"区分1", 属性:"属性1", 名前:"名前1", av1:"0", av2:"0", bv1:"0", bv2:"0"} ,{区分:"区分2", 属性:"属性2", 名前:"名前2", av1:"0", av2:"0", bv1:"0", bv2:"0" , children:[{属性:"属性2-1", 名前:"名前2-1", av1:"0", av2:"0", bv1:"0", bv2:"0"} , {属性:"属性2-2", 名前:"名前2-2", av1:"0", av2:"0", bv1:"0", bv2:"0"}]} ,{区分:"区分3"}]); } } }


 いくつかはまったのでメモ(上記のコードに全て含めています。)

  • イベントの順番(ITEM_EDIT_BEGINNING,ITEM_EDIT_BEGIN,ITEM_EDIT_ENDの順番)
  • 入力をキャンセルする方法(AdvancedDataGridEventのpreventDefault()を使う)
  • 警告ダイアログの表示タイミング(FlexGlobals.topLevelApplication.callLaterを使う)
  • 後続のイベントを防ぐ(フォーカスの移動を防ぐ)(AdvancedDataGridEventのstopImmediatePropagation()を使う)
  • グリッド入力値の取得(var newVal:String = TextInput(view.list.itemEditorInstance).text;)
  • グリッド入力値以前の値を取得(var oldVal:String = evt.currentTarget.editedItemRenderer.data[evt.dataField];)
  • 入力値を入力前にもどす (TextInput(view.list.itemEditorInstance).text = oldVal;)
  • 任意の場所のグリッドにフォーカスをあてる(view.list.editedItemPosition = {columnIndex:columnIndex, rowIndex:rowIndex};)
  • 対象のイベントの選別(AdvancedDataGridEventのreasonを調べ "other"かどうかの判定)
 等々

参考にしたサイト(順不同)




: