Input text sizing function I have this jQuery function I wrote up to set the size of an input based off of its data. In this case I have already figured out the widths for each character based off of a 12px font size for Helvetica.

It's not super flexible or anything, but I would like to know if there is any good way to take what I have and maybe make it more elegant (or fewer lines of code).

HTML:

&lt;input value="Some really long string about nothing important"" /&gt;


CSS: 

body {
    font-family:Helvetica;
    font-size:12px;
}
span {
    padding:0;
    margin:0;
}
input {
    border:0;
}


JavaScript / jQuery:

// Helvetica, 12px or 1.2em at 62.5%
var str = $('input').val();
var length = str.length;

var charWidth = 0;
for ( var i = 0; i &lt; length; i++ )
{
    console.log(str[i]);

    if ( str[i] == "f" || 
         str[i] == "i" || 
         str[i] == "I" || 
         str[i] == "j" || 
         str[i] == "l" || 
         str[i] == "t" 
       )
    {
        charWidth += 3;
    }
    if ( str[i] == "r" )
    {
        charWidth += 4;
    }
    if ( str[i] == "v" || 
         str[i] == "x" || 
         str[i] == "y" || 
         str[i] == "z" 
       )
    {
        charWidth += 5;
    }
    if ( str[i] == "c" || 
         str[i] == "k" ||
         str[i] == " "
       )
    {
       charWidth += 6;
    }
    if ( str[i] == "a" || 
         str[i] == "A" || 
         str[i] == "b" || 
         str[i] == "d" || 
         str[i] == "e" || 
         str[i] == "F" || 
         str[i] == "g" || 
         str[i] == "h" || 
         str[i] == "J" || 
         str[i] == "L" || 
         str[i] == "n" || 
         str[i] == "o" || 
         str[i] == "p" || 
         str[i] == "q" || 
         str[i] == "s" || 
         str[i] == "T" || 
         str[i] == "u" || 
         str[i] == "V" || 
         str[i] == "X" || 
         str[i] == "Y" || 
         str[i] == "Z" ||
         str[i] == "0" ||
         str[i] == "1" ||
         str[i] == "2" ||
         str[i] == "3" ||
         str[i] == "4" ||
         str[i] == "5" ||
         str[i] == "6" ||
         str[i] == "7" ||
         str[i] == "8" ||
         str[i] == "9" 
       )
    {
        charWidth += 7;
    }
    if ( str[i] == "B" ||
         str[i] == "E" || 
         str[i] == "K" || 
         str[i] == "P" || 
         str[i] == "S" 
       )
    {
        charWidth += 8;
    }
    if ( str[i] == "C" || 
         str[i] == "D" || 
         str[i] == "G" || 
         str[i] == "H" || 
         str[i] == "M" || 
         str[i] == "N" || 
         str[i] == "O" || 
         str[i] == "Q" || 
         str[i] == "R" || 
         str[i] == "U" || 
         str[i] == "w" 
       )
    {
        charWidth += 9;
    }

    if ( str[i] == "m" || str == "W")
    {
        charWidth += 11;
    }
}

$('input').css({'width': charWidth});


jsFiddle
Here's how you could use a table array for the widths.  I didn't fill in all the character widths (I just did lowercase) because it's tedious to build, but you can extend it to contain all the typeable characters that you want to support.  I also made it a jQuery method that you can call like this: 

$("input").autoSize();


Here's the code (also in a jsFiddle):

(function() {
    var widths = [
     // a, b, c, d, e, f, g
        7, 7, 6, 7, 7, 3, 7,
     // h, i, j, k, l, m, n
        7, 3, 3, 6, 3, 11, 7,
     // o, p, q, r, s, t, u
        7, 7, 7, 4, 7, 3, 7,
     // v, w, x, y, z
        5, 9, 5, 5, 5
    ];

    // character code our table starts with
    var lowWidth = 97;

    $.fn.autoSize = function() {
        return this.each(function() {
            var val = this.value;
            var totalWidth = 0, charIndex, ch;
            for (var i = 0, len = val.length; i &lt; len; i++) {
                // get char code and see if it's in our width table
                charIndex = val.charCodeAt(i) - lowWidth;
                ch = val.charAt(i);
                if (charIndex &gt;= 0 &amp;&amp; charIndex &lt; widths.length) {
                    totalWidth += widths[charIndex];
                } else if (ch == ' ') {
                    // special case for space char 
                    // until the table contains all codes we need
                    totalWidth += 6;
                }
            }
            $(this).css("width", totalWidth + "px");
        });
    }
})();




FYI, jQuery will also measure the natural width of any DOM element for you so you could also have a span that is styled with the right font that you insert this text into and then ask jQuery what it's width is.  jQuery will temporarily make it position absolute (so it will layout to it's natural width) and then let the browser tell you how wide it is.  This would be much, much more accurate than what you are doing.

Letting jQuery measure it for you would look like this:

$.fn.autoSize = function() {
    var testItem = $("#testWidth");
    return this.each(function() {
        // put the text into our test span
        testItem.text(this.value);
        $(this).width(testItem.width());
    });
}


And, you'd have appropriate CSS for a testItem span (see the jsFiddle demo for details):

jsFiddle demo: http://jsfiddle.net/jfriend00/jQ93f/