Tag: override

FormItem, adding an icon

FormItem, adding an icon

Adding an icon to a form item is (yet another) one of those really annoying things in flex. I’m sure its something that loads of people wish to do but you can’t.

Well just to see if I could, I set about and extended the FormItem class so that I could add an image/icon.

After a quick look at the source code of the FormItem you can see that it only has two children. One, the label and two, the indicator. So if you do wish to add anything else you’re going to have to extend the FormItem.

Thankfully the FormItem is based on the Container which makes adding anything fairly straight forward. I prefer to do any extending in actionscript but you could do the below in MXML with a bit of actionscript code at the same time.

There are 3 steps you need to make.

  1. Override the createChildren method
  2. Set the image source
  3. Override the label

Override the createChildren

protected override function createChildren():void {
    super.createChildren();
    //you could move the image creation into a seperate function when and if the imagesource has been set
	//but for this example I've kept it simple.
	this.image = new Image();
	image.width = 16;
	image.height = 16;
	//again I've hardcoded these values for simplicity
	//You could if you wanted to create a versitile custom component load these values in from a CSS file
	image.setStyle('verticalCenter', 0 );
	image.setStyle('left', 5 );
	image.source = _imageSource;
	this.rawChildren.addChild(image);
	//bind the string property to the image source property.
	BindingUtils.bindProperty(image, 'source', this, 'imageSource');
}

from the above code you’ll see that all I’ve done is create an image, set its various properties and add it to the form.

most of this could and probably should be moved to a separate function (but for this demo I haven’t) so that you only add the image if it is actually required.  Also the style settings should come from a CSS file but for simplicity of the demo I haven’t done this.

Set the image source

private var _imageSource : String = '';

[Bindable]
public function get imageSource() : String {
	return _imageSource;
} 

//Sets the imageSource and I've added a number of spaces at the start to offset the 
//width of the image.
//The overall form width will be calculated from the width of the label (this is done inside the FormItem) 
public function set imageSource(str : String) : void {
  _imageSource = str;
  if(_imageSource.length > 0){//setting the label (not using _label) will resize the form/formItems
  //add spaces to the trimed version to make sure you don't end up with 100's of spaces at the start.
	label = "   " + StringUtil.trim(_label);
  } else {
	label = StringUtil.trim(_label);
  }
}

In the above code you can see that I set the variable _imageSource (which bound to the images source – see first snippet of code).  If the source is not “” then I add spaces to the label, make sure you set label and not _label.  This makes sure that the label width gets recalcualted.

Override the label

//Sets the label.
//If the imageSource has been set already then this will add spaces to the label
public override function set label(str : String) : void {
  _label = str;
  if(_imageSource.length > 0){
	_label = "   " + str;
  } else {
	_label = StringUtil.trim(str);
  }
  // call the super last, this will also force the remeausing of the formItem and Form
  super.label = _label;
}

The above code is very similar to the setter that set the imageSource but this time it sets _label then makes sure that the super function gets the new label.

Check out the simple demo here. (Right click for source)

[ad name=”ad-1″]