How to Get tabIndex to Work Properly in IE

Social Share Toolbar

tabIndex allows you to define a specific tab order of objects in a swf. This is especially helpful when designing forms with input fields. Upon reaching the final object in the tab order the cursor is supposed to go back to the first tabIndex. As you might imagine this works properly in Firefox. As you might also imagine, it does not work properly in IE.

Instead of wrapping back to the first object, IE takes the client out of the swf and into the address bar, or other objects on the page unrelated to the swf where your form fields reside. You can see an example here: http://www.rabidgadfly.com/swf/tabhack.html .

The good news is that there’s a relatively simple hack to prevent IE from wrestling tab control away from your swf. The trick is to create an empty movie clip and assign it the last tabIndex. Then attach an onSetFocus to it that hands focus back to the first object in your tab order. The code looks like this:


input1.tabIndex = 1;
input2.tabIndex = 2;
input3.tabIndex = 3;
restartTab_mc.tabIndex = 4;

restartTab_mc.onSetFocus = function() {
	Selection.setFocus(input1);
};

You can try out the fix here: http://www.rabidgadfly.com/swf/tabhack2.html, or download the fla to take a look .

-rG

How to Queue getURL calls to appease IE

Social Share Toolbar

Web analytics can be a real pain in the ass sometimes, especially with Flash. If the object you’re coding is a link then you’re required to execute two getURLs and therefore two separate calls to the browser. One link being the actual URL you’re navigating to and the other being a javascript call to an analytics function.

As I mentioned in a previous post, while Firefox is able to handle this without an issue, many times Internet Explorer will only take one. This is because Internet Explorer calls getURL() asynchronously.

Until recently I hadn’t run into the problem myself but the time inevitably came where I was saddled with the issue. The solution my coworkers have been using is to string the calls together into one javascript getURL call but that can make for some hard to read and manage code. I decided instead to write a function that would queue up the calls and send them at a specified interval.

I start off by defining the variables I’m going to need:


var linkQ:Array = new Array();
var sendInterval:Number;
var waitTime:Number = 75;

linkQ will be a multi-dimensional array that will take the link and the target. sendInterval will simply hold the setInterval id, and wait time represent the number of milliseconds to wait between sending links.

We use Hitbox so my example will be using _hbLink which takes 6 parameters: ID, Link Position (on the page), _x,_y,_width,_height. ID and Position are both strings defined by your friendly neighborhood SEO manager. I wrote a function external to the Flash app so it can be used with any site or app we host:


function hblink(linkID:String,linkPOS:String,Position:String,linkurl:String,linkurlTarget:String) {
	if (!linkQ.length) {
		linkQ.push(["javascript:_hbLink('"+linkID+"','"+linkPOS+"','"+Position+"');",""]);
		if(linkurl) {
			if(linkurlTarget) {
				linkQ.push([linkurl,linkurlTarget]);
			} else {
				linkQ.push([linkurl,"_self"]);
			};
		};
		sendInterval = setInterval(_root.sendData,waitTime);
	} else {
		linkQ.push(["javascript:_hbLink('"+linkID+"','"+linkPOS+"','"+Position+"');",""]);
		if(linkurl) {
			if(linkurlTarget) {
				linkQ.push([linkurl,linkurlTarget]);
			} else {
				linkQ.push([linkurl,"_self"]);
			};
		};

	};
};

My function takes five parameters: linkID and linkPOS coincide with _hbLink’s ID and Link Position, Position is a string I pass containing the _x,_y,_width, and _height, linkurl is the functional navigation link, and linkurlTarget is the target page. So what I would pass looks something like this:


hblink("buttonHome","navbar",String(this._x+","+this._y+","+this._width+","+this._height),'http://www.google.com','_blank');

The function separates pushes the two links (the _hbLink call and the actual URL) into the linkQ array and, if no interval is currently set, defines the interval to call the sendData function that actually executes the getURLs one at a time, waitTime seconds apart. Here’s what that function looks like:


function sendData() {
	var execCode:String = String(linkQ[0][0]);
	var execTarget:String = String(linkQ[0][1]);
	if (execTarget.length) {
		getURL(execCode,execTarget);
	} else {
		getURL(execCode);
	};
	linkQ.splice(0,1);
	if (!linkQ.length) {
		clearInterval(sendInterval);
	};
};

The sendData function only reads the first row in the array no matter how many are queued up. After it sends the getURL it removes that link from the array. This function will fire every waitTime seconds until the array is empty at which point it will clear the interval.

There’s not a lot of info out there on this topic and the few solutions I came across were overly complicated or just plain ugly. I hope this info helps somebody out.

-rG