4

i need functionaliy which will have TextArea with

1) maximum total lines- 6 and 
2) in each line there must be maximum of 16 chars
3) if user enters 17th character the cursor should go to the next line 
and user will type in there (the line will be counted)
4) if user reaches to the 7th line it will not allow user to write
5) if user type e.g "Hello, I Love StackOverflow and its features" (counting 
from 1st Char 'H', the 16th char is 't' but it is whole word 'StackOverflow',
    it shouldn't break and continue to next line e.g.
        Hello, I Love St
        ackOverflow
now the whole word should come to next line like:

        Hello, I Love
        StackOverflow 
        and its features

here is the link what i have done so far http://jsfiddle.net/nqjQ2/2/

sometimes some of the functionality work, some times not, and facing browser issues for onKeyUp and onKeyDown can anyone help me with it ?

SML
  • 2,172
  • 4
  • 30
  • 46
  • Always post the relevant code/markup/etc. **in the question itself**, don't just link to jsfiddle. (A fiddle is *also* nice.) – T.J. Crowder Jan 10 '13 at 13:58
  • 2
    Strongly recommend doing what SO does instead: Allow people to type freely, show them whether they're over-limit, and don't allow them to post when they're over-limit. But don't try to *prevent* them from going over-limit. It's a **much** better user experience. (Type a lot in a comment box here on SO to see what I mean.) – T.J. Crowder Jan 10 '13 at 13:58
  • Speaking from experience, writing this kind of logic on top of a text area is a very large and very complicated undertaking. You should first step back and ask yourself (or your client) if it is really worth it to you/them. – jbabey Jan 10 '13 at 13:58
  • The biggest problem you will face is font's... Not all fonts are monospaced (i.e. same width regardless of which character is used) meaning you can't reliably count how many characters are on each line. In addition to this, you have to take into consideration the browsers own wrapping functionality. Do you plan on using a monospaced font? – Gavin Jan 10 '13 at 14:03
  • @gavin, i can count chars in each line and i am using font-family - arial – SML Jan 10 '13 at 14:07
  • You can count characters however you cannot reliably determine when the browser has automatically wrapped the text due to being too long. If you fix the width of your textarea to be wider than the width of your lines, it should be ok? I'll see what I can come up with. – Gavin Jan 10 '13 at 14:11
  • @gavin, i have already fixed the width of textarea wider than actual size of 16 chars, which makes it fits and browser will not wrap it automatically – SML Jan 10 '13 at 14:17

2 Answers2

12

I think this is mostly what you want:

<textarea id="splitLines"></textarea>

JavaScript:

var textarea = document.getElementById("splitLines");
textarea.onkeyup = function() {
    var lines = textarea.value.split("\n");
    for (var i = 0; i < lines.length; i++) {
        if (lines[i].length <= 16) continue;
        var j = 0; space = 16;
        while (j++ <= 16) {
            if (lines[i].charAt(j) === " ") space = j;
        }
        lines[i + 1] = lines[i].substring(space + 1) + (lines[i + 1] || "");
        lines[i] = lines[i].substring(0, space);
    }
    textarea.value = lines.slice(0, 6).join("\n");
};

See the fiddle in action.

Lukas
  • 9,765
  • 2
  • 37
  • 45
  • @SunilLohar - Lukas' solution actually uses pure javascript. Mootools is selected by default when you create a new fiddle ;) – Gavin Jan 10 '13 at 14:34
  • Hmm... Apparently it doesn't preserve cursor position... I'll have to fix that. – Lukas Jan 10 '13 at 14:42
  • how can we avoid Space while adding new line, it adds new line along with space before it. – SML Jan 10 '13 at 14:51
  • Well, thank you all for sharing their opinions,i was really struggling to write the code for these features and @Lukas -mind-blowing -that was one of the amazing logic i saw in your code, i didnt know that for writing these many features we can do with such small code. – SML Jan 10 '13 at 15:18
  • Change `lines[i + 1] = lines[i].substring(space) + (lines[i + 1] || "");` to `lines[i + 1] = lines[i].substring(space + 1) + (lines[i + 1] || "");` and you won't get the extra space at the beginning of the line. I've updated the answer. – Lukas Jan 10 '13 at 15:22
  • @Lukas struggling on a similar problem for a few days now, saw dozens of suggestions but nothing else worked - amazing work! I'd suggest a few improvements though. If I type for example "The quick brown fox..." and then go back and add "The VERY quick..." it will rearrange the words correctly but not add a space between "brown" and "fox". I think we can do `lines[i + 1] = lines[i].substring(space + 1) + (lines[i + 1] ? " " + lines[i + 1] : "");` and add a space if we already have stuff on the next line, see updated fiddle here http://jsfiddle.net/9x5Fb/348/ – Boris Aug 24 '15 at 11:13
  • @Lukas then, if we do as above and add more text to an earlier line, causing the words below to be rearranged, we have the problem of cursor jumping to the very end of the text, so you have to manually go back up to continue typing where you started. Once another word gets carried over, the cursor jumps again. Any idea how to fix that? – Boris Aug 24 '15 at 11:17
  • 1
    Figured out the second problem too - http://jsfiddle.net/9x5Fb/350/ , store current start and end of selection as suggested here http://stackoverflow.com/questions/14508707/updating-an-inputs-value-without-losing-cursor-position and set them after applying the textbox value. Only do that if start and end are the same - in order to still allow selecting text, otherwise the selection would get reset on every keystroke. – Boris Aug 24 '15 at 13:28
2

In Jquery

$(function () {

    var limit = function (event) {
        var linha = $(this).attr("limit").split(",")[0];
        var coluna = $(this).attr("limit").split(",")[1];

        var array = $(this)
            .val()
            .split("\n");

        $.each(array, function (i, value) {
            array[i] = value.slice(0, linha);
        });

        if (array.length >= coluna) {
            array = array.slice(0, coluna);
        }

        $(this).val(array.join("\n"))

    }

    $("textarea[limit]")
        .keydown(limit)
        .keyup(limit);

})



<textarea limit='10,5'  cols=10 rows=5 ></textarea>

http://jsfiddle.net/PVv6c/

Tuyoshi Vinicius
  • 861
  • 8
  • 22