Journal Entries

 

Mar 15, 2007

It’s a feature that plays like a bug.


This is not a bug. But it is not, not a bug.

I have a textfield with embedded fonts created by a custom object populated with the text “Enter a name”. When a user clicks into this textfield, I want to erase the current text and leave an empty textfield with a cursor blinking and ready for input.

Here’s the textfield:

__myContainer_mc.createTextField( "my_tf", 1, 0, 0, 200, 20 );
__myContainer_mc[ "my_tf" ].border = true;
__myContainer_mc[ "my_tf" ].borderColor = 0×8DAC3E;
__myContainer_mc[ "my_tf" ].type = “input”;
__myContainer_mc[ "my_tf" ].embedFonts = true;
__myContainer_mc[ "my_tf" ].text = “Enter a name”;
__myContainer_mc[ "my_tf" ].setTextFormat( getMyTextFormat() );

Here’s what I wrote to capture the focus event:

__myContainer_mc[ "my_tf" ].onSetFocus = function() {
	this.text = “”;
}

When this script is run, the user, upon clicking into the textfield sees an empty textfield without a cursor. On top of that, the user cannot enter any text into the textfield. Or rather as I later discovered, the user cannot enter any text that they can see into the textfield.

After much trial and error (and very little help from to all powerful Google), this is the functioning script:

var myRef = this;
__myContainer_mc[ "my_tf" ].onSetFocus = function() {
	this.text = “”;
	this.setTextFormat( myRef.getMyTextFormat() );
};

It would seem that embedded text that is programmatically reset, needs to be reformatted as well. That is a nuisance. Why does a textfield lose its format at any time?

Because I cannot let a frustrating problem die, I refined the script a little bit more. What if there were multiple textfields on the Stage that each required different actions in response to a focus change? Setting individual onSetFocus handlers for every instance is tedious and greatly increases the chances of writing in bugs.

So scrapping the onSetFocus handler and taking advantage of the Selection object, we have this:

Selection.addListener( this );

/.../

public function onSetFocus( oldFocus, newFocus ) {

	switch( newFocus ) {
		// The 'add a name' textfield has been selected.
		case __myContainer_mc[ "my_tf" ]:
			// Erase the current text.
			newFocus.text = “”;
			newFocus.setTextFormat( getMyTextFormat() );
			break;
	}

}

With our custom object now broadcasting all focus events to the Selection object, we can have a single event handler in our object handle the different actions required for different textfield instances.

Here’s the whole thing for copy / paste enthusiasts:

private function gatherName( ):Void {

	// Create a name input field.
	__myContainer_mc.createTextField( "my_tf", 1, 0, 0, 200, 20 );
	__myContainer_mc[ "my_tf" ].border = true;
	__myContainer_mc[ "my_tf" ].borderColor = 0×8DAC3E;
	__myContainer_mc[ "my_tf" ].type = “input”;
	__myContainer_mc[ "my_tf" ].embedFonts = true;
	__myContainer_mc[ "my_tf" ].text = “Enter a name”;
	__myContainer_mc[ "my_tf" ].setTextFormat( getMyTextFormat() );

	// Start listening to selection events.
	Selection.addListener( this );

}

/*
 *	When a new object is selected, this method controls the actions taken according to the selected object.
 */
public function onSetFocus( oldFocus, newFocus ) {

	switch( newFocus ) {
		// The ‘add a name’ textfield has been selected.
		case __myContainer_mc[ "my_tf" ]:
			// Erase the current text.
			newFocus.text = “”;
			newFocus.setTextFormat( getMyTextFormat() );
			break;
	}

}

This one is definitely going in theWell(currently being built out). I’ve run into it before and lost close to three days working the details out. I know that it’s not a bug, but it is one of those idiosyncrasies of a scripting language that drive developers and designers alike insane. Hopefully, I just saved someone else’s sanity and free time.

 

Comments are closed.