jQuery update character counter after pasting in more characters than maxlength - javascript

I have a form that with a textarea and I'm trying to prevent users from pasting more than 1000 characters into it. I have a div that displays the number of characters left as the user types, which is the problem. I have the pasting part working, but I'm also trying to set the character counter at the same time.
Here's the code:
<textarea name="Note" id="Note" cols="80" rows="5" class="text-input shadow form-control" maxlength="1000"></textarea>
<div id="NoteLength"></div>
<div>characters remaining.</div>
and the jQuery:
$("#NoteLength").text("1000");
//user is typing
$("#Note").keyup(function () {
el = $(this);
if (el.val().length >= 1000) {
el.val(el.val().substr(0, 1000));
} else {
$("#NoteLength").text(1000 - el.val().length);
}
});
//user is pasting
$("#Note").blur(function (event) {
var maxLength = 1000;
var length = this.value.length;
if (length > maxLength) {
$("#NoteLength").text("0");
this.value = this.value.substring(0, maxLength);
}
});
It's truncating the text as expected, but it's not resetting the NoteLength div to if I paste a large chunk of text, say 1500 characters. If I paste blocks of 200 characters, the counter works fine. Works if I backspace over the last character pasted in too, just not when I go way over in one paste which is unfortunately the most likely user scenario.

You can use the input event to capture any change to the value of the input by a user
$("#NoteLength").text("1000");
//user is changing the input value, typing or pasting, all of it
$("#Note").on('input', function () {
if (this.value.length > 1000) {
this.value = this.value.substr(0, 1000);
}
$("#NoteLength").text(1000 - this.value.length);
});

Related

Angular Material TextArea set limit on number of lines entered

I don't want to know how to set the visible number of rows.
I want to restrict the number of lines of text that a user can enter into a text area.
For example I want a maximum of 10 lines.
If the user can enter 11 lines it will mess up the UI on other applications that use the data.
By lines I mean when the user enters a carriage return and starts on a new line.
If you cut and paste the text from the text area into notepad on windows there should be no more than 10 lines. e.g. This description is 14 lines long (this does not included wrapped text).
I already know how to adjust visible rows and restrict character length.
EDIT:
I have edited the title and description to try and make it clearer.
There is probably more than one way to do this, but an obvious - and relatively straightforward - one is to listen to input events on the text area and remove any line feed characters added over the limit. This is a generic solution - it isn't specific to Angular or Angular Material (but the code is TypeScript):
<textarea matInput (input)="limitLines($event, 5)"></textarea>
limitLines(event: InputEvent, maxLines: number) {
let text = (event.target as HTMLTextAreaElement).value;
if (text.length > 0) {
const lineCount = 1 + text.replace(/[^\n]/g, '').length;
if (lineCount > maxLines) {
const textArray = text.split('\n');
const newText = textArray.reduce((result, line, lineNum, array) => {
if (lineNum < maxLines) {
return result.concat('\n').concat(line);
}
return result.concat(line);
});
(event.target as HTMLTextAreaElement).value = newText;
}
}
}
you can also check by counting "\n" on the string and if the count is > than max rows then call event.preventDefault();
<textarea
(keydown.enter)="onKeydown($event)"
class="form-control"
></textarea>
onKeydown(event: Event) {
if(textBoxValue.split("\n").length >= maxRows) {
event.preventDefault()
}
}

How to use jquery to prevent a editable div reach over our restricting length

Let's said I have the following code:
<div id="editing" contenteditable onclick="document.execCommand('selectAll',false,null)">Put text here...</div>
In this case, I want to restrict my user, for example, can only put 200 characters in it (including space), how can I restrict it? I know I might achieve it with jquery but most example on webs checks it when they click a button, and as I redesign my code with this StackOverflow question as base, it checks it when the div is clicked but with that in mind you can't alert user when the types over 200 words.
So how can I continuously checking words user type in a contenteditable div and alert them when they reach the limit?
The input event is supported with contenteditable, then just stop the event if there is too much text like so:
var el = document.getElementById('editing');
var max = 20;
el.addEventListener('input', function(e) {
if (el.innerHTML.length > max) {
el.innerHTML = el.innerHTML.substr(0, max); // just in case
alert('Not allowed more than ' + max + ' characters');
}
});
<div id="editing" contenteditable onclick="document.execCommand('selectAll',false,null)">Put text here...</div>
However, just stay away from contenteditable events. they are bad
Here is simple pure js solution: if anything is there please comment i will update my answer.. :D
function check()
{
// get the HTML value.
var content = document.getElementById('editing').innerHTML;
//Edit : replace spaces from content (ideally you have to figure out how to remove the posible html tags that user might enter)
content = content.replace(/ /g," ");
console.log(content);
// validate value againts limit say 10 or any constant value.
if(content.length > 20)
{
// alert user.
alert('limit reached');
// flush extra characters from end.
document.getElementById('editing').innerHTML = content.slice(0,content.length-1);
return;
}
}
//Edit : if you want remove placeholder from annoying user you can flush it when user gets the focus on it say
function checkPlaceholder()
{
document.getElementById('editing').innerHTML = "";
}
<div id="editing" contenteditable onInput="check();" onfocus="checkPlaceholder();">Put text here...</div>
<div id="editing" contenteditable onkeypress = "if($(this).text().length >= 200) {return false; }"onclick="alert(document.execCommand('selectAll',false,null)">Put text here...</div>
You return false onkeypress when the character count is greater than or equal to 200
// Detect when you add a character to the div.
$('div#editing').on('keydown',function(e) {
// Check if you already have 200 characters (but allow 'backspace' and 'del' keys).
if (e.keyCode != 8 && e.keyCode != 46 && $(this).text().length >= 200) {
alert('The field is limited to 200 characters');
return false; // This will make the new character to be ignored.
}
});

