Adjustable Form Text Area with the contenteditable Tag

How to create a dynamic text area without breaking form styles

Programming code by Pixnio is licensed under Creative Commons Zero

As developers, we have to deal with non-standard form inputs while creating new objects. One of the hurdles is handling a large amount of text in a single text area. The challenge is how should the form look given a great deal of text from the user. The standard textarea tag is the typical go-to for this problem. Even that has its limitations if you want to maintain the styles of your form and also have a good user experience. We dealt with this exact problem on a recent project at Collective Idea. Here is the trail of research and the solution we landed on.

What we wanted was a textarea that would expand as the user typed the content. This seemed easy enough, but as we began our research we found a large amount of seemingly “workaround” solutions. Basically lots and lots of JavaScript that was doing a bunch of calculations for height. Solutions that looked a whole lot like this one:

var span = $('<span>').css('display','inline-block')
                      .css('word-break','break-all')
                      .appendTo('body').css('visibility','hidden');
function initSpan(textarea){
  span.text(textarea.text())
      .width(textarea.width())
      .css('font',textarea.css('font'));
}
$('textarea').on({
    input: function(){
       var text = $(this).val();      
       span.text(text);      
       $(this).height(text ? span.height() : '1.1em');
    },
    focus: function(){           
       initSpan($(this));
    },
    keypress: function(e){
       //cancel the Enter keystroke, otherwise a new line will be created
       //This ensures the correct behavior when user types Enter
       //into an input field
       if(e.which == 13) e.preventDefault();
    }
});

While this could have achieved what we wanted, this example has a lot of code and logic to wrap your mind around.

We then realized that adding contenteditable="true" to a div would achieve the user experience we desired. The obvious problem is this is not a form input. Because this accomplished what we were looking for from a user experience standpoint, we decided to travel further down this path. We ended up using a hidden input field for capturing the value of the div. Using a little bit of JavaScript to set the value, this was achievable. It also requires a little bit of CSS to get the desired behavior.

JavaScript

$(document).ready(function() {
  $(document).on("submit", "form#new_expandable", function(e) {
    e.preventDefault();

    var contents = $(".expandable-input").html();

    $('input#expandable').val(contents);
    this.submit();
  });
});

HTML

<form id="new_expandable">
  <div contenteditable="true" class="expandable-input"></div>
  <input type="hidden" id="expandable"></input>
  <input type="submit"></input>
</form>

CSS

.expandable-input {
  min-height: 18px;
  height: auto;
  width: 200px;
  border: 1px solid;
}

Collective Idea - expandable.gif

Really, there are different ways to handle this scenario, but we thought this solutions was the most concise and easy to understand. Let us know of anyways you have solved this problem in the past.

Photo of Cameron Bass

Cam joined Collective Idea as an intern, instantly falling in love with the endless potential of developing software. He’s now a full-time team member, working on a variety of client and internal projects.

Photo of Victoria Gonda

Victoria is a software developer working on mobile and full stack web applications. She enjoys exchanging knowledge through conference talks and writing.

Comments:


Post a Comment

(optional)
(optional — will be included as a link.)