How to Autosize a Textarea Using Prototype

How to autosize a textarea using Prototype?

Facebook does it, when you write on people's walls, but only resizes vertically.

Horizontal resize strikes me as being a mess, due to word-wrap, long lines, and so on, but vertical resize seems to be pretty safe and nice.

None of the Facebook-using-newbies I know have ever mentioned anything about it or been confused. I'd use this as anecdotal evidence to say 'go ahead, implement it'.

Some JavaScript code to do it, using Prototype (because that's what I'm familiar with):

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<script src="http://www.google.com/jsapi"></script>
<script language="javascript">
google.load('prototype', '1.6.0.2');
</script>
</head>

<body>
<textarea id="text-area" rows="1" cols="50"></textarea>

<script type="text/javascript" language="javascript">
resizeIt = function() {
var str = $('text-area').value;
var cols = $('text-area').cols;

var linecount = 0;
$A(str.split("\n")).each( function(l) {
linecount += Math.ceil( l.length / cols ); // Take into account long lines
})
$('text-area').rows = linecount + 1;
};

// You could attach to keyUp, etc. if keydown doesn't work
Event.observe('text-area', 'keydown', resizeIt );

resizeIt(); //Initial on load
</script>
</body>
</html>

PS: Obviously this JavaScript code is very naive and not well tested, and you probably don't want to use it on textboxes with novels in them, but you get the general idea.

Autosize textarea using prototype?

Here's technique for autosizing a textarea.

Uses pixel height instead of line height: more accurate handling of line wrap if a proportional font is used.
Accepts either ID or element as input
Accepts an optional max height param - useful if you'd rather not let the text area grow beyond a certain size (keep it all on-screen, avoid breaking layout, etc.)
Tested on Firefox 3 and IE6

Code: (plain vanilla Javascript)

function FitToContent(id, maxHeight)
{
var text = id && id.style ? id : document.getElementById(id);
if ( !text )
return;

/* Accounts for rows being deleted, pixel value may need adjusting */
if (text.clientHeight == text.scrollHeight) {
text.style.height = "30px";
}

var adjustedHeight = text.clientHeight;
if ( !maxHeight || maxHeight > adjustedHeight )
{
adjustedHeight = Math.max(text.scrollHeight, adjustedHeight);
if ( maxHeight )
adjustedHeight = Math.min(maxHeight, adjustedHeight);
if ( adjustedHeight > text.clientHeight )
text.style.height = adjustedHeight + "px";
}
}

