patternjavascriptMinor
Input text sizing function
Viewed 0 times
inputsizingtextfunction
Problem
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:
CSS:
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 < 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"
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:
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 < 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"
Solution
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:
Here's the code (also in a jsFiddle):
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:
And, you'd have appropriate CSS for a testItem span (see the jsFiddle demo for details):
jsFiddle demo: http://jsfiddle.net/jfriend00/jQ93f/
$("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 = 0 && charIndex < 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/
Code Snippets
$("input").autoSize();(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 < 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 >= 0 && charIndex < 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");
});
}
})();$.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());
});
}Context
StackExchange Code Review Q#35784, answer score: 5
Revisions (0)
No revisions yet.