Counting input chars - use onkeyup or onkeydown? - javascript

I need to set the maximum character input for users simililar to how stackoverflow.com works. I plan on using javascript to provide feedback to the user and count the characters. Only submissions that don't exceed the maximum character count are allowed. I don't plan on using the xhtml input properties to limit this amount as I'll allow overage on characters as long as they are not submitted. On the backend I'll just set the varchar field in mysql to charmax.
Question is, how do I count character inputs, do I base it off of onkeydown() or onkeyup(). I'm not too sure why there are two functions, because a key that goes down must come up, so which one should I use to do the counting?

HTML:
<input type='text' id='text'/>
JS:
function textLength(value){
var maxLength = 144;
if(value.length > maxLength) return false;
return true;
}
document.getElementById('text').onkeyup = function(){
if(!textLength(this.value)) alert('text is too long!');
}
Here is a fiddle demo: http://jsfiddle.net/maniator/L2LRK/

Use document.getElementById('YourInputBoxId').value.length to get the length of the text.
Don't use the keyboard events to keep track of the number of characters. Ctrl+V is a single keypress (or two maybe), but it can cause your text to grow megabytes. :)
You could use these events to update a label with the current number of characters.
Apart from onkeyup, you can also use the oninput event, which is triggered when you type into an input box.
And remember, always check on the server as well. Javascript may fail or can be deliberately disabled. Your server should always perform necessary checks. Although I believe that MySQL will automatically truncate texts that are too large...
A good alternative would be to set the maxlength property of the inputs. This way, the maximum length is enforced even without javascript. Then, you can remove that flag and add the necessary events from javascript. This way, you will have a usable solution for javascript browsers, while having a more strict check for non-javascript browsers, which I think is better than no check at all.

I found the bug in your suggestion. Here my test patterns:
If limit max characters are 05 characters.
Test value: 123456, ABCDEF
1: Use keyboard, type the text normally
for 123456, 6 will be deleted
for ABCDEF, F will be deleted
Result: OK
2: Use keyboard, copy and paste 123456 and ABCDEF from other place
for 123456, paste (Ctrl V): "123456123456" => 456123456 will be deleted
for ABCDEF, paste (Ctrl V): "ABCDEFABCDEF" => DEFABCDEF will be deleted
Result: OK
3: Use mouse, copy and paste 123456 and ABCDEF from other place
for 123456, paste (Right click + paste): "123456123456" => NO characters will be deleted
for ABCDEF, paste (Right click + paste): "ABCDEFABCDEF" => NO characters will be deleted
Result: FALSE;
4: Use mouse, copy and paste 123456 and ABCDEF from other place after that type something else
for 123456, paste (Right click + paste): "123456123456" => NO characters will be deleted, type "123" using keyboard => All text will be deleted.
for ABCDEF, paste (Right click + paste): "ABCDEFABCDEF" => NO characters will be deleted, type "ABC" using keyboard => All text will be deleted.
Result: FALSE;
I give you my false from my project at same function. In my function this pattern are false for ALL. Here my : jsfiddle This function that I have found in the internet, sorry I forget the source so If you are the owner, please for give me to public here.
HTML:
//Count content
maxL = 2000;
var bName = navigator.appName;
function taLimit(taObj) {
if (taObj.value.length == maxL) return false;
return true;
}
function taCount(taObj, Cnt) {
objCnt = createObject(Cnt);
objVal = taObj.value;
if (objVal.length > maxL) objVal = objVal.substring(0, maxL);
if (objCnt) {
if (bName == "Netscape") {
objCnt.textContent = maxL - objVal.length;
} else {
objCnt.innerText = maxL - objVal.length;
}
}
return true;
}
function createObject(objId) {
if (document.getElementById) return document.getElementById(objId);
else if (document.layers) return eval("document." + objId);
else if (document.all) return eval("document.all." + objId);
else return eval("document." + objId);
} //End Count content
You have <b><label id="myCounter">2000</label></b> characters left
<br/>
<textarea class="inputtextfield" onKeyPress="return taLimit(this)" onKeyUp="return taCount(this,'myCounter')" id="content" name="content" rows=7 wrap="physical" cols=40></textarea>
I am very confused how to fix my bug.

There are two functions because there are two different events. If you wanted to know when someone pressed Ctrl + Enter for instance you need to know exactly when each key is hold down and when it is released.
In your case (display a warning when reached the limit) i would use keydown because that is what happens first, that way you know right at the moment when the user went over X characters. If you used keyup te user could press a key for several seconds without seeing any message.
To count the characters you can do:
document.getElementById("myInput").value.length