How to show end of the text in input after programmatically adding text?

I want to programmatically add words in input and always see the end of the text. But the problem is that when I'm adding word (like input.value += 'word') when length of text is almost the same as length of input, text inside input doesn't move, so I can see only begining of the text and ending is become hidden.
I think if I could put cursor to the end of input it will help, but none of tricks with cursor not working in Chrome, such as
input.value = input.value
or
input.setSelectionRange(input.value.length, input.value.length);
Seems to work well enough:
let input = document.getElementById('auto');
let sentence = 'Courage is the magic that turns dreams into reality.';
let index = 0;
setTimeout(function typing() {
let letter = sentence.charAt(index++);
input.blur();
input.value += letter;
input.focus();
input.setSelectionRange(index, index);
if (index < sentence.length) {
let ms = Math.floor(75 + Math.random() * 150);
setTimeout(typing, ms);
}
}, 1000);
<input id="auto" type="text">
If the input does not have focus, then Chrome will show it "scrolled" all the way to the left, showing the beginning of your input value.
If the element has focus, then you can set the selection range to move the cursor:
window.onload = function(){
var input = document.getElementById('foobar');
input.value += ' bazbat';
input.focus();
input.setSelectionRange( input.value.length - 1 );
}
<input id="foobar" value="foobar" size="6">
But it would be a very confusing and frustrating UX if the cursor is moving around while the user is attempting to type a value.
Other options to consider:
Change the width of your input to match the value. make html text input field grow as I type?
Toggle between an input and a span (edit mode vs read mode). With a span, you'd have a lot more control over how text is displayed. Jquery: Toggle between input and text on click
Use an indicator of some sort to alert the user that one of their input values was modified. This would be useful even if they can see the entire value, as they might not notice that the value was updated.

Can input be limited to html <textarea>? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What is the best way to emulate an HTML input “maxlength” attribute on an HTML textarea?
My question is can a <textarea > be configured only to accept a certain number of characters? I can do this in the following JavaScript, but the person for whom I am designing this page does not want a status field.
My current way of doing things is I have a <textarea > that is part of a form that uses a nice JavaScript function to fill a message in a status box.
I also read SO and found Alerts and sounds really aren't the way to alert people, so the following code changes background color (and restores when appropriate) when there is an error.
Here is that code:
// Checks Form element TransDesc for overruns past 255 characters.
function warnOverDescLen()
{
var misc_text =
document.forms["InvGenPayTickets"]["TransDesc"].value;
var alert_text =
"You cannot enter more than 255 characters. Please remove some information.";
var rc = true;
if(255 < misc_text.length)
{
document.forms["InvGenPayTickets"]["trans_status"].value
= alert_text;
misc_text = misc_text.substring(0, 253);
document.forms["InvGenPayTickets"]["TransDesc"].value
= misc_text;
document.forms["InvGenPayTickets"]["trans_status"].style.backgroundColor
= "pink";
}
else
{
document.forms["InvGenPayTickets"]["trans_status"].value
= "";
document.forms["InvGenPayTickets"]["trans_status"].style.backgroundColor
= "lightgoldenrodyellow";
}
return rc;
}
<textarea rows="4" cols="60" name="TransDesc" id="TransDesc"
onkeypress="return warnOverDescLen();" ></textarea>
<span style="color: #50081E; font-weight: bold">Status</span>
<br />
<input type=text name="trans_status" id="trans_status" maxwidth="50"
size="65" />
This is a solution for HTML5, not supported by IE9 or earlier (according to this):
<textarea maxlength="255"></textarea>
Since you probably can't drop support for IE9 (and maybe even IE8), it's recommended you couple that with JavaScript, preventing the default behavior for the keydown and paste events on the textarea, as standup75 suggested.
Here is how to do that with plain JavaScript:
<textarea id="txtarea" maxlength="255"></textarea>
<script>
var field = document.getElementById('txtarea');
if(field.addEventListener) {
field.addEventListener('keydown', enforceMaxlength);
field.addEventListener('paste', enforceMaxlength);
} else {
// IE6-8
field.attachEvent('onkeydown', enforceMaxlength);
field.attachEvent('onpaste', enforceMaxlength);
}
function enforceMaxlength(evt) {
var maxLength = 255;
if(this.value.length >= maxLength) {
evt.preventDefault()
}
}
</script>
http://jsfiddle.net/snJwn/
HTML5 offers the maxLength attribute. Otherwise, you'd need some javascript, in jQuery, you'd do something like
maxLength = 50;
$("textarea").on("keydown paste", function(e){
if ($(this).val().length>=maxLength) e.preventDefault();
});
you can use the maxlength="255" (it specifies the maximum number of characters allowed in the element.)
or you can also do this by the jquery here i found the tutorial
html
<textarea cols="30" rows="5" maxlength="10"></textarea>
jquery
jQuery(function($) {
// ignore these keys
var ignore = [8,9,13,33,34,35,36,37,38,39,40,46];
// use keypress instead of keydown as that's the only
// place keystrokes could be canceled in Opera
var eventName = 'keypress';
// handle textareas with maxlength attribute
$('textarea[maxlength]')
// this is where the magic happens
.live(eventName, function(event) {
var self = $(this),
maxlength = self.attr('maxlength'),
code = $.data(this, 'keycode');
// check if maxlength has a value.
// The value must be greater than 0
if (maxlength && maxlength > 0) {
// continue with this keystroke if maxlength
// not reached or one of the ignored keys were pressed.
return ( self.val().length < maxlength
|| $.inArray(code, ignore) !== -1 );
}
})
// store keyCode from keydown event for later use
.live('keydown', function(event) {
$.data(this, 'keycode', event.keyCode || event.which);
});
});
Live example