Demo: (uses jQuery, targets on the textarea i'm typing into right now - if you have Firebug installed, paste both samples into the console and test on this page)

$("#post-text").keyup(function() 
{
FitToContent(this, document.documentElement.clientHeight)
});

Creating a textarea with auto-resize

This works for me (Firefox 3.6/4.0 and Chrome 10/11):

var observe;if (window.attachEvent) {    observe = function (element, event, handler) {        element.attachEvent('on'+event, handler);    };}else {    observe = function (element, event, handler) {        element.addEventListener(event, handler, false);    };}function init () {    var text = document.getElementById('text');    function resize () {        text.style.height = 'auto';        text.style.height = text.scrollHeight+'px';    }    /* 0-timeout to get the already changed text */    function delayedResize () {        window.setTimeout(resize, 0);    }    observe(text, 'change',  resize);    observe(text, 'cut',     delayedResize);    observe(text, 'paste',   delayedResize);    observe(text, 'drop',    delayedResize);    observe(text, 'keydown', delayedResize);
text.focus(); text.select(); resize();}
textarea {    border: 0 none white;    overflow: hidden;    padding: 0;    outline: none;    background-color: #D0D0D0;}
<body onload="init();"><textarea rows="1" style="height:1em;" id="text"></textarea></body>

Textarea Auto height

It can be achieved using JS. Here is a 'one-line' solution using elastic.js:

$('#note').elastic();

Updated: Seems like elastic.js is not there anymore, but if you are looking for an external library, I can recommend autosize.js by Jack Moore. This is the working example:

autosize(document.getElementById("note"));
textarea#note { width:100%; box-sizing:border-box; direction:rtl; display:block; max-width:100%; line-height:1.5; padding:15px 15px 30px; border-radius:3px; border:1px solid #F7E98D; font:13px Tahoma, cursive; transition:box-shadow 0.5s ease; box-shadow:0 4px 6px rgba(0,0,0,0.1); font-smoothing:subpixel-antialiased; background:linear-gradient(#F9EFAF, #F7E98D); background:-o-linear-gradient(#F9EFAF, #F7E98D); background:-ms-linear-gradient(#F9EFAF, #F7E98D); background:-moz-linear-gradient(#F9EFAF, #F7E98D); background:-webkit-linear-gradient(#F9EFAF, #F7E98D);}
<script src="https://rawgit.com/jackmoore/autosize/master/dist/autosize.min.js"></script><textarea id="note">Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.</textarea>

Textarea to resize based on content length

You can check the content's height by setting to 1px and then reading the scrollHeight property:

function textAreaAdjust(element) {
element.style.height = "1px";
element.style.height = (25+element.scrollHeight)+"px";
}
<textarea onkeyup="textAreaAdjust(this)" style="overflow:hidden"></textarea>

How to make textarea automatically resize horizontally to fit entered text?

Given this HTML:

<textarea id="theID" rows=5 cols=15></textarea>

you can try with the following JS + jQuery:

var minCol = $('#theID').attr('cols');;
$('#theID').keyup(updateCols);

function updateCols() {
var lines = $('#theID').val().split(/\n/);
var lineMaxLenght = getLineMaxLenght(lines);
if (lineMaxLenght >= minCol) {
$('#theID').attr('cols', lineMaxLenght);
}
}

function getLineMaxLenght(lines) {
var max = -1;
for (var i = 0; i < lines.length; i++) {
if (lines[i].length > max) {
max = lines[i].length;
}
}
return max;
}

You can improve getLineMaxLenght using some other library

Creating a textarea with auto-resize

This works for me (Firefox 3.6/4.0 and Chrome 10/11):

var observe;if (window.attachEvent) {    observe = function (element, event, handler) {        element.attachEvent('on'+event, handler);    };}else {    observe = function (element, event, handler) {        element.addEventListener(event, handler, false);    };}function init () {    var text = document.getElementById('text');    function resize () {        text.style.height = 'auto';        text.style.height = text.scrollHeight+'px';    }    /* 0-timeout to get the already changed text */    function delayedResize () {        window.setTimeout(resize, 0);    }    observe(text, 'change',  resize);    observe(text, 'cut',     delayedResize);    observe(text, 'paste',   delayedResize);    observe(text, 'drop',    delayedResize);    observe(text, 'keydown', delayedResize);
text.focus(); text.select(); resize();}
textarea {    border: 0 none white;    overflow: hidden;    padding: 0;    outline: none;    background-color: #D0D0D0;}
<body onload="init();"><textarea rows="1" style="height:1em;" id="text"></textarea></body>

Resize text area automatically to show all text on load without scrolling in Blazor

If you are willing to use JSInterop, this will work:

  1. Add a JS function to _Host.cshtml:
...

<script>
ResizeTextArea = function (id) {
var el = document.getElementById(id);
if (el) {
el.style.height = "5px";
el.style.height = (el.scrollHeight + 5) + "px";
}
return true;
}
</script>

  1. In your Blazor component, inject IJSRuntime and add the OnAfterRenderAsync event handler to call the JS function:
@page "/interop"
@inject IJSRuntime jsRuntime

<h1>JSInterop</h1>

<textarea
class="form-control" maxlength="255" style="width:250px;"
@bind="Comment" id="Comments" required>
</textarea>

@code {
public string Comment = "This is test comments for textarea. This is test comments for textarea.";


protected override async Task OnAfterRenderAsync(bool firstRender)
{
await jsRuntime.InvokeAsync<bool>("ResizeTextArea", "Comments");
}
}

Note: the JS function was taken from this SO answer

Resize text area based on content

You can try this solution:

<script>
function textAreaAdjust(o) {
o.style.height = "1px";
o.style.height = (25+o.scrollHeight)+"px";
}
</script>

All you have to do is call the function with passing your textarea

<textarea onkeyup="textAreaAdjust(this)" style="overflow:hidden"></textarea>

Again, this solution come from here, i did not wrote it myself



Related Topics



Leave a reply



Submit