1

I have a textarea where contents need to be restricted by a word limit.

<textarea class="user_response"></textarea>

Here is the code I have so far. I could change the color of whole text but could not find a way to change color after the word limit.

$(".user_response").on('keyup', function() {
    var words = this.value.match(/\S+/g).length;
    if (words > gWordLimit) {
        $(this).css("color","red");
    } else
        $(this).css("color","black");               
});

The desired outcome: If the word limit is 2, after the second word, the color of excess characters should be highlighted as red, per say.

Rob
  • 14,746
  • 28
  • 47
  • 65
user4826347
  • 783
  • 2
  • 11
  • 29
  • 2
    This won't work with a normal ` – Coli Dec 11 '17 at 10:57
  • I have never used it myself, but I know you can format text in online e-mail clients (message part). If you'd check out how those work, I'm sure you could set all sorts of properties on specific words. – LGT Dec 11 '17 at 11:00
  • I am going to develop the effect for you. Just about to final it – Haider Ali Dec 11 '17 at 11:28

3 Answers3

0

here is the updated answer:

$(document).ready(function(){
 $(".user_response").keypress( function() {
    var words = $('.user_response').text().length;
if(words >4)
{
    if(words ==5)
    {
             $(".user_response").attr("contenteditable","false");
                $("#highlite").show();
                $("#highlite").attr("contenteditable","true");
                $("#highlite").focus();
        
                $("#highlite").css("color","red");
                }
            }else
                $("#highlite").css("color","black");  
                });
    $("#highlite").keyup( function() {
    if($("#highlite").text().length <1){
     
     $(".user_response").attr("contenteditable","true");
     $("#highlite").attr("contenteditable","false");
     $("#highlite").hide();
     $(".user_response").focus();
     }      
    });           
});
div{
 -moz-appearance: textfield-multiline;
-webkit-appearance: textarea;
border: 1px solid gray;
font: medium -moz-fixed;
font: -webkit-small-control;
height: 28px;
overflow: auto;
padding: 2px;
resize: both;
width: 400px;

}
span{
 outline: 0px solid transparent;
 }
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>


<script>

</script>
</head>
<body>
<div class="user_response" contenteditable="true"><span id=highlite></span> </div>

</body>
</html>

Note:

i have made div and span look like text area . change word limit according to yours .second if condition must be greater than the previous/

Community
  • 1
  • 1
jasinth premkumar
  • 1,430
  • 1
  • 12
  • 22
0

You need to access the content of the textarea. So you're only way is to use contenteditable.

Note: When you want to use the content of .input later, you need to strip all span tags inside of it.

$(document).ready(function() {
  // https://stackoverflow.com/a/4220182/4203811 [
  
  //setup before functions
  var typingTimer;              
  var doneTypingInterval = 1000;  
  var input = $('.input');

  //on keyup, start the countdown
  input.on('keyup', function () {
    clearTimeout(typingTimer);
    typingTimer = setTimeout(highlight, doneTypingInterval);
  });

  //on keydown, clear the countdown 
  input.on('keydown', function () {
    clearTimeout(typingTimer);
  });
  
  // ]
  
  // https://stackoverflow.com/a/27622713/4203811 [
  function highlight() {
    var wordArray, lastWords = [], firstParts, length;

    wordArray = input.html().replace(/<\/?span.*?>/g, "").split(/\s+/);

    length = wordArray.length;

    for (var i = 2; i < length; i++) {
      lastWords.push(wordArray.pop());             // pop the last word
    }

    firstParts = wordArray.join(' ');        // rejoin the first words together

    input.html([firstParts, ' <span class="red">', lastWords.reverse().join(' '), '</span>'].join(''));
  };
  
  // ]
});
body {
  display: flex;
  align-items: center;
  justify-content: center;
}
html, body {
  height: 100%;
  overflow: hidden;
}
div {
  font-family: sans-serif;
}
div > span {
  font-size: 25px;
  color: black;
  display: inline-block;
  background-color: grey;
  padding: 10px;
}
.red {
  color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
  <span class="input" contenteditable>Content</span>
</div>

Credits: Based on Chris Coyier: Expanding Border, https://codepen.io/chriscoyier/pen/KyaZVm/

Coli
  • 927
  • 8
  • 28
  • div with contenteditable always give problem on edits as cursor goes to the top of the text unlike textarea – user4826347 Dec 13 '17 at 19:54
  • Yeah, but that what you want is possible only in a `contenteditable`. You can change the focus with some hacky stuff https://stackoverflow.com/questions/2388164/set-focus-on-div-contenteditable-element – Coli Dec 18 '17 at 14:03
0

My solution to this problem is. Take a div below the text area. This div will show what user have entered in text area. The characters which are greater then limit will be shown in red while other text will be shown black in that area. Below is the code snippet. And here is the working jsFiddle https://jsfiddle.net/xhfokb7g/

<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
        span.error {
         color: red;
        }
    </style>
</head>
<body>
    <textarea class="user_response" cols="30" rows="10"></textarea>
    <div id="texty"></div>
    <script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
    <script>
        $(document).ready(function(){
            var txtarea      = $('.user_response');
            var climit = 20;
            var texty = $("#texty");

            txtarea.on('keyup', function(){
                if($(this).val().length > wordslimit){
                    cleanText = $(this).val().slice(0, wordslimit);
                    errorText = $(this).val().slice(wordslimit, $(this).val().length);
                    errorText = "<span class='error'>" + errorText + "</span";
                    textAreaText = cleanText + errorText;
                    texty.html(textAreaText);
                } else {
                    txtarea.html($(this).val());
                }
                texty.html($txtarea.val());
            });
        });
    </script>
</body>
</html>
Haider Ali
  • 1,081
  • 8
  • 23