Patricks asks:

Having an interesting dilemma that I cannot seem to come up with a working solution to. I have a text box that we need people to enter a time into. I dont want it to be a mask but rather onBlur the string "completes" with the proper format. For example, the user enters 3:29.2 for their time, onBlur the result needs to be 00:03:29.20. Or the user enters 4.6, onblur should result in 00:00:04.60. Just curious if you could point me in the right direction or come up with a demo, I think this would be very useful to many folks as a blog entry.

So let me state right off - I really don't like formatting in JavaScript. If I'm doing any kind of Ajax development and need the data to look nice, I will almost always do the formatting in ColdFusion first. ColdFusion has spoiled me, what can I say? So please keep that in mind when reviewing my solution. There are probably a hundred different ways to do this (better) but hopefully this will be helpful anyway.

For my solution, I decided to do something a bit different. Instead of building a form and using the onblur as Patrick wanted, I thought I'd build something like a test script. The idea would be that I could provide an array of inputs and when the page loaded, it would run through them all and output the results. Here is what I came up with initially.

<h2>Tests</h2> <div id="testDiv"></div>

<script> var myarea = document.getElementById("testDiv") var tests = ["2.2","3:29.2"]

for(var i=0;i<tests.length;i++) { myarea.innerHTML += "<br/>" + tests[i] + " = " + formatTime(tests[i]) }

function formatTime(t) { return t } </script>

I create a simple div on top. The JavaScript section begins by creating a pointer to it. The tests array represent all my inputs. Next I loop over the inputs and add to the div the initial value and the result of the format. As you can see, the format does nothing now. I ran this and got the following output:

Nice and simple. But the point is - I can easily then add more inputs and test the output to ensure my function works correctly. So now for the actual formatting - and again - consider this code rough - I know it could be improved:

function formatTime(t) { //Desired result is hh:mm:ss.MM //Check for ., if not dot, assume it is just the seconds or more portion var ms = "00" if(t.indexOf(".") != -1) ms = t.split(".")[1]

var time = t.split(".")[0] //so ms should be ok as is, but time may not be var items = time.split(":")

//loop over length of size - 3 var toAdd = 3-items.length for(var i=1; i <= toAdd; i++) { items.unshift("00") }

//now fix each item - if size of the item is 1, prepend with 0 for(var i=0; i < items.length; i++) { if(items[i].length == 1) items[i] = "0" + items[i] }

var timeStr = items.join(":") return timeStr + "." + ms }

I begin by grabbing the millisecond portion of the input - if it exists. The split function is a nice way to treat a JavaScript string like a ColdFusion list. The right side portion of the input is the hours, minutes, and seconds. Since a user may enter only seconds, or maybe only minutes and seconds, I may need to "pad" my data. So I split that portion on the colon character and if the size is less than three, I enter some blank values into the array. By the way, don't make the mistake I did:

for(var i=1; i <= (3-items.length); i++) { items.unshift("00") }

Can you guess why that failed?

Anyway, the next step was to convert any single character value, like "3", into a fuller "03" string. Finally I can convert the array back into a string using join. Here is the complete test script with some additional inputs. As you can imagine, this version was not the first version I sent him. As he sent back bugs, I simply entered his inputs and updated the function:

<h2>Tests</h2> <div id="testDiv"></div>

<script> var myarea = document.getElementById("testDiv") var tests = ["2.2","3:29.2","4.6","3","03:22:10.4"]

for(var i=0;i<tests.length;i++) { myarea.innerHTML += "<br/>" + tests[i] + " = " + formatTime(tests[i]) }

function formatTime(t) { //Desired result is hh:mm:ss.MM //Check for ., if not dot, assume it is just the seconds or more portion var ms = "00" if(t.indexOf(".") != -1) ms = t.split(".")[1]

var time = t.split(".")[0] //so ms should be ok as is, but time may not be var items = time.split(":")

//loop over length of size - 3 var toAdd = 3-items.length for(var i=1; i <= toAdd; i++) { items.unshift("00") }

//now fix each item - if size of the item is 1, prepend with 0 for(var i=0; i < items.length; i++) { if(items[i].length == 1) items[i] = "0" + items[i] }

var timeStr = items.join(":") return timeStr + "." + ms } </script>

And the output: