1

I need to specify number of characters contained per line in a textarea element (Link to fiddle).

This is the horror I'm witnessing:

enter image description here

So cols="50" actually gives me following row lengths:

        | Without scroll | With scroll
Chrome  50                 47
FF      52                 50

What I actually meant with cols="50" is that I want the textarea to hold exactly 50 characters per line. How I can achieve this so that it works in all major browsers?

EDIT: I would also like to point out that in the real page the total number of characters in a textarea is not limited so y-scrolling must be possible. Whether or not line breaks are automatically included by a textarea (or equivalent element) doesn't matter since the text is later split into rows containing maximum of 50 characters before sending them to the server with ajax post.

Mika Lammi
  • 1,278
  • 9
  • 21
  • 1
    How about trying to accomplish this with JavaScript? – Matias Cicero Oct 24 '14 at 12:34
  • @MatiCicero JavaScript solution is fine if that gets the problem solved. Added javascript tag. – Mika Lammi Oct 24 '14 at 12:45
  • What do you mean by “the textarea to hold exactly 50 characters per line”? Are you referring to the display of data as in the example, or user input? What should happen if the user tries to type a longer line? Hard wrapping? Soft wrapping? Truncation? Beep beep? – Jukka K. Korpela Oct 24 '14 at 12:59
  • Strikes me as a Firefox bug more than anything. – James Donnelly Oct 24 '14 at 13:06
  • @JukkaK.Korpela I'm referring to the display only. Value of the field is processed in a way that the length of the actual "row strings" doesn't really matter. I would prefer soft or hard wrapping. – Mika Lammi Oct 24 '14 at 13:16
  • “Soft” vs. “hard” refers to the issue whether line breaks appear in the display only or are included in the form data sent when the form is submitted. It is unclear whether this is meant to be submitted at all, or otherwise processed. Is this about display only (so that you could use another HTML element instead of `pre` if that turns out to be more suitable)? – Jukka K. Korpela Oct 24 '14 at 13:38
  • @JukkaK.Korpela It will be sent with ajax post. I could use different element as long as it provides basic textarea funtionality like copy, paste and y-scrolling. Whether or not the element automatically inclcudes line breaks does not matter. Row length is limited for visual purposes. – Mika Lammi Oct 24 '14 at 13:51
  • This appears to be a Chrome bug/oddity more than anything, since it is natural to expect that `cols=50` means 50 characters when vertical scroll bar is present; this is how Firefox and IE implement it. I’m afraid the only way to achieve this in Chrome is to have JavaScript code that reacts to any input event by checking that all lines are at most 50 characters and breaks them if not. And you would need to set `cols` to a larger value for that. – Jukka K. Korpela Oct 24 '14 at 18:19

2 Answers2

1

Heres how you can do it in javascript:

<script>
    var textareas = document.getElementsByTagName("textarea");

    for(var i = 0; i < textareas.length; ++i){
        textareas[i].addEventListener("input", handleInput);
        textareas[i].cols += 3;
        handleInput(null, textareas[i]);
    }

    function handleInput(event, area){
       if(area === undefined) area = this;
       area.value = fixText( area.value, area.value.length, area.cols-3);
    }

    function fixText(text, length, limit){
        var counter = 0;
        for(var i = 0; i < length; ++i){
           var currChar = text[i];
           counter++;
            if(currChar === "\n"){
                counter = 0;
            } else if(counter > limit){
                text = text.substring(0,i) + "\n" + text.substring(i, text.length); 
                counter = 0;
            }        
        }
        return text;
    }

Here i use the col attribute of the textarea and add a linebreak every VALUE_OF_COL characters that doesn't contain a linebreak.

Check it out here: JSFiddle

Johan Karlsson
  • 6,419
  • 1
  • 19
  • 28
  • This is actually the approach I tried at first. I dismissed it as overly complex for the task because there are some caveats like input event not firing in some versions of IE when text is pasted. Also the caret position jumps to the end when the line at the middle of the text is edited. I will mark this as an answer if there is no simpler solution. – Mika Lammi Oct 24 '14 at 14:59
1

It seems this issue is only in Chrome, so you could do something like this:

<script>
    window.onload = function(){
        textareas = document.getElementsByTagName("textarea");
        var isChrome = navigator.userAgent.indexOf("Chrome") != -1;
        for(var i = 0; i < textareas.length; ++i){
            if(isChrome){
                textareas[i].style.width = textareas[i].offsetWidth + textareas[i].cols/3 + "px";
            }
        }
    }    
</script>

Check it out here: JSFiddle

Johan Karlsson
  • 6,419
  • 1
  • 19
  • 28