Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Increase size of input field as text is entered

I have a fairly simple CSS question. I have an input text field, and on page load i would like it to be 150px in width.

However, as the user enters some text, if the text is greater than 150px in width, then the width should auto adjust.

Here's a plunker:

http://plnkr.co/edit/ig0BQrJDiEtXKV8zJ2w2?p=preview

HTML:

<input class="input-class" type="text" placeholder="Placeholder">

CSS:

.input-class-2 {
  -moz-border-bottom-colors: none;
  -moz-border-left-colors: none;
  -moz-border-right-colors: none;
  -moz-border-top-colors: none;
  border-color: -moz-use-text-color -moz-use-text-color #ef8e80;
  border-image: none;
  border-style: none none dashed;
  border-width: 0 0 1px;
  color: #ef8e80;
  cursor: pointer;
  font-family: Gotham-Book;
  font-size: 18px;
  min-width: 150px;
}

I assumed min-width would do this.

like image 804
Oam Psy Avatar asked Apr 22 '15 07:04

Oam Psy


2 Answers

There currently is no way to achieve this with pure CSS, perhaps once calc and attr can be used in combination, but not currently. So we have to fall back to JavaScript.

There isn't any real reason to use jQuery for this. You can argue that your "concerns should be separated" i.e. code should be separate from mark-up, but that is easy to do using addEventListener. However, if I'm dealing with one off small bits of JavaScript it tends to be faster — in terms of implementation, page render and even for those trying to track down what is making the input behave strangely — to use inline event listeners.

<input type="text" 
       style="min-width: 150px;" 
       onkeyup="this.size = Math.max(this.value.length, 1)" 
/>

or:

<input type="text" 
       style="width: 150px;" 
       onkeyup="
         this.style.width = '1px';
         this.style.width = (
             this.scrollWidth &gt; 140
           ? this.scrollWidth + 10
           : 150
         )+'px';
       " 
/>

Disclaimer: Obviously if you are implementing many of these inputs it is far better to code a generalised function to handle them. Plus it is always far better to avoid inline style by using a stylesheet.

/**
 * Directly setting the size attribute, with minWidth
 */
function autosize(elm, minWidth){
  var keyup = function(e){
    var t = e.target || e.srcElement;
    var v = Math.max(t.value.length, 1);
    t.setAttribute
      ? t.setAttribute('size', v)
      : (t['size'] = v)
    ;
  };
  elm.style.minWidth = minWidth+'px';
  elm.addEventListener
    ? elm.addEventListener('keyup', keyup)
    : elm.attachEvent('onkeyup', keyup)
  ;
};

The size attribute is by far the most obvious choice, although you can directly set the width — if you prefer — using scrollWidth.

/**
 * Directly setting width, with minWidth
 */
function autosize(elm, minWidth){
  var keyup = function(e){
    var t = e.target || e.srcElement;
    t.style.width = '1px';
    t.style.width = t.scrollWidth + 'px';
  };
  elm.style.minWidth = minWidth+'px';
  elm.addEventListener
    ? elm.addEventListener('keyup', keyup)
    : elm.attachEvent('onkeyup', keyup)
  ;
};

You can trigger either of these functions by passing your target element in as the first argument. There are a number of ways of finding your element, the easiest and most universal being getElementById. Although you will only be able to find your element if it has been parsed by the browser, so the script tag you use — to run the following code — will either have to be placed below the element in the mark-up i.e. bottom of <body> (preferable), or after waiting for window load, or DOM readiness.

autosize( document.getElementById('myinput'), 150 );

/**
 * Directly setting width, with minWidth
 */
function autosize1(elm, minWidth){
  var keyup = function(e){
    var t = e.target || e.srcElement;
    t.style.width = '1px';
    t.style.width = t.scrollWidth + 'px';
  };
  elm.style.minWidth = minWidth+'px';
  elm.addEventListener
    ? elm.addEventListener('keyup', keyup)
    : elm.attachEvent('onkeyup', keyup)
  ;
};

/**
 * Directly setting the size attribute, with minWidth
 */
function autosize2(elm, minWidth){
  var keyup = function(e){
    var t = e.target || e.srcElement;
    var v = Math.max(t.value.length, 1);
    t.setAttribute
      ? t.setAttribute('size', v)
      : (t['size'] = v)
    ;
  };
  elm.style.minWidth = minWidth+'px';
  elm.addEventListener
    ? elm.addEventListener('keyup', keyup)
    : elm.attachEvent('onkeyup', keyup)
  ;
};

autosize1( document.getElementById('a'), 150 );
autosize2( document.getElementById('b'), 150 );
<p>Each input is using a different implementation:</p>
<input type="text" 
       style="min-width: 150px;" 
       onkeyup="this.size = Math.max(this.value.length, 1)" 
/><br />
<input type="text" 
       style="width: 150px;" 
       onkeyup="
         this.style.width = '1px';
         this.style.width = (
             this.scrollWidth &gt; 140
           ? this.scrollWidth + 10
           : 150
         )+'px';
       " 
/><br />
<input type="text" id="a" /><br />
<input type="text" id="b" /><br />
like image 97
Pebbl Avatar answered Nov 13 '22 23:11

Pebbl


You can try like this:

function resizeInput() {
    $(this).attr('size', $(this).val().length);
}

$('input[type="text"]')
    .keyup(resizeInput)
    .each(resizeInput);

JSFIDDLE DEMO

There is one more alternative of using the

<span contenteditable="true">Some Text</span>

instead of using Input tags.

JSFIDDLE DEMO

like image 39
Rahul Tripathi Avatar answered Nov 13 '22 22:11

Rahul Tripathi