JSFiddle - React, Tailwind, and code Playground

by fullyslick

HTML

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Symbol Count</title>
</head>
<body>
<textarea name="message" id="js-message" cols="30" rows="10"></textarea>
<p>Symbols total: <b id="js-message-left-total">0</b>, left: <b id="js-message-left-symbols">0</b></p>
<script src="solution.js"></script>
</body>
</html>

JavaScript

'use strict';

/**
 * @type {{maxChar: number, textArea: null, textAreaTotal: null, textAreaLeft: null, init: init, events: events}}
 */
var TextCounter = {
    maxChar: 140,
    textArea: null,
    textAreaTotal: null,
    textAreaLeft: null,
    init: function() {
        this.textArea = document.querySelector('#js-message');
        this.textAreaTotal = document.querySelector('#js-message-left-total');
        this.textAreaLeft = document.querySelector('#js-message-left-symbols');

        this.events();
    },
    events: function() {
        var self = this,
            chars = 0;

        this.textAreaLeft.innerText = this.maxChar;

        this.textArea.addEventListener('keyup', function() {

            chars = 0;

            // Do not count empty spaces, only chars
            for (var i = 0; i < self.textArea.value.length; i++) {
                if (self.textArea.value[i] !== ' ') {
                    chars++;
                }
            }

            // Resolves long press issues
            if (self.maxChar - chars < 0) {
                // Text longer than 140 chars will be stripped to first 140 chars
                self.textArea.value = self.textArea.value.substring(0, self.textArea.value.length - (chars - self.maxChar));
                // After stripping set entered chars to maximum
                chars = self.maxChar;
            }

            // Display total used and left chars
            self.textAreaTotal.innerText = chars;
            self.textAreaLeft.innerText = self.maxChar - chars;
        });

        // Prevent entering chars if limit is reached
        this.textArea.addEventListener('keypress', function(event) {
            if (self.maxChar - chars <= 0) {
                event.preventDefault();
            }
        });
    }
};

TextCounter.init();