Wednesday, October 14, 2009

How to Localize a Browse Button

Yes, I have seen more complaints about this than you can image but the good news is not only can you 'localize' it but make it pretty. Wanna see what I'm talking about?


In case you're not familiar with the problem, a form input type of "file" connects to the client's operating system via an Application Programming Interface (API). That familiar window that allows us to select our file is displayed depending on your operating system (*nix, Windows, Mac). Because of this, it was deemed as a security risk to allow a developer to interfere in any way with this functionality.

What browser will this work on?

First and foremost, this will work in IE 6 and 7, FF 2 and 3, and Safari on MAC.

What you need


1) 2 Images: One to display English one to display French. (Or whatever languages you choose.)


Admittedly, these aren't pretty but they'll do. The file name you give your images plays a roll (well at least for this example). The English one I've called browseen_US and browsefr_FR. Why? Because when we swap (by pressing the French or English link) the buttons will swap based on locale. In addition, the image dimensions should stay the same. In this case they're not quite the same so you can see the difference.

2) The Code (Read the comments throughout)


<html>
<head>
<script type="text/javascript">
//Set your default language
var myLang="fr_FR";

//The 'switchTo...' functions will be triggered when we select the
//English or French link.
//The call to initFileUploads updates the UI.
function switchToEnglish() {
myLang="en_US";
initFileUploads();
}

function switchToFrench() {
myLang="fr_FR";
initFileUploads();
}

//This function will update the UI. Note this is where the magic happens.
//We will be using a regular file input type but we use a combination
//of CSS and JavaScript to overlay the English and French buttons.
function initFileUploads() {

var fakeFileUpload = document.createElement('div');

fakeFileUpload.className = 'fakefile';
fakeFileUpload.appendChild(document.createElement('input'));
var image = document.createElement('img');

image.src='browse'+myLang+'.jpg';
image.id="uploadImgId";

fakeFileUpload.appendChild(image);
var x = document.getElementsByTagName('input');

for (var i=0;i<x.length;i++) {
if (x[i].type != 'file') continue;
if (x[i].parentNode.className != 'fileinputs') continue;
x[i].className = 'file hidden';
var clone = fakeFileUpload.cloneNode(true);
x[i].parentNode.appendChild(clone);
x[i].relatedElement = clone.getElementsByTagName('input')[0];
x[i].onchange = x[i].onmouseout = function () {
this.relatedElement.value = this.value;
}
}
}

//This function is called just as a test to see what will be submitted.
//The output will be different depending on the browser you're using.
function viewSubmit() {
for(i=0; i<document.browseTest.elements.length; i++) {
if(document.browseTest.elements[i].name == "") {
document.write("This is the dynamically generated input. ---- ");
}
document.write("The field name is: " + document.browseTest.elements[i].name + " and it’s value is: " + document.browseTest.elements[i].value + ".<br />");
}
}
</script>

<!--These styles are needed for the magic to work. You may have to adapt these depending on what browser you need this to work in. -- >
<style type="text/css">
div.fileinputs {
position: relative;
/*ie7 and ff2 are colliding*/
width: auto;
}

div.fileinputs .file {
/*For ie7 only*/
width: 235px;
}

div.fakefile {
position: absolute;
top: 0px;
left: 0px;
z-index: 1;
}

input.file {
position: relative;
text-align: right;
-moz-opacity:0 ;
filter:alpha(opacity: 0);
opacity: 0;
/*Required for ff2 ONLY*/
width: 145px;
z-index: 2;
}

#uploadImgId {
position: absolute;
/*ie 7 needs this*/
width: 90px;
}

</style>
</head>

<!--The initFileUploads is called to update the UI upon entering the page. -->
<body onload="initFileUploads();">

<fieldset><legend>Browse Button Localization</legend>
Select Language: <a href="#" onclick="switchToEnglish()">English</a>
<a href="javascript:switchToFrench()">French</a><p>

<form name="browseTest" class="example">
<div class="fileinputs">
<input type="file" class="file" name="originalFileInput"/>
</div>

<br />
<input type="button" name="submit" value="View the Submission Value" onclick="viewSubmit()">
</form>
</fieldset>

</body>
</html>

Feel free to swipe!

No comments:

Post a Comment