1

So, I have an input and I want it to adjust its width to its content. For now, I use the code like this:

var adjustWidthToContent = function()
{
 var inputLength = $(this).val().length;
 // the minimum 1em width allows to start typing when the input is empty
 $(this).width(Math.max(1, inputLength*0.7) + "em");
};
$("input").on("input",adjustWidthToContent);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<input type='text' />

This works ok for desktop, but I'd like to make this more accurate (the 0.7 coefficient is a "hacky" one and the one which calculates the real width is obviously different for different symbols). Try to type multiple symbols: you'll see that the gap grows. Fixing that will be especially helpful for mobile interface where I don't want any extra space get occupied by the empty part of the input element.

Obviously, I need to use something different than inputLength. How do I get the "actual" width of the text inside the input?


PS here's what I used, based on suggestions:

$.fn.textWidth = function () {
 if (!$.fn.textWidth.fakeEl)
  $.fn.textWidth.fakeEl = $('<span>').hide().appendTo(document.body);
 $.fn.textWidth.fakeEl.text(this.val() || this.text()).css('font', this.css('font'));
 return $.fn.textWidth.fakeEl.width();
};
var adjustWidthToContent = function()
{
 var textWidth = jQuery(this).textWidth();
 var defaultWidth = 20;
 $(this).width( (textWidth || defaultWidth) + 'px');
};
$("input").on("input",adjustWidthToContent).trigger("input");
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<input type='text' />

PPS this does need some elaboration for adjustWidthToContent to be applicable so several text fields, though.

YakovL
  • 7,557
  • 12
  • 62
  • 102

1 Answers1

1

The solution is to create a fake span, put the inputted text inside, get the size of this span and apply to your input box.

I put 7px more to make room for the " " when the user press "space" to go to another word and the input won't suffer.

I also defined that the default size for the input will be 50px if there's nothing inside.

Html

<input id="my-input" type='text' />

JS

$.fn.textWidth = function (text, font) {
    if (!$.fn.textWidth.fakeEl) $.fn.textWidth.fakeEl = $('<span>').hide().appendTo(document.body);
    $.fn.textWidth.fakeEl.text(text || this.val() || this.text()).css('font', font || this.css('font'));
    return $.fn.textWidth.fakeEl.width();
};

$('#my-input').on('input', function () {
    var textWidth = $(this).textWidth();
    var defaultValue = 50;
    $('#' + this.id).width( (textWidth == 0 ? defaultValue : textWidth + 7)  + 'px');
}).trigger('input');

I did this following one of the answers of this post: Calculating text width

Hope it helps you! Cheers

Community
  • 1
  • 1
andrepaulo
  • 816
  • 11
  • 24
  • Right, thanks, I've adapted the code a little, but it works fine (I'll add my code to the initial post) – YakovL Sep 16 '16 at 15:54