- Home
- Blog
- Web Design Build an Elastic Textarea with Ext JS
Build an Elastic Textarea with Ext JS
- 7 min. read
-
William CraigCEO & Co-Founder
- President of WebFX. Bill has over 25 years of experience in the Internet marketing industry specializing in SEO, UX, information architecture, marketing automation and more. William’s background in scientific computing and education from Shippensburg and MIT provided the foundation for MarketingCloudFX and other key research and development projects at WebFX.
Since it was first featured on Facebook, elastic textareas – <textarea>
elements that automatically expand or shrink depending on how much text the user inputs – has become one of the coolest functional UI effects on the web. In this article, I will guide you through the re-creation of this astonishing effect using Ext JS, and I bet you that you will be surprised to see how easy it is to do it.
Live Demo
Check out the example of what we will be creating by clicking on the following link.
What you will need
For this tutorial, we will use the Ext JS JavaScript framework – my favorite framework for cross-browser web application development. I will explain the mechanics step by step so that if you prefer, you can implement the same programming logic using another JavaScript framework/library or with just JavaScript. Only the Ext Core will be needed in this example.
What is Ext JS?
Ext JS describes itself as being a “cross-browser JavaScript library for building rich internet applications“. Although it’s true, this description is too succinct to describe this excellent JavaScript framework’s power and capabilities. It’s the perfect tool for creating Rich Internet Applications (RIA): it has a commanding effects library and an awesome GUI toolkit, providing you with tons of components that mimic desktop applications’ fluidity and complexity on the web. Ext JS is available in two flavors: Ext Core and Ext JS.
Ext Core is the “lite version” of Ext JS, offering the same kind of functionalities you can find in other popular JS frameworks (like jQuery or MooTools).
It’s licensed under the very permissive MIT license. Some functions that are available in Ext JS are not available in Ext Core though – but in our instance, it’s quite alright.
Ext JS is packed with a lot of extra features and lots of GUI gadgets. You can get it under one of the two licenses: under a GPL or a commercial license that waives the GPL restrictions. It’s extremely well documented with tons of demos and an easy to follow manual.
It also has great community support, although they can be a bit harsh to beginners who don’t first search if their question has been answered already before asking questions. If you’re interested in learning about Ext JS more fully, check out this great tutorial that is available here.
The Issue
Unfortunately, there is no textarea.contentHeight
or similar method, so forget about a direct way to get the text height. “So how do I make the textarea
grow and shrink?” A possible approach to find a textarea
‘s height is to get the font size and textarea width and count the number of characters typed.
But then when you press the Enter key your calculations are messed up. “Ok, that’s not a problem… I can put the Enter key into the equation” you might think, but then you have to think about CSS formatting (i.e.
padding, line height, or font size). You see how this can become a nightmare in no time?
Don’t despair: there is an easy way using Ext JS!
The Trick
To make the textarea
grow or shrink, you need to get its content’s height and take into account the CSS styles that affect text formatting like font-size
, line-height
, etc. The trick to get text height is to mimic the textarea
contents in a hidden div
.
To get a decent effect, we will also limit the textarea minimum and maximum sizes, there is no beauty in a 0-px height textarea
. Alright, it’s time to get our hands dirty.
Step 1: Laying down the foundations
First step is to create a function and set up some control variables; we shall name this function elasticTextArea
. We also declare two extra functions that allow us to get and set all CSS styles at once.
function elasticTextArea (elementId){ /* * This are two helper functions, they are declared here for convenience * so we can get and set all styles at once and because they are not * available in ext-core only in Ext JS */ //available in Ext JS (not ext-core) as element.getStyles function getStyles(el, arguments){ var ret = {}; total = arguments.length; for (var n=0; n< len;) { el.setStyle(styles[i++], styles[i++]); } } else if (Ext.isObject(styles)) { el.setStyle(styles); } } } //minimum and maximum textarea size var minHeight = 10; var maxHeight = 300; //increment value when resizing the textarea var growBy = 20 ; var el = Ext.get(elementId);
Step 2: Get the textarea CSS styles
To get an accurate measurement, we need to get the textarea CSS styles that affect text formatting, and they are:
padding
font-size
(and other font styles)font-family
line-height
width
//get textarea width var width = el.getWidth(); //current textarea styles var styles = el.getStyles('padding-top', 'padding-bottom', 'padding-left', 'padding-right', 'line-height', 'font-size', 'font-family', 'font-weight', 'font-style'); //store textarea width into styles object to later apply them to the div styles.width = width +'px'; //hide the textarea scrool to avoid flickering el.setStyle('overflow', 'hidden');
Step 3: Create the hidden div
And here’s where the magic begins. We start by creating a hidden container for the textarea contents. We set its position to absolute
— this way, the div
is removed from the layout’s flow and positioned outside the visible area of the browser.
Note: setting its visibility
CSS attribute to hidden
or its display
to none
causes some browsers not to recalculate its height, that’s why we opted for this method. We also instruct the textarea to recalculate its height by re-running this function on every key stoke; another method is to run it at a specific interval, but I find it to be more resource-intensive and less elegant that way.
//create the hidden div only if does not exists if(!this.div){ //create the hidden div outside the viewport area this.div = Ext.DomHelper.append(Ext.getBody() || document.body, { 'id':elementId + '-preview-div', 'tag' : 'div', 'style' : 'position: absolute; top: -100000px; left: -100000px;' }, true); //apply the textarea styles to the hidden div Ext.DomHelper.applyStyles(this.div, styles); //recalculate the div height on each key stroke el.on('keyup', function(){ elasticTextArea(elementId); }, this); }
Step 4: Copy textarea contents to the hidden div and get its height
To ensure a correct measurement, we replace some special characters with their HTML character entities and also append a space (' '
) string to the new line to force its representation.
/* clean up textarea contents, so that no special chars are processed * replace with so that the enter key can trigger a height increase * but first remove all previous entries, so that the height measurement * can be as accurate as possible */ this.div.update( el.dom.value.replace(//, '') .replace(/<|>/g, ' ') .replace(/&/g,"&") .replace(/ /g, '') ); //finally get the div height var textHeight = this.div.getHeight();
Step 5: Resize the textarea
In the last step, we give the textarea its new height.
//enforce textarea maximum and minimum size if ( (textHeight > maxHeight ) && (maxHeight > 0) ){ textHeight = maxHeight; el.setStyle('overflow', 'auto'); } if ( (textHeight < minHeight ) && (minHeight > 0) ){ textHeight = minHeight ; } //resize the textarea el.setHeight(textHeight + growBy , true); }
Try it out
Wasn’t that simple? Save the JavaScript code we wrote as elasticTextarea.js or download the source, include Ext Core and the JavaScript library, and have fun.
To include the JS libraries:
<script type="text/JavaScript" src="ext-core/ext-core.js"></script> <script type="text/JavaScript" src="elastic.js"></script>
The HTML for the text area:
<textarea id="ta"></textarea>
To call the function (‘ta’ being the ID of the textarea
):
<script type="text/JavaScript"> elasticTextArea("ta"); </script>
Conclusion
The purpose of this article is to introduce you to Ext JS. If you know your JavaScript well, you might find that this code will only work for one textarea. If you’d like a more robust and flexible solution, get the Ext JS plugin that can be found over at my site.
Stay tuned for more Ext JS tutorials here on Six Revisions, written by me. Future tutorials will cover Ext JS plugins, and talk about more cool and easy-to-create UI effects using Ext JS RIA framework.
Related Content
- A Guide on Advanced Logging and Benchmarking with FirePHP
- 40 Exceptional jQuery Interface Techniques and Tutorials
- 10 Promising JavaScript Frameworks
-
President of WebFX. Bill has over 25 years of experience in the Internet marketing industry specializing in SEO, UX, information architecture, marketing automation and more. William’s background in scientific computing and education from Shippensburg and MIT provided the foundation for MarketingCloudFX and other key research and development projects at WebFX.
-
WebFX is a full-service marketing agency with 1,100+ client reviews and a 4.9-star rating on Clutch! Find out how our expert team and revenue-accelerating tech can drive results for you! Learn more
Make estimating web design costs easy
Website design costs can be tricky to nail down. Get an instant estimate for a custom web design with our free website design cost calculator!
Try Our Free Web Design Cost CalculatorWeb Design Calculator
Use our free tool to get a free, instant quote in under 60 seconds.
View Web Design CalculatorMake estimating web design costs easy
Website design costs can be tricky to nail down. Get an instant estimate for a custom web design with our free website design cost calculator!
Try Our Free Web Design Cost Calculator