Editable Empty DataGrid

Editable Empty DataGrid

14.05.2010 in Media & More

In Adobe Flex spielt das DataGrid als Datenvisualisierungs-Control eine zentrale Rolle. In diesem Artikel beschreibe ich, wie sich dieses Control sinnvoll erweitern lässt. Alle Beispiele lassen sich über das Kontextmenü (rechte Maustaste > Quelle anzeigen) im Sourcecode ansehen und downloaden.

Beispiel 1 zeigt, wie sich die Daten eines Objekt-Arrays in einem DataGrid darstellen lassen.


Beispiele 1 und 2

Um die Daten editierbar zu machen, genügt es, wie Beispiel 2 zeigt, die Eigenschaft editable auf true zu setzen.

Doch lassen sich nur solche Datenzeilen editieren, die bereits Daten enthalten. Befindet man sich in der letzten Datenzelle („Bundy“) und drückt die TAB-Taste, verliert der Focus das DataGrid an das nächste Control.

Die Erweiterung

In den Beispielen 3 und 4 habe ich das DataGrid nun so erweitert, dass sich auch die nächste bzw. erste leere Zelle ansteuern und ausfüllen lässt, danach auch die weiteren Zeilen.


Beispiele 3 und 4

Nach dieser Funktionalität habe ich lange im Internet gesucht, aber keine zufriedenstellende Lösung gefunden. Deshalb habe ich diese eigene Lösung entwickelt und veröffentliche sie hier und vermute, dass sie auch für andere Flex-Entwickler sehr nützlich sein kann.

Die Lösung im Detail

Ganz so trivial, wie es anfangs schien, war es nicht, die gewünschte Funktionalität zu realisieren. Zunächst einmal muss man wissen, dass man es, sobald die Eigenschaft editable auf true gesetzt wurde, mit zwei Controls zu tun bekommt: mit dem DataGrid und einem TextInput (als dem standardmäßigen ItemEditor). Dieser wird jeweils immer passgenau über die aktuell ausgewählte Zelle gesetzt.

Zwei Events habe ich behandelt: focusIn und itemEditEnd.

focusIn wird ausgelöst, nachdem das DataGrid den Focus erhält, ItemEditEnd, wenn die Bearbeitungssitzung des ItemEditors (unserem TextInput) endet.

Im focusIn-Event wird zunächst mit

if (this.dataProvider==null) this.dataProvider = new ArrayCollection(); 

dafür gesorgt, dass auf jeden Fall ein dataProvider-Objekt (als ArrayCollection) existiert.

Dem dataProvider wird nun ein neues Object-Element angefügt.

ArrayCollection(this.dataProvider).addItem(new Object()); 

Genau hierin liegt schon das Geheimnis, das auch einem völlig leeren DataGrid nun die Editierfähigkeit beibringt (damit besitzt es nämlich einen, wenn auch leeren Datensatz).

Jetzt gilt es noch, die Eingabeposition auf die erste Zelle der neuen Zeile zu setzen:

this.editedItemPosition = {rowIndex: this.dataProvider.length - 1, columnIndex: 0};

Im itemEditEnd-Event ist etwas mehr zu tun. Mit

var txtIn:TextInput = TextInput(e.currentTarget.itemEditorInstance);

wird eine Referenz auf unseren ItemEditor (den TextInput) gesetzt.

var colName:String = this.columns[e.columnIndex].dataField;

ermittelt den Namen der aktuellen Spalte anhand der dataField-Eigenschaft.

Beides benötigen wir nun, um unserem neuen (leeren) Datensatz über

this.dataProvider[e.rowIndex][colName] = txtIn.text;

den Inhalt des TextInput zuzuweisen.

this.dataProvider.refresh();

aktualisiert unseren dataProvider.

In einer if-Konstruktion prüfen wir zum einen, ob wir in der letzten Spalte sind und ob die letzte Zeile Daten enthält:

if (e.columnIndex==this.columnCount-1 && hatZeileDaten(this.dataProvider.length-1))

Trifft beides zu, wird das Standardverhalten beim Verlassen des ItemEditors unterdrückt.

e.preventDefault();

Diese Maßnahme ist sehr wichtig, da ansonsten der Focus an dieser Stelle das DataGrid verlässt. Wir wollen aber erreichen, dass mit dem nächsten Druck auf die TAB-Taste der Focus auf die erste Zelle der nächsten Zeile wandert.

Als Aufräumarbeit bleibt noch, den ItemEditor mit

this.destroyItemEditor();

zu entfernen und den Focus mit

this.setFocus();

ausdrücklich wieder auf das DataGrid zu setzen.

Nun greift wieder unsere Programmierung im focusIn-Event, d.h. es wird ein neues (leeres) Element angehängt, was die Folgezeile wieder editierbar macht. Und alles beginnt wieder von vorn…

Auf die Erläuterung der Hilfsfunktion hatZeileDaten sowie die Flag-Variable neueZeile habe ich zugunsten einer zusammenhängenden Darstellung des Eventflows verzichtet. Beim Blick in den vollständigen Sourcecode wird deren Bedeutung jedoch schnell ersichtlich.

Ergänzt habe ich noch eine Getter-Eigenschaft dataProvider2 vom Typ ArrayCollection. Anders als dataProvider wird hier das jeweils künstlich erzeugte leere Element wieder entfernt, so dass beim Zugriff auf die Datensätze von außen niemand etwas mitbekommt vom Trick mit der leeren Eingabezeile ;-).


Schlagworte: ,

  1. bill gates scholarship - 30.03.2011

    Thanks for that awesome posting. It saved MUCH time 🙂

Copyright © 2009-2024 by multimedia and more - - Impressum - Datenschutz