Tuesday, February 27, 2007

Home on the TextRange

I've been having some grief with a Flex project. It's has a few modules that are loaded at runtime based on a menu. One of these Modules occasionally produced an error message when it loads. It was a strange message relating to a ButtonBar's Programmatic skin. Which seemed strange as I wasn't using a ButtonBar anywhere. Until I realised I was using a RichTextEditor which contains a ButtonBar. I tried many things to fix this problem with no luck.

So I started thinking about making my own RichTextEditor. I created a quick test component with a TextArea and a button. The idea being that the button would call a function to set the selected text to bold. You can get the start and end index of the selection easy enough using the TextArea.selectionBeginIndex and TextArea.selectionEndIndex properties. But there is a problem. The text components have two properties you need to worry about;text and htmlText. The selection index properties relate to the text property. But the actual changes need to effect the htmlText property. I started thinking about an array to manage the position of the html elements. But it wasn't going to be straight forward.

Which got me wondering how the RichTextEditor managed this. A quick look in the class file revealed an import for mx.controls.textClasses.TextRange. "The TextRange class provides properties that select and format a range of text in the Label, Text, TextArea, TextEditor, and RichTextEditor controls.". In other words it does exactly what I was looking for in my RichTextEditor. Using TextRange I rewrote my bold function:

* Listen for click event from bold_btn
* set selected text to bold

private function bold(event:Event):void
var b :int = text_area.selectionBeginIndex;
var e :int = text_area.selectionEndIndex;

if(b != e)
var tf:TextRange = new TextRange(text_area,true,b,e);
tf.fontWeight = "bold";

The TextRange object receives four parameters.

  • The Text component that is the target of the action.

  • Are we going to make a change.

  • The start index of the change.

  • The end index of the change.

In the following line we change the fontWeight property of the TextRange object and consequently the htmlText property of the selection. The TextRange class can effect most of the html elements available to Flex Text. The only exception I've found so far is inserting an image. Obviously this is only the beginning of a custom RichTextEditor. But TextRange will greatly simplify the task.


Ari said...

Thats a neat trick for AS3, but what would be the equivalent for AS2, I'm struggling with a project right now.

My main problem is that when I search through the HTML text for the string that I want to edit, I may get multiple hits, is there a way to translate the begin index of the text to the htmlText equivalent?

geekglue said...

There isn't an equivalent AS2 Class for TextRange. But I expect that most of the magic that is TextRange is available in AS2. I think the best starting point is to take a look at the TextRange Class to see how it works and whether the individual methods have AS2 equivalents.