One of the nice features of the Flex mx:List component is that you can set the renderers to be editable without having to create a new itemrenderer. With the Spark List (s:List) that option is no longer available. Fortunately it is quite easy to create a custom editable itemrenderer for the List.
Select an item in the left column and change the value, you can see the change events being traced out. Right click to view the source code.
There are three steps making an editable itemrenderer for the Spark List component.
First
Create a custom itemrenderer with a TextInput and a Label.
<?xml version="1.0" encoding="utf-8"?>
<s:ItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
autoDrawBackground="true">
<s:Label id="labelDisplay"
text="{data.label}"
top="7" bottom="5" left="5" right="3"/>
<s:TextInput id="inputTxt"
visible="false"
top="1" bottom="1" left="1" right="0"/>
</s:ItemRenderer>
Second
In order to toggle between the read and write states we need to add a click handler to the label and focusOut handler to the text input. You will notice that I simply set the respecitive components to either visible or not instead of uses the spark states. Using the spark states would require extending the list component to include an editHover state and for this example I wanted to keep things simple.
<fx:Script>
<![CDATA[
import spark.components.supportClasses.ListBase;
private function onChange(event:Event):void
{
isEdit(false);
}
private function onEdit(event:Event):void
{
inputTxt.text = data.label;
isEdit(true);
//set cursor postion to end
inputTxt.selectRange(inputTxt.text.length,inputTxt.text.length+1);
inputTxt.setFocus();
}
private function isEdit(value:Boolean):void
{
labelDisplay.visible = !value;
inputTxt.visible = value;
}
]]>
</fx:Script>
<s:Label id="labelDisplay"
text="{data.label}"
click="onEdit(event)"
top="7" bottom="5" left="5" right="3"/>
<s:TextInput id="inputTxt"
visible="false"
focusOut="onChange(event)"
top="1" bottom="1" left="1" right="0"/>
Third
This is the not so obvious step. You need to manually dispatch an event through the List’s dataProvider in order to notify the List and anything else that is using the data source that it’s contents have changed.
private function onChange(event:Event):void
{
var oldValue:String = labelDisplay.text;
if (oldValue != inputTxt.text)
{
data.label = inputTxt.text;
labelDisplay.text = inputTxt.text;
//dispatch the data update event
var list:ListBase = this.owner as ListBase;
list.dataProvider.itemUpdated(data, 'label', oldValue, inputTxt.text);
}
isEdit(false);
}
And that’s it. A basic editable list itemrenderer for the Spark List in 3 easy steps. Right click on the swf to see the source code.
I’ve been looking for the itemupdated for a while =) Thank you Derrick
Thanks for the example. I have a question about the ListB ase, is there a reason to use “var list:ListBase” instead of “var list:List”?
@D
Using var:ListBase gives you more flexibility in which list based components you can use the renderer in, it’s not bound to just the spark list.
Could this demo be done using custom states and the new state syntax? Or are custom states only definable in DataRenderers?
@ash you could use states in the itemrenderer, it just adds some more complexity. I always try to keep things as simple as possible, in this case not using states provided a nice clean solution.
nice….
“@ash you could use states in the itemrenderer, it just adds some more complexity. I always try to keep things as simple as possible, in this case not using states provided a nice clean solution.”
totally agree with you on that one, Derrick. Using states in my opinion adds unnecessary complexity where simplicity is always a benefit.
Quote
“This is the not so obvious step.”
You got that right. I’m glad I found this post and now have a little better understanding of Flex. Thanks.
@Gavin – simplicity is the key and it’s important to remember that the project should always be able to be picked up by somebody else down the line, so over-complicating things reduces the opportunity for this to happen.
Very useful. Thank you.