Magento is 2008 vintage as far as the checkout goes so you might as well stick to 2008 vintage prototype.
Like many others I too have often wanted to set names in forms to be Proper Case but implementation can be tricky. Personally I prefer backend name tidying, this is because the Google-able code to fix names (e.g. MacDonald) is better in PHP land to JS.
Here is an example of how to get things working if you do want to go full frontend. In this example just the name widget box is fixed (addresses can be just block capitalised in some use cases).
If you copy the name widget template over to your theme, e.g. to:
frontend/package/theme/template/customer/widget/name.phtml
Now add a simple script to the end:
<script>
function toTitleCase(string)
{
return string.toLowerCase().replace(/_/g, ' ').replace(/\b([a-z\u00C0-\u00ff])/g, function (_, initial) {
return initial.toUpperCase();
}).replace(/(\s(?:de|a|o|e|da|do|em|ou|[\u00C0-\u00ff]))\b/ig, function (_, match) {
return match.toLowerCase();
});
}
$('getFieldId('firstname')?>').observe('blur', function(e) { (this).setValue(toTitleCase((this).getValue())); });
$('getFieldId('lastname')?>').observe('blur', function(e) { (this).setValue(toTitleCase((this).getValue())); });
I don't think it is necessary to do this on the front end, in the back end you can have a helper function to make a name title case using a better algorithm, here is an example:
public function titleCase($string)
{
$word_splitters = array(' ', '-', "O'", "L'", "D'", 'St.', 'Mc');
$lowercase_exceptions = array('the', 'van', 'den', 'von', 'und', 'der', 'de', 'da', 'of', 'and', "l'", "d'");
$uppercase_exceptions = array('III', 'IV', 'VI', 'VII', 'VIII', 'IX');
$string = strtolower($string);
foreach ($word_splitters as $delimiter) {
$words = explode($delimiter, $string);
$newwords = array();
foreach ($words as $word) {
if (in_array(strtoupper($word), $uppercase_exceptions)) {
$word = strtoupper($word);
} elseif (!in_array($word, $lowercase_exceptions)) {
$word = ucfirst($word);
}
$newwords[] = $word;
}
if (in_array(strtolower($delimiter), $lowercase_exceptions)) {
$delimiter = strtolower($delimiter);
}
$string = implode($delimiter, $newwords);
}
return $string;
}
Then, in your form controllers you can then parse the post data, e.g.:
$lastname = Mage::helper('whatever')->titleCase($post['lastname']);
I would advise against the jQuery way, the Prototype way achieves what you need to do.