How can I block further input in textarea using maxlength

I have a textarea that I want to block input on if the entered characters reaches a max-length.
I currently have a Jquery script for the textbox that calculates the characters entered and want to add something that will block input in the textarea once 150 characters are entered.
I have tried using max-length plugins in conjunction with my script but they don't seem to work. Help is appreciated.
CURRENT CODE
(function($) {
$.fn.charCount = function(options){
// default configuration properties
var defaults = {
allowed: 150,
warning: 25,
css: 'counter',
counterElement: 'span',
cssWarning: 'warning',
cssExceeded: 'exceeded',
counterText: '',
container: undefined // New option, accepts a selector string
};
var options = $.extend(defaults, options);
function calculate(obj,$cont) {
// $cont is the container, now passed in instead.
var count = $(obj).val().length;
var available = options.allowed - count;
if(available <= options.warning && available >= 0){
$cont.addClass(options.cssWarning);
} else {
$cont.removeClass(options.cssWarning);
}
if(available < 0){
$cont.addClass(options.cssExceeded);
} else {
$cont.removeClass(options.cssExceeded);
}
$cont.html(options.counterText + available);
};
this.each(function() {
// $container is the passed selector, or create the default container
var $container = (options.container)
? $(options.container)
.text(options.counterText)
.addClass(options.css)
: $('<'+ options.counterElement +' class="' + options.css + '">'+ options.counterText +'</'+ options.counterElement +'>').insertAfter(this);
calculate(this,$container);
$(this).keyup(function(){calculate(this,$container)});
$(this).change(function(){calculate(this,$container)});
});
};
})(jQuery);
Have you tried ​the maxlength attribute? That will block input once the character limit is reached.
<textarea maxlength='150'></textarea>​​​​​​​​​​​​​​​​​​​​​​​​​​ // Won't work
<input type='text' maxlength='150' />
Edit It appears that maxlength for a textarea works in Chrome, but not in other browsers, my bad. Well, another approach would just be to monitor keydown events and if length>150, return false/preventDefault/however you want to stop the default action. You'd still want allow backspace and enter however, so monitor keycode as well.
$('#yourTextarea').keydown(function(e) {
if (this.value.length > 150)
if ( !(e.which == '46' || e.which == '8' || e.which == '13') ) // backspace/enter/del
e.preventDefault();
});
You're much better off not trying to prevent the user from typing in too many characters and instead showing a counter and only enforcing the character limit when the user tries to submit. The comment boxes Stack Overflow are a decent example. It's both easier technically and more importantly better for the user to do it this way: it's really irritating not to be able to type/paste/drag text into a textarea even if you know there's a character limit.
Textarea maxlength with Jquery works OK but probably doesn't solve the issue of pasting in larger amounts of text.
PB Edit: Has since been updated here
Try this code below i hope will work, remember to include jQuery library
<div class="texCount"></div>
<textarea class="comment"></textarea>
$(document).ready(function(){
var text_Max = 200;
$('.texCount').html(text_Max+'Words');
$('.comment').keyup(function(){
var text_Length = $('.comment').val().length;
var text_Remain = text_Max - text_Length;
$('.texCount').html(text_Remain + 'Words');
$('.comment').keydown(function(e){
if(text_Remain == 0){
e.preventDefault();
}
});
});
});
You can truncate the contents of the textarea if it is over 150 characters as described at http://web.enavu.com/daily-tip/maxlength-for-textarea-with-jquery/. I can see some issues with copy/pasting if that brings the text over the limit though.

Categories

Resources