2

I'm trying to do a "twitter like" character counter in a contenteditable div. I want to limit the user to typing a max of 140 characters.

I used jQuery to count the characters and show the remaining, but it doesn't count the Enter key (new line) as a character. I need to count the new lines too.

I tried to use a textarea, but I need to specify the max-height for the scrollbar be visible only on the max-height. There is no limit of lines or characters.

DEMO: https://jsfiddle.net/oLomzakh/

Can you help me figure out how to include the new line count on the character count?

rphv
  • 5,409
  • 3
  • 29
  • 47
  • What's the question? – Duston Mar 02 '16 at 20:37
  • https://jsfiddle.net/wdowosv4/ works fine for me. the scrollbar is only visible when there are several lines of text (in chrome and FF and IE11). certain browsers may vary in the presentation, but that's preferable to an inconsistent counter. – dandavis Mar 02 '16 at 22:54
  • @dandavis I think he wants the box to be small, and grow with the content that's added to it, up to a certain `max-height` - at which point the scroll bar appears. – xyhhx Mar 03 '16 at 16:34
  • @Martin: like this: https://jsfiddle.net/pew3mbyd/ ? that's a trivial adjustment for a textarea... – dandavis Mar 03 '16 at 19:08
  • @dandavis Probably more like this: https://jsfiddle.net/pew3mbyd/1/ – xyhhx Mar 03 '16 at 20:25

3 Answers3

2

I think you can use $.html() instead of $.text(), you'll be able to know when there is a \n, but with $.text() it won't count special chars.

You can use "this.innerText.length" property too, without jQuery, but it will count \r\n and not only 1 character for a new line.

EDIT : you can get the $.html() for example and replace each new line <br> by only one character, then you just have to get the property length of that result.

Suicideboy
  • 144
  • 8
1

Firstly, working code:

maxCharacters = 140;

$('#char-count').text(maxCharacters);

$('#text-area').bind('input', function() {

    var count = $('#char-count');
    var characters = $(this).text().length;
    var newlines = $($(this).html()).length;

    if (!!newlines) newlines -= 1;

    characters += newlines;

    if (characters > (maxCharacters - 11)) {
        count.addClass('over');
    } else {
        count.removeClass('over');
    }
    count.text(maxCharacters - characters);

});

Now, an explanation:

It seems content-editable renders new lines using HTML (at least in Webkit). Adding a debugger; statement in the event handler, and checking the value of $(this).html() will reveal that:

enter image description here

As you can see there are both div's and br's in there.

That's where var newlines = $($(this).html()).length; comes in. This will count the children of the element (including both div's and br's). We need to also adjust newlines by -1 because once edited, there is always a remaining div or br.

We can add this to our $(this).text() value to get the real character count.

xyhhx
  • 6,384
  • 6
  • 41
  • 64
  • On chrome the first enter counts twice and on firefox when the text is deleted the counter is 139 cause stil a br in the div –  Mar 02 '16 at 21:11
  • Is there a way to detect the enter key and then increase de counter? –  Mar 02 '16 at 21:17
  • If a user inputs only whitespace, should that count as characters, or 0? – xyhhx Mar 02 '16 at 21:24
  • As an aside, [contenteditable might not be the best for what you want](http://stackoverflow.com/a/8694125/1007638). As the linked answer states, you will need to also somehow track clipboard events like cut and paste. Why don't you style a ` – xyhhx Mar 02 '16 at 21:27
  • whitespaces counts as charcters –  Mar 02 '16 at 21:29
  • with content editable I can use `max-height` to show the scrollbar only on the max height of the div. I can't find a way to do the same with `textarea` [as you can see](https://jsfiddle.net/ho5fatwz/) –  Mar 02 '16 at 21:37
  • 1
    you should use to `input` event so that alt IME and pasting (via mouse) affect the count. – dandavis Mar 03 '16 at 19:11
  • type one character, then press enter, it should count 2, but it counts 1 – kdureidy Mar 05 '16 at 03:40
  • If I am correct, it still doesn't show the character count INSIDE the `
    ` (this was asked)
    – Nash Carp Nov 09 '17 at 15:52
0

Martins answer is correct. But if you want white spaces and special characters to count as well you need this:

maxCharacters = 140;

$('#char-count').text(maxCharacters);

$('#text-area').bind('input', function() {

    var count = $('#char-count');
    var characters = $(this).text().length;

    if (characters > (maxCharacters - 11)) {
        count.addClass('over');
    } else {
        count.removeClass('over');
    }
    count.text(maxCharacters - characters);
});

I removed these 3 lines of code:

var newlines = $($(this).html()).length;

if (!!newlines) newlines -= 1;

characters += newlines;
Nash Carp
  • 169
  • 12