Related

Detecting Period Symbol as not Valid against Number Input Pattern Using JavaScript

I have an input tag of type number with pattern validation attached to it that has at least taken care of eliminating the 'e' '+' '-' characters from being input. However the '.' symbol still gets through for some reason. Here are the relevant portions of code from my program:
<input type="number" id="job-priority" min="1" max="99" pattern="[0-9]+" placeholder="1 (High) — 99 (Low)" style="width:186px; padding-left:14px; text-align:center;">
document.getElementById('job-priority').addEventListener('input', function () {
// Check that characters typed into job priority field are valid.
if (!document.getElementById('job-priority').validity.valid) {
var value = document.getElementById('job-priority').value;
value = value.slice(0,-1);
document.getElementById('job-priority').value = value;
}
});
document.getElementById('job-priority').addEventListener('change', function () {
// Check that number entered into job priority stays within limits.
var value = Number(document.getElementById('job-priority').value);
var min = Number(document.getElementById('job-priority').min);
var max = Number(document.getElementById('job-priority').max);
if (value < min)
document.getElementById('job-priority').value = min;
else if (value > max)
document.getElementById('job-priority').value = max;
});
From my own research on this up to this point, I have come across one previous question post on StackOverflow regarding input patterns with input type number. That post, in short, confirms that input patterns don't work for input type number. It proposes the solution to just use input type text instead with a pattern to allow only numbers through. However, I want to keep the input type to number because of the up/down arrows that increase/decrease the number in the input field. I would be willing to change the input type to text only if their is a way to keep the up/down arrows in question.
I also see that if I remove the pattern from the input tag, my event listener for 'input' still successfully takes care of not allowing the 'e' '+' '-' characters somehow. Of course, the '.' symbol is still being allowed when it shouldn't. So I guess at least I confirmed that the pattern wasn't actually doing anything from what I can tell.
More specifically, if the '.' is typed as the first character, the validation check successfully works and nothing appears in the input field which is the desired behavior. However, if the first character typed is a number and then second character typed in is the '.' symbol, then for some reason the '.' symbol appears when it should not have.
Figured out a solution to my problem.
document.getElementById('job-priority').addEventListener('input', function () {
// Check that characters typed into job priority field are valid.
document.getElementById('job-priority').type = 'text';
if (!document.getElementById('job-priority').validity.valid) {
var value = document.getElementById('job-priority').value;
value = value.slice(0,-1);
document.getElementById('job-priority').value = value;
}
document.getElementById('job-priority').type = 'number';
});
You'll see that what I did was change the input type to 'text' temporarily just for the input validation. Then, as soon as it's done, immediately change the input type back to 'number'.

Remaning characters textarea problems

I am facing the following problem: I have to calculate the remaining characters in a textarea. It is a simple task and there's a lot of reference for doing such things. The piece of code I created to do this is bellow. Everything works fine an so, but, the QA team did this: they cut and pasted a piece of text of a txt document and they pasted till they reached the maximum of text allowed in my textarea. But what happens is that even when the max of characters is not reached the user cant type anymore.
And also if I erase some characters using the backspace I cant type anymore.
Let me be more specific. Let's say that the last word is "nerd" and the remaining characters is "47". The code doesn't allow me to write more and even if I use the backspace and have "ner" I cant type a single more letter!
The fiddle bellow has the scenario to check what I am saying. You can paste the text that is in the comment of the html section of my fiddle to state what I am talking about. Thanks in advance for any help.
http://jsfiddle.net/sLr8co1n/4/
GIF: http://gifmaker.cc/PlayGIFAnimation.php?folder=2015020423hlKs7Ki7knoQBCZAoSaQNN&file=output_rwGbzN.gif
$("#textAreaComplemento").bind("keyup change", function (e) {
calculaCaracteresRestantes();
});
var text_max = 200;
function calculaCaracteresRestantes() {
if ($('#textAreaComplemento').val() == undefined) {
return false;
}
var text_length = $('#textAreaComplemento').val().length;
var text_remaining = text_max - text_length;
$('#textarea_feedback').html(text_remaining);
return true;
}
After testing and playing around in Fiddle, I could figure out that basically the line "$('#textAreaComplemento').val().length" is finding out the number of characters only (and not counting the number of spaces, like in this case there are 4 spaces before return false ). Hence, when you copy, paste something (say your code which has 5 spaces in between it), then the user can enter only after deleting 6 letters which makes the total count as 194 (200-6) + 5 (spaces) + space for one letter to be entered.You can probably use something like this to avoid any spaces or carriage returns being counted by the browser and just consider the letters:
$(function () {
$('#test').keyup(function () {
var x = $('#test').val();
var newLines = x.match(/(\r\n|\n|\r)/g);
var addition = 0;
if (newLines != null) {
addition = newLines.length;
}
$('#length').html(x.length + addition);
})
})
Something like this might help u mate.. :)
$("#textAreaComplemento").bind("keyup change input propertychange", function (e) {
calculaCaracteresRestantes();
});
Fiddle

Detecting whether user input contains a forbidden character in JavaScript

I have a text box that is going to be validated in JavaScript upon click on the submit button.
Only the character 0-9 and a-f and A-F are allowed.
So g-z and G-Z as well as other characters such as punctuation or not allowed.
The code I have so far is:
function validate_form ( )
{
valid = true;
if ( document.form.input.value == [a-zA-Z_,.:\|] )
{
alert ( "You can only enter either 0-9 or A-F. Please try again." );
valid = false;
}
return valid;
}
Which doesn't seem to work.
I'm new to JavaScript so can any one please give me a hint as to where I'm going wrong?
We can actually clean this code up a lot. There's no need to keep track of valid as test() will provide us with the true or false value we're looking for. It's also a good deal easier in your case to keep a whitelist of acceptable characters rather than a blacklist. That is, we know every character we want, but can't possibly specify every character we don't want.
function validate_form() {
return /^[a-fA-F0-9]+$/.test(document.form.input.value);
}
Note that you can also use this to do a pre-check:
document.form.input.onkeyup = function() {
if (!validate_form()) {
alert("You can only enter either 0-9 or A-F. Please try again.");
}
};
the syntax is /^[a-zA-Z_,.:\|]+$/.test(document.form.input.value). Notice the ^ and $: without them, the test will pass even for strings that have only at least one allowed character.
The best way for validation is to not let the user, enter wrong character. Use this code (this is the jQuery version, but you can also convert it easily to JavaScript):
$('#inputFiledId').keyup(function(e){
// checking the e.keyCode here, if it's not acceptable, the return false (which prevents the character from being entered into the input box), otherwise do nothing here.
});
This is called pre-check. Please consider that you whatever you do in client-side, you should always check the values at the server also (have server-side validation) as there are multiple hacks around, like form-spoofing.
You could do something like this
$('input').keyup(function(){
var charac = /[g-zG-Z;:,.|_]/;
var result = charac.test($(this).val());
if(result == true){
alert('You can only enter either 0-9 or A-F. Please try again.');
}
})
http://jsfiddle.net/jasongennaro/GTQPv/1/

Disabling some special characters in text area

Hey guys, I'm thinking of ways to disable users from typing some special characters like < and >. But I would like them to use full stops and commas and question marks and exclamation marks and quotes. I've come up with this piece of code but it doesn't seem to allow any special character.:
<script type="text/JavaScript">
function valid(f) {
!(/^[A-zÑñ0-9]*$/i).test(f.value)?f.value = f.value.replace(/[^A-zÑñ0-9]/ig,''):null;
}
</script>
There are several ways of doing this, none of them are a good way to go tho, but we'll get to that.
you can bind to onkeyup/onkeydown/onkeypress events on the element and cancel events for characters you have blacklisted. This will not stop people from pasting the characters into the field however.
You can bind to the onchange event of the element and them remove the blacklisted characters from it, once the user is done inputting.
The problem with any type of sanitizing like this in javascript is that it is trivial for a user with a tiny bit of knowhow, to circumvent these measures and still upload the offending characters to the server anyway.
So if you don't want to allow special characters in the user generated input you should either
remove them serverside after the userinput has been submitted
keep them but encode them into html entities > and < for > and < for instance before outputting them anywhere on your webpage.
Try with this...
var iChars = "!##$%^&*()+=-[]\\\';,./{}|\":<>?";
for (var i = 0; i < document.formname.fieldname.value.length; i++) {
if (iChars.indexOf(document.formname.fieldname.value.charAt(i)) != -1) {
alert ("Your username has special characters. \nThese are not allowed.\n Please remove them and try again.");
return false;
}
}
why not simply check the character pressed on "onKeyDown" event?
<textarea id="foo"></textarea>
<script>
document.getElementById('foo').onkeydown = validate;
function validate(){
var evtobj = window.event? event : e; // IE event or normal event
var unicode = evtobj.charCode? evtobj.charCode : evtobj.keyCode;
var actualkey = String.fromCharCode(unicode);
]
return (/^[A-zÑñ0-9]*$/i).test(actualKey);
</script>
This simply gets the key which was pressed, and if it is a valid one returns true, otherwise false, this, in term, determines if the key is actually written in the textarea or not

Replace text (change case) in a textbox using Javascript

I am trying to build a sort of intelli-sense text input box, where as the user types, the 'and' is replaced by 'AND \n' (i.e. on each 'and', the 'and' is capitalized and user goes to new line).
The Javascript I used for this is:
function Validate()
{
document.getElementById("search").value = document.getElementById("search").value.replace("and","AND \n"); //new line for AND
}
The HTML part is like this:
< textarea type="text" name="q" id="search" spellcheck="false" onkeyup='Validate();'>< /textarea>
Though the above script works well on Firefox and Chrome, it sort-of misbehaves on Internet Explorer (brings the cursor to the end of the text on each 'KeyUp').
Also the above code doesn't work for the other variants of 'and' like 'And', 'anD' or even 'AND' itself.
I think the actual answer here is a mix of the two previous:
onkeyup="this.value = this.value.replace(/\band\b/ig, ' AND\n')"
You need the i to make the search case insensitive and the g to make sure you replace all occurrences. This is not very efficient, as it'll replace previous matches with itself, but it'll work.
To make it a separate function:
function validate() {
document.getElementById('search') = document.getElementById('search').replace(/\band\b/ig, ' AND\n');
}
If you alter the textarea contents while the user is typing the caret will always move to the end, even in Firefox and Chrome. Just try to edit something you already wrote and you'll understand me. You have to move the caret to the exact position where the users expects it, which also implies you have to detect text selections (it's a standard behaviour that typing when you have a selection removes the selected text).
You can find here some sample code. You might be able to use the doGetCaretPosition(), setCaretPosition() functions.
I tried to work around the problem and solved by using the following javascript:
function Validate() {
if( document.getElementById("search").value.search(/\band$(?!\n)/i) >= 0 ){ // for maintaining cursor position
document.getElementById("search").value = document.getElementById("search").value.replace(/\band$(?!\n)/i,"AND\n"); //new line for AND
}
}
Thin slicing the above problem and solution:
1) The function was being called on each key up, thus earlier "AND\n" was being repeated on each key up, thus inserting a blank line on each key press. I avoided the above by using the regex:
/\band$(?!\n)/i
\b = Like Word (to avoid SAND)
$ = End of line (as "and" will be replaced by "AND\n" thus it will always be end of line)
(?!\n) = Not followed by new line (to prevent repeatedly replacing "AND\n" on each key press)
i = To cover all variants of "and" including "And","anD" etc.
2) Internet Explorer was misbehaving and the cursor position was not maintained (moved to end) when the input was re-edited. This was caused (as hinted by Alvaro above) due to the replace function.
Thus I inserted an "if" statement to call replace function only when it is needed, i.e. only when there is some "and" needing replacement.
Thanks everyone for the help.
try using the following replace() statement:
replace(/\band(?!$)/ig, "And\n")
since this is being called repeatedly against the altered string you have to make sure that the "and" is not followed by a line break.
example (uses a loop and function to simulate the user typing the letters in):
function onkeyup() {
var str = this;
return this.replace(/\band(?!$)/ig, "And\n");
};
var expected = "this is some sample text And\n is separated by more text And\n stuff";
var text = "this is some sample text and is separated by more text and stuff";
var input = "";
var output = "";
for(var i = 0, len = text.length; i < len; i++ ) {
input += text.substr(i,1);
output = onkeyup.call(input);
}
var result = expected == output;
alert(result);
if( !result ) {
alert("expected: " + expected);
alert("actual: " + output);
}
you can test this out here: http://bit.ly/8kWLtr
You need to write a JS code that run in both IE and FireFox. I think this is what you need:
var s = document.getElementbyId('Search');
s.value = s.value.replace('and', 'AND \n');
I think you want your replace call to look like this:
replace(/\band\b/i,"AND \n") (see below)
That way it is not case sensitive (/i), and only takes single words that match and, so 'sand' and similar words that contain 'and' don't match, only 'and' on it's own.
EDIT: I played around with it based on the comments and I think this working example is what is wanted.
Replace the onKeyUp event with onBlur:
<textarea type="text" name="q" id="search" spellcheck="false" onblur='Validate();'></textarea></body>
So that the validate function is only run when the user leaves the text box. You could also run it onSubmit.
I also added a global switch (g) and optional trailing whitespace (\s?) to the regex:
replace(/\band\b\s?/ig,"AND \n")
This causes input like this:
sand and clay and water
to be transformed into this when you leave the text box:
sand AND
clay AND
water
You should probably test this against a bunch more cases.

Categories

Resources