views:

624

answers:

5

If I've got a textarea like this:

<textarea id="foo" cols=80 wrap="hard"></textarea>

Is there any way, using JavaScript, to grab the hard-wrapped text?

I've tried the obvious $("#foo").val(), but that returns the unwrapped text.

For example, if the textarea is:

<textarea id="bar" cols=5 wrap="hard">a b c d e f</textarea>

The browser will wrap the text to:

a b c
d e f

And I was some way to grab that text – "a b c\nd e f" (which, because of wrap=hard, is the text that would be sent if the <textarea… was submitted in a <form…).

A: 

I don't think it's possible out of the box You could wrap the text yourself using textarea's cols value. From the HTML point of view the text in textarea is not wrapped. It's just how it's being displayed for you to be able to read it better.

PS. If you are using jQuery you should use $('#foo') instead of $('[id=foo]') selector as it's much faster (and shorter).

RaYell
The wrapping is *mostly* for display purposes… Except when `wrap=hard` - then newlines are added to the text when it is submitted (and they are added "properly" - ie, the browser knows where it has created the "soft" line breaks, so it just converts those to hard breaks).
David Wolever
(which is the problem with wrapping the text myself - I'd run the risk of wrapping it differently from the browser, causing mass panic and confusion)
David Wolever
(and thanks for the jQuery tip)
David Wolever
+1  A: 
Gaby
Sorry, this doesn't work: `t = $("<textarea cols='5' wrap='hard'>a b c d e f g h i</textarea>"); console.log($('<div/>').append(t.clone()).html())` produces `"<textarea cols="5" wrap="hard">a b c d e f g h i</textarea>"`, not `"a b c\nd e f\ng h i"` (which is what I'm after)
David Wolever
misunderstood .. do not be so harsh :D, look at the edit section in my answer ..
Gaby
Sorry, `.text()` doesn't work either: `$("<textarea cols='5' wrap='hard'>a b c d e f g h</textarea>").text()` ==> `"a b c d e f g h"` :(
David Wolever
You want to automatically create newlines where the text wraps (due to the size of the textarea) ?
Gaby
Yea - see my edits to the question.
David Wolever
OK .. apologies for the misunderstanding.. this is not possible out of the box .. best method is what Ty W suggested in his answer ..
Gaby
@David Wolever, take a look at my latest suggestion .. It seems to work in my test, but do not know if it is an option in your case..
Gaby
Thanks Gaby - yea, that does seem like the only reliable way to do it.
David Wolever
A: 

It's a bit of a hack, but you could create a script on the server that prints out whatever is posted to it in some format (JSON, plain text, whatever suits you) and post your textarea to that script via AJAX whenever you need to get the contents of it.

Ty W
I'd thought about that… But I didn't think it was possible to call the `submit` method on a form without actually reloading the page (and calling `form.submit` is the only way I know to hard-wrap the text). Is there some other way to submit a form without a page reload?
David Wolever
Using an Ajax call will not reload the page .. that is the whole idea of Ajax.. Check out jQuery's Ajax feature ..
Gaby
Yes, but using an Ajax won't cause the text to wrap either. For example, try using Firebug to set `wrap=hard` on this form: http://jquery.malsup.com/form/ then try posting it - the posted text won't include line breaks.
David Wolever
+1  A: 

Since the formatting is done by the browser on submit, your best bet will be to have the browser submit, but to a location of your choice such as an iframe where you can extract the formatted text from the form or url parameters.

<html><body>
    <script type="text/javascript">
        function getURLParameter(qs, name)
        {
          var pattern = "[\\?&]"+name+"=([^&#]*)";
          var regex = new RegExp( pattern );
          var res = regex.exec( qs );
          if (res == null)
            return "";
          else
            return res[1];
        }
        function getHardWrappedText(){
            if (top.location.href !== window.location.href) return;
            var frm_url = document.getElementById('ifrm').contentDocument.URL;
            if (frm_url.indexOf('http') < 0) return;
            var text = unescape(getURLParameter(document.getElementById('ifrm').contentDocument.URL, 'bar')).replace(/\+/g,' ');
            alert(text)
        }
    </script>
    <form name="main" method="get" target="ifrm">
        <textarea id="bar" name="bar" cols=5 wrap="hard">a b c d e f</textarea>
        <input type="submit">
    </form>
    <iframe id="ifrm" name="ifrm" onload="getHardWrappedText();" style="display:none;"></iframe>
</body></html>
Chris S
A: 

I'm assuming that you know the dimensions of the text area (if not, you can probably just get them from the DOM).

Use this to split the string. Go to the xth char (in your example the 5th), and see if the next char is a space. If so (or if there are no spaces in the preceding segment), this is where you split. Otherwise, you find the preceding space and split there.

Wrap this in a function and you could add in some recursion to find the nth line.

JGB146
That's trie, it is possible to write my own text wrapping algorithm… But the difficulty with that is that it most likely won't match the browser's algorithm, and mass confusion will abound (eg, the browser might wrap "aaa.bb" to "aaa.\nbb", while my algorithm might wrap it to "aaa.b\nb").
David Wolever
It may end up, though, that this is the way to go… In which case I could add some sort of a 'preview', which would (in my case) be able to reduce confusion.
David Wolever