tomazos has asked for the wisdom of the Perl Monks concerning the following question:

I ran into an interesting one today. I'm trying to dynamically-size the number of rows in an 80-char wide TEXTAREA such that the default content just fits inside it.

# pass in multi-paragraph English text sub calculate_rows_from_content($) { my ($content) = @_; # hard wrap $content =~ s/([^\n]{80})/$1\n/g; # count newlines + 3 my $rows = 3; $rows++ while ($blurb =~ /\n/g); return $rows; }

Its pretty good, but not perfect (nor will it ever be without testing the user agent because different browsers hide and show the scrollbar when the content fits, changing the real width, sigh).

Wondering if anyone has a more accurate one? This one doesn't take into account whole words getting wrapped - and most likely a bunch of other things.

-Andrew.


Andrew Tomazos  |  andrew@tomazos.com  |  www.tomazos.com

Replies are listed 'Best First'.
Re: Estimating height of TEXTAREA from content
by Your Mother (Archbishop) on Jul 25, 2005 at 03:22 UTC

    This is a JavaScript solution wrapped in perl which I did for a project a couple months ago. merlyn is quite right, of course, about XHTML being unpredictable in different browsers and user settings. I usually do percentage and em based layouts to try to compensate for this but there is no perfect solution.

    You can transfer the "algorithm" to perl code pretty easily. It's just trying to get the text area somewhere between 3 and (update 42) 40 ems high and fit the text inside as well as possible. Takes into account character count and line breaks and tries to get a reasonable middle ground. You can play with it dynamically and salt the settings and CSS to taste.

    use CGI qw(:standard); print header(), start_html(-title => 'Textarea madness!', -script=> <<'EndJS', function fixTextarea ( elemId ) { var box = document.getElementById(elemId); var height = Math.floor( box.value.length / 50 ); var newlines = box.value.match(/(\n)/g); if ( newlines ) height += Math.floor( newlines.length * .7 ) + 3; if ( height < 3 ) height = 3; if ( height > 40 ) height = 40; box.style.height = height + 'em'; } EndJS ), h2("Textarea with JavaScript assisted dynamic resize"), start_form(), textarea( -style => 'width:40em;line-height:120%;overflow:auto;', -id => 'response', -onfocus => "fixTextarea('response')", -onkeypress => "fixTextarea('response')", -name => 'response', ), script({-type=>'text/javascript'}, # call it up front "fixTextarea('response')" ), end_form();
Re: Estimating height of TEXTAREA from content
by merlyn (Sage) on Jul 25, 2005 at 01:50 UTC
    How can you know what font and font size and line spacing the browser is using? I think you're going to have to redefine your needs before you have a satisfactory solution.

    -- Randal L. Schwartz, Perl hacker
    Be sure to read my standard disclaimer if this is a reply.

      The width and height of a TEXTAREA is specified in characters, not pixels.

      Plus, I set the font size to monospace 10pt with CSS, so its guaranteed to be monospace (which is the default anyway).

      (You can see it in action here if you are curious.)

      Anyway, let me restate: Given an 80-character soft-wrapping of a multi-paragraph scalar of English words in a monospace font ($content), what will the height of it be in characters ($rows)?

      -Andrew.


      Andrew Tomazos  |  andrew@tomazos.com  |  www.tomazos.com
        Given an 80-character soft-wrapping of a multi-paragraph scalar of English words in a monospace font ($content), what will the height of it be in characters ($rows)?

        Wrap it yourself and count the lines:

        use Text::Wrap; my $rows = split("\n", fill('','', $content););