Archive

Posts Tagged ‘datagrid’

After edit confirmation for DataGrid itemEditor

February 19th, 2008 No comments

The main idea came from the need of password change confirmation into an DataGrid which has user informations. The updated of information is sent immediately to the server, so some important fields, like password should be confirmed before sending. Since there are a lot of issues in affected, I consider this solution (snippet) to be non elegant, mainly because it doesn’t respect a lot of my principles. If you were able to produce a better solution, please let me know.

Let’s begin : first, the DataGrid, which has an itemEditEnd listener, to handle the data which comes from itemEditors, where we will treat DataGridEvent to see what column was affected and ask confirmation question accordingly.

<mx:DataGrid id=”mainList”  dataProvider=”{usersList}” itemEditEnd=”checkDataInput(event)”>

Next, we’ll use three DataGridColumns – you can add more, as suitable to your needs. First column is not visible and keeps the userID information which I use to send the update requests to the server. The second column is the user real name, and has nothing special about it – information can be edited and will be submitted immediately to the server – thus doing the real time job.

<mx:DataGridColumn headerText=”ID” dataField=”uid” editable=”false” visible=”false”/>

<mx:DataGridColumn headerText=”User Real Name” dataField=”user_real_name” wordWrap=”true”>
<mx:itemEditor>
<mx:Component>
<mx:TextInput restrict=”A-Za-z ” maxChars=”20″/>
</mx:Component>
</mx:itemEditor>
</mx:DataGridColumn>

The last column is our subject, the password column. We intend to ask for a confirmation after this field is affected by the user (a superuser, which can manage all the accounts).  The passwdLabelFunction is used to display star character instead of the MD5 encoded string which is held on the server, and we are affecting the passwd dataField accordingly.

1
2
3
4
5
 
private function passwdLabelFunction(i:Object,c:DataGridColumn):String{
i.passwd = '******';
return '******';
}

<mx:DataGridColumn headerText=”Password” dataField=”passwd” labelFunction=”passwdLabelFunction”>
<mx:itemEditor>
<mx:Component>
<mx:TextInput restrict=”A-Za-z0-9 ” displayAsPassword=”true” maxChars=”20″/>
</mx:Component>
</mx:itemEditor>
</mx:DataGridColumn>

Now, DataGrid being prepared, we’ll need to make a artifice (the non-elegant part) to make this work. First, a private var will be used to store the string which cames from the password itemEditor, so we can send it to the server in case of change password confirmation (’yes’ leaf). A second private var will guard that we don’t have an multi event propagation in the checkDataInput handler (I have tried various techniques, but nothing worked – I’ve applied the old ‘flag check’ technique).

1
2
private var passwdKeep:String;
private var allreadyTriggered : Boolean = false;

Now, the checkDataInput function will look like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
 
private function checkDataInput(e:DataGridEvent):void{
//avoiding ESC key was pressed
if (e.reason == DataGridEventReason.CANCELLED) return;
 
//nothing happend with the data inside of it
if (e.currentTarget.editedItemRenderer.data[e.dataField] == TextInput(e.currentTarget.itemEditorInstance).text) return;
 
if (e.columnIndex == 2 &amp;&amp; !allreadyTriggered){
allreadyTriggered = true; //so the next time we'll know that we have been here. It will became false again, after we catch the answer
e.preventDefault(); //prevent the default behaviour
passwdKeep = MD5.calculate(TextInput(e.currentTarget.itemEditorInstance).text);//we are keeping the freshly entered string in an MD5 encoding, prepared to be send to the server
Alert.show('Do you really change the password for this user?','Please confirm',Alert.YES|Alert.NO,this,onConfirmPasswdChange);
return;
}
//avoiding null input
if(TextInput(e.currentTarget.itemEditorInstance).text == "") {
// Prevent the user from removing focus, and leave the cell editor open.
e.preventDefault();
// Write a message to the errorString property. This message appears when the user mouses over the editor.
TextInput(e.currentTarget.itemEditorInstance).errorString = "Oops, this field cannot be empty!";
}else {
 
//here lies the code which send the other informations to the server directly, without confirmation.
}
}

What remains, is to capture the response form the Alert :

1
2
3
4
5
6
7
 
private function onConfirmPasswdChange(e:CloseEvent):void{
allreadyTriggered = false;//we have an answer, so we'll change back the flag so the DataGrid item end edit handler can capture next event
if (e.detail==Alert.YES){
//here lies the code which send the encoded password to the server;
}
}

Even if it looks complex, if you have the same needs as I had, I’m sure you’ll get the idea and the code running. But then again, if you produced a better solution, please let me know.

DataGrid – vertical text on header

December 8th, 2007 No comments

The ideea behind vertical text on header is inspired by the use of CheckBox as an itemRenderer in a DataGrid. The width of the header of that column will be too large, so you need to do something to make it look good.

First, we define a header renderer component, let’s say that is based on VBox and has a Label inside. The plan is to use the rotate ability of Label, to make it vertical. The main problem (which exists since the begining of Flash) is that you’ll have to embed your fonts that are used on rotated components, risking otherwise not to see the text.

Here is the component (named VDGHeader.mxml):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml" paddingLeft="20" paddingTop="0" width="100%" height="100%"&gt;
&lt;mx:Script&gt;
&lt;![CDATA[
[Embed(systemFont='Verdana', fontName='myVerdana', mimeType='application/x-font', unicodeRange='U+0020-U+007E')] public var myVerdana:Class;
 
import mx.controls.dataGridClasses.DataGridColumn;
import mx.managers.SystemManager;
import de.richinternet.utils.Dumper;
 
[Bindable] private var text:String;
[Bindable] private var src:String;
 
override public function set data(value:Object):void{
var col:DataGridColumn = value as DataGridColumn;
text = col.headerText;
}
]]&gt;
&lt;/mx:Script&gt;
&lt;mx:Label id="txtLbl" text="{text}" fontFamily="myVerdana" rotation="90" width="100%" /&gt;
&lt;/mx:VBox&gt;

As you can see, I’ve embeded only the most used chars from the font, to optimize size. Component overrides the setter of data, which will catch the headerText property of a DataGridColumn.

Example of usage :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
&lt;mx:DataGrid
verticalCenter="0" horizontalCenter="0"
height="100%" width="100%"
headerHeight="180"
id="mainList"
dataProvider="{items}"
textAlign="center"
editable="false"&gt;
&lt;mx:columns&gt;
&lt;mx:DataGridColumn headerText="id" dataField="id" visible="false"/&gt;
&lt;mx:DataGridColumn headerText="Contact name" dataField="name" width="120"/&gt;
&lt;mx:DataGridColumn headerText="Contact surname" dataField="surname"/&gt;
&lt;mx:DataGridColumn headerText="Active" dataField="active" headerRenderer="VDGHeader" width="20"&gt;
&lt;mx:itemRenderer&gt;
&lt;mx:Component&gt;
&lt;mx:CheckBox selected="{data.active}"/&gt;
&lt;/mx:Component&gt;
&lt;/mx:itemRenderer&gt;
&lt;/mx:DataGridColumn&gt;
&lt;mx:columns&gt;