I Hate Country Select Boxes

The country select box is my favorite pet peeve. You see it everywhere, in every signup form, every address entry form, everywhere that someone thinks that you’re too dumb to know what country you live in without some hints. Sure, you can tack USA to the top of the list, but where does that really get you? “Screw you Germany, France, Somalia, Canada, the UK, the Rebublic of Ireland, Russia, Croatia, Slovenia, Romaina, Bulgaria, and whatever other countries there are, you don’t have the internets anyway.”

The country select box isn’t an just insult to my intelligence and my nation’s internets-usage, it’s also a pain to use. I’ve learned to press “C” three times to get Canada, but I pity the poor fellow who lives in Myanmar and has to press “M” a grand total of 21 times to bypass Macau through Mozambique, and all the while dodging bullets fired at Buddhist monks. You know what country you live in, and you can spell it on the first try, too. So why have a select?

With some creative javascript, a small amount of input checking, and a bit of moxie, you can spare your visitors this humiliation. All you need is a list of all the countries (which you needed anyway), and a text input.

Here’s the HTML, to start:

<input type="text" name="myElement" id="myElementID"
onkeyup="countryList.updateTextbox(this.id,this.id+'_container')" />
<div id="myElementID_container"></div>

If you really want to be fancy/unobtrusive, you can rig up some javascript to apply the onkeyup stuff only when you load the page or something, but that’s not my point. Also, bonus points if you add onfocus and onblur attributes that show and hide myElementID_container.

I like to work with php, because I like having an extra layer where I can pull some fancy tricks to help myself out. In this case, that involves getting an array of every country. I used this one because it’s associative and gives country codes. Put it somewhere appropriate so that we can get at it. To get it into a form we can use from javascript, we simply invoke json_encode(), which will turn it into an object.

Next comes a wee bit of javascript, with the one thing of PHP. I’m going to make everything take place from within the context of a JSON object called countryList, because I feel fancy, and because if some other javascript needs a variable called countries somewhere else we won’t have to care. Here, I’ll walk you through it — if you just want to take the code without learning anything, that’s fine, but your punishment is that you have to copy each of my snippets individually to do it. Credit is always nice, too.

var countryList = {
	countries : <?= $countries ?>,
	updateTextbox : function(id, containerid){
		textBox = document.getElementById(id);
		current = textBox.value;
		var suggestionslist = document.createElement('ul');
		for(var code in countryList.countries){
			countryName.to = countryList.countries[code];

That part was pretty boring, I just instantiated everything and started my loop through the JSON. What happens next is that I’m going to use the substring function to compare the start of what I’m typing with that start of all the countries I’m looping through. Then, if there’s a match I’m going to use the DOM methods to build me a new list item featuring a link (clickable to update the textbox), to add to my new list of countries, replacing the old one.

	if(countryName.substring(0,current.length).toLowerCase()==current.toLowerCase()){
		countryNameNode = document.createTextNode(countryName);
		listNode = document.createElement('li');

		linkNode = document.createElement('a');
		linkNode.setAttribute("href","javascript: document.getElementById('"+id+"').value = '"+
		countryName+"'; countryList.updateTextbox('"+id+"','"+containerid+"'); void(0);");
		//The void(0); above is necessary to prevent firefox from redirection, annoyingly.
		linkNode.appendChild(countryNameNode);
		listNode.appendChild(linkNode);
		suggestionslist.appendChild(listNode);

	}

Next, we just append the list, after closing our loop, of course.

		}
		var container =document.getElementById(containerid);
		while(container.firstChild)
			container.removeChild(container.firstChild);
		container.style.textAlign = "left";
		container.appendChild(suggestionslist);
	}
}

And there you have it!

What’s that? “A demo,” you clamour? Fine, here. Note that this has a fancy timeout applied to the onblur hide so that you can still click the country links, if you’re quick enough.

If you use this, you should definitely add a check to see that the country is in a form you can use. Be sure to check for variations, e.g. “USA,” “The US,” “United States,” etc., but don’t be draconian about it or this will prove worse than a regular dropdown. Remember to be user-friendly, not user-proof.

Leave a Reply