Restrict user input at client side


I need to validate user input in Javascript.
I have with me the range of ASCII codes that are valid.
For example, following are valid characters

32 to 126,
128, 138, 140, 142,
145 to 148,
154, 156, 158, 159,
161 to 167,
176,
180 to 182,
191 to 255

and the rest needs to be restricted at the client side.
Please tell me how to go about it.
LVL 8
thomas908Asked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

netsmithcentralCommented:
Javascript has the charCodeAt function to return the character code of a certain character.  Like:

function validate(what){
 for (i=0; i<what.length; i++){
  var a = what.charCodeAt[i];
  if (a<32) return false;
  else if (a==127) return false;
  else if (a>128&&a<138) return false;
  else if (a==139||a==141) return false;
  else if (a==143||a==144) return false;
  else if (a>148&&a<154) return false;
  else if (a==155||a==157||a==160) return false;
  else if (a>167&&a<176) return false;
  else if (a>176&&a<180) return false;
  else if (a>182&&a<191) return false;
  else return false;
 }
}

<form onsubmit="return validate(document.getElementById('theText').value">
<input id="thetext">
</form>
bpmurrayCommented:
Be very careful. While NetSmith's solution is correct, it assumes that your codes are Unicode, but I don't think that's the case. Note that ASCII has NO values greater than 127, so you're referring presumably to Windows CodePage 1252 values. Instead of using these, which will be different on Mac, Linux and Windows, as well as varying depending on locale, use the correct Unicode values. You can find these easily enough - see http://www.unicode.org/charts/ for all alphabets, and http://www.unicode.org/charts/PDF/U0080.pdf for the Latin-1 characters which overlaps Windows quite a bit. Other charts that are relevant are Basic Latin (http://www.unicode.org/charts/PDF/U0000.pdf) and Latin Extended A (http://www.unicode.org/charts/PDF/U0100.pdf).

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
thomas908Author Commented:
Thanks for replying

I can fetch the codes from a properties file (using JSP) and put them in a javascript array.
Then I want to do the comparison (of allowing or disallowing). This way if the list changes, I only have to modify the properties file.

I have put the values in the properties file as

name.validChars = 32-126, 128, 138, 140, 142, 145-148, 154, 156, 158, 159,161-167, 176, 180-182, 191-255

In the Javascript function I can get the values as

     var getChars = '<%= locale.getValue("name.validChars") %>';


I want to iterate over the values delimited by comma(,) and put them in an array.
Then I want to iterate over that array and alert the user for invalid values and allow the values mentiond in the array.
Amazon Web Services

Are you thinking about creating an Amazon Web Services account for your business? Not sure where to start? In this course you’ll get an overview of the history of AWS and take a tour of their user interface.

TedInAKCommented:
Here's my way.  It validates each keystroke, and if the the keystroke isn't within the defined characters, it erases it.  But, if you were to paste a string containing invalid characters using "right-click | paste", it doesn't catch it.  That's why I also run the validate() function onsubmit, to strip out any illegal characters.

<html>
<head>
<script type="text/javascript">
function validate(input) {
   var re = /[\x00-\x1E\x7F\x81-\x89\x8A\x8D\x8F-\x90\x95-\x99\x9B\x9D\xA0\xA8-\xAF\xB1-\xB3\xB7-\xBE]/g
   input.value = input.value.replace(re, "");
}
</script>
</head>
<body onload="document.getElementById('input').focus()">
<form onsubmit="validate(this.input)">
   <input type="text" name="input" onkeyup="validate(this)">
   <input type="submit">
</form>
</body>
</html>
thomas908Author Commented:
thomas908Author Commented:
>>\x00-\x1E\x7F\x81-\x89\x8A\x8D\x8F-\x90\x95-\x99\x9B\x9D\xA0\xA8-\xAF\xB1-\xB3

They are ASCII codes? What are these values?
TedInAKCommented:
They're the hex equivalents of the characters you don't want, e.g., \x00 = ascii "00", \x20 = ascii "32", etc.  I couldn't figure out how to test for ascii codes using my regular expression, so I converted them to hex (using the same exact ascii table in your link...go figure!) and tested for them that way.
TedInAKCommented:
Also, to verify that my code works, you could change the "var re =" line to:
   var re = /[\x61-\x6D]/g;

That disallows the letters a-m (lowercase only).
thomas908Author Commented:
>input.value = input.value.replace(re, "");

I want to give an alert, if invalid value is entered.
How to check for invalid vlaues in this case?
thomas908Author Commented:
I can't pass a this referecne, I am gettign the input value uisng

document.search.name.value;
thomas908Author Commented:
I did this

if(Ltrim(Rtrim(text)).match(re)==null)
                        {
                              return false;
                        }

But is there a way to convert, ascii to hex ot do I have to put hex in my properties file
thomas908Author Commented:
>>(Ltrim(Rtrim(text)).match(re)==null)

This is giving null, whatever may be the input
TedInAKCommented:
Here's a reworked example. I test for used invalid characters instead of valid because it's easier to code for the regular expression.

<html>
<head>
<script type="text/javascript">
var invalidChars = new Array;
invalidChars[0] = "0-31";
invalidChars[1] = "127";
invalidChars[2] = "129-137";
invalidChars[3] = "139";
invalidChars[4] = "141";
invalidChars[5] = "143-144";
invalidChars[6] = "149-153";
invalidChars[7] = "155";
invalidChars[8] = "157";
invalidChars[9] = "160";
invalidChars[10] = "168-175";
invalidChars[11] = "177-179";
invalidChars[12] = "183-190";

function decToHex(dec) {
   if (parseInt(dec) == 0) return "00";
   var hex = parseInt(dec).toString(16).toUpperCase();
   if (hex.length%2) hex = "0" + hex;
   return hex;
}

function buildRE() {
   var re = "";
   var temp;
   for (var i = 0; i < invalidChars.length; i++) {
      temp = invalidChars[i].split("-");
      re+= "\\x" + decToHex(temp[0]);
      if (temp[1]) re+= "-\\x" + decToHex(temp[1]);
   }
   return re;
}

function validate(str) {
   var re = new RegExp("[" + buildRE() + "]", "g");
    if (str.search(re) != -1) alert("Invalid input");
}
</script>
</head>
<body onload="document.getElementById('input').focus()">
<input type="text" name="input" onchange="validate(this.value);">
</body>
</html>
thomas908Author Commented:
Thanks for the code
I have done

 function validateCharacters() {
     var text = document.text1.value;
     var re = new RegExp("[" + buildRE() + "]", "g");
     
       var a = fulltext.search(re);
     alert(a);
...
}

It gives -1 for both valid as well as invalid characters. I tried backslash  for which it is giving -1 and it is also giving -1 for a whcih is a valid value
thomas908Author Commented:
Also, when i write

if (fulltext.search(re) != -1) {
   ...
}

it gives me a blank alert. i am unable to figure it out
ZvonkoSystems architectCommented:
Here my version:


<html>
<head>
<title>Zvonko &#42;</title>
<script>
var validChars = new Array();
validChars[0] = true;
validChars[8] = true;
validChars[9] = true;
for(var i= 32;i<=126;i++) validChars[i] = true;
validChars[128] = true;
validChars[138] = true;
validChars[140] = true;
validChars[142] = true;
for(var i=145;i<=148;i++) validChars[i] = true;
validChars[154] = true;
validChars[156] = true;
validChars[158] = true;
validChars[159] = true;
for(var i=161;i<=167;i++) validChars[i] = true;
validChars[176] = true;
for(var i=180;i<=182;i++) validChars[i] = true;
for(var i=191;i<=255;i++) validChars[i] = true;

function checkCode(e){
  var keyCode = (e.which)?e.which:e.keyCode;
  return (validChars[keyCode]==true);
}
</script>
</head>
<body>
<form>
<input type="text" mane="mytext" onkeydown="return checkCode(event)" >
</form>
</body>
</html>




TedInAKCommented:
Thomas,

What is "fulltext"?  Shouldn't the line read:
   var a = text.search(re);
thomas908Author Commented:
>>What is "fulltext"?  Shouldn't the line rea
Sorry, for the typo.
Actually the name of the field is fulltext. While typing in EE I changed it to text. But its wriiten corectly in my code.
So the problem is somewhere else.
thomas908Author Commented:
>>input type="text" mane="mytext" onkeydown="return checkCode(event)" >
I can't send the even object to the function.
I have to pick the value from the text field using

     var text = document.search.value;

thomas908Author Commented:
Also, it needs to be done on Submit, rather than keypress
thomas908Author Commented:
>>if (str.search(re) != -1) alert("Invalid input");

Do we need to create this search function?
thomas908Author Commented:
>>Do we need to create this search function?
Sorry, its an inbuild function. But its not working, may be the regular expression is incorrect
thomas908Author Commented:
I am gettign the value from the text field as

var fulltext = document.search.fulltext.value;

But the regular expression is in Hex, will the 2 work together correctly.
thomas908Author Commented:
Hi TedInAK,
I created a new HTML file and pasted this code

<html>
<head>
<script type="text/javascript">
function validate(input) {
   var re = /[\x00-\x1E\x7F\x81-\x89\x8A\x8D\x8F-\x90\x95-\x99\x9B\x9D\xA0\xA8-\xAF\xB1-\xB3\xB7-\xBE]/g
   input.value = input.value.replace(re, "");
}
</script>
</head>
<body onload="document.getElementById('input').focus()">
<form onsubmit="validate(this.input)">
   <input type="text" name="input" onkeyup="validate(this)">
   <input type="submit">
</form>
</body>
</html>

But it is not working.
There must be something that is missing in this code.
TedInAKCommented:
Try this:

<html>
<head>
<script type="text/javascript">
var invalidChars = new Array;
invalidChars[0] = "0-31";
invalidChars[1] = "127";
invalidChars[2] = "129-137";
invalidChars[3] = "139";
invalidChars[4] = "141";
invalidChars[5] = "143-144";
invalidChars[6] = "149-153";
invalidChars[7] = "155";
invalidChars[8] = "157";
invalidChars[9] = "160";
invalidChars[10] = "168-175";
invalidChars[11] = "177-179";
invalidChars[12] = "183-190";

function decToHex(dec) {
   if (parseInt(dec) == 0) return "00";
   var hex = parseInt(dec).toString(16).toUpperCase();
   if (hex.length%2) hex = "0" + hex;
   return hex;
}

function buildRE() {
   var re = "";
   var temp;
   for (var i = 0; i < invalidChars.length; i++) {
      temp = invalidChars[i].split("-");
      re+= "\\x" + decToHex(temp[0]);
      if (temp[1]) re+= "-\\x" + decToHex(temp[1]);
   }
   return re;
}

function validate() {
   var input = document.getElementById("input");
   var re = new RegExp("[" + buildRE() + "]", "g");
   if (input.value.search(re) != -1) {
      alert("Invalid input");
      input.focus();
      return false;
   }
   return true;
}
</script>
</head>
<body onload="document.getElementById('input').focus()">
<form name="myForm" onsubmit="return validate()">
   <input type="text" name="input">
   <input type="submit" value="Submit">
</form>
</body>
</html>
thomas908Author Commented:
Still the same, this is what I have done

 function decToHex(dec) {
   if (parseInt(dec) == 0) return "00";
   var hex = parseInt(dec).toString(16).toUpperCase();
   if (hex.length%2) hex = "0" + hex;
   return hex;
}
function buildRE() {
   var re = "";
   var temp;
   var invalidChars = new Array;
   invalidChars[0] = "0-31";
   invalidChars[1] = "127";
   invalidChars[2] = "129-137";
   invalidChars[3] = "139";
   invalidChars[4] = "141";
      invalidChars[5] = "143-144";
      invalidChars[6] = "149-153";
      invalidChars[7] = "155";
      invalidChars[8] = "157";
      invalidChars[9] = "160";
      invalidChars[10] = "168-175";
      invalidChars[11] = "177-179";
      invalidChars[12] = "183-190";


   for (var i = 0; i < invalidChars.length; i++) {
      temp = invalidChars[i].split("-");
      re+= "\\x" + decToHex(temp[0]);
      if (temp[1]) re+= "-\\x" + decToHex(temp[1]);
   }
   return re;
}

 function validateCharacters() {
     var fulltext = document.search.fulltext.value;

     var re = new RegExp("[" + buildRE() + "]", "g");
     if (document.search.fulltext.value.search(re) != -1) {
      alert("Invalid input");
   
      return false;
     }
     return true;
 }
thomas908Author Commented:
Also tried putting

var invalidChars = new Array;
   invalidChars[0] = "0-31";
   invalidChars[1] = "127";
   invalidChars[2] = "129-137";
   invalidChars[3] = "139";
   invalidChars[4] = "141";
      invalidChars[5] = "143-144";
      invalidChars[6] = "149-153";
      invalidChars[7] = "155";
      invalidChars[8] = "157";
      invalidChars[9] = "160";
      invalidChars[10] = "168-175";
      invalidChars[11] = "177-179";
      invalidChars[12] = "183-190";

outside the javascript fucntion, but still same result
TedInAKCommented:
This works...what characters are you typing in that slip through?

<html>
<head>
<script type="text/javascript">
function decToHex(dec) {
   if (parseInt(dec) == 0) return "00";
   var hex = parseInt(dec).toString(16).toUpperCase();
   if (hex.length%2) hex = "0" + hex;
   return hex;
}
function buildRE() {
   var re = "";
   var temp;
   var invalidChars = new Array;
   invalidChars[0] = "0-31";
   invalidChars[1] = "127";
   invalidChars[2] = "129-137";
   invalidChars[3] = "139";
   invalidChars[4] = "141";
     invalidChars[5] = "143-144";
     invalidChars[6] = "149-153";
     invalidChars[7] = "155";
     invalidChars[8] = "157";
     invalidChars[9] = "160";
     invalidChars[10] = "168-175";
     invalidChars[11] = "177-179";
     invalidChars[12] = "183-190";


   for (var i = 0; i < invalidChars.length; i++) {
      temp = invalidChars[i].split("-");
      re+= "\\x" + decToHex(temp[0]);
      if (temp[1]) re+= "-\\x" + decToHex(temp[1]);
   }
   return re;
}

 function validateCharacters() {
     var fulltext = document.search.fulltext.value;

     var re = new RegExp("[" + buildRE() + "]", "g");
     if (document.search.fulltext.value.search(re) != -1) {
      alert("Invalid input");
   
      return false;
     }
     return true;
 }
 </script>
</head>
<body onLoad="document.getElementById('input').focus()">
<form name="search" onSubmit="return validateCharacters()">
   <input type="text" name="fulltext">
   <input type="submit" value="Submit">
</form>
</body>
</html>
TedInAKCommented:
BTW...the above JS is your changed version, I just changed the form to match.
thomas908Author Commented:
thanks for replying.
The JS code is not working.
Even if I copy this code to a seperate HTML file, it does not work.

<html>
<head>
<script type="text/javascript">
function validate(input) {
   var re = /[\x00-\x1E\x7F\x81-\x89\x8A\x8D\x8F-\x90\x95-\x99\x9B\x9D\xA0\xA8-\xAF\xB1-\xB3\xB7-\xBE]/g
   input.value = input.value.replace(re, "");
}
</script>
</head>
<body onload="document.getElementById('input').focus()">
<form onsubmit="validate(this.input)">
   <input type="text" name="input" onkeyup="validate(this)">
   <input type="submit">
</form>
</body>
</html>

thomas908Author Commented:
The form code is not a problem. The validation fucntion is getting called upon submit but the fucntion is not giving the appropriate result.
thomas908Author Commented:
Sorry, missed you previous comment
thomas908Author Commented:
All the characters slip through

For example, ASCII 150 (û)
ASCII 178 (&#9619;)
thomas908Author Commented:
ASCII 141 (ì)
ASCII 130 (é)
thomas908Author Commented:
Hi Zvonko
The function will be called when submit button is pressed. There are 4 text fields which need to be validated, I am getting the value of each one of them as

var text1 = document.formName...
var text2 = document.formName...
var text3 = document.formName...

I can't use Keypress, please tell me how ot do it on submit
TedInAKCommented:
bpmurray's post (http://www.experts-exchange.com/Web/Web_Languages/JavaScript/Q_21980769.html#17469290) highlights the problem: û might be ASCII code 150, but it is unicode 251 (hex: 0x00FB).  You might want to check the links in bpmurray's post to see about converting from ASCII to Unicode.
thomas908Author Commented:
Does that mean we should not use this hex conversion and directly use ASCII codes?
TedInAKCommented:
It doesn't have anything to do with hex...if you enter "û" at http://javascript.internet.com/miscellaneous/ascii-character-code.html, you'll see that javascript recognizes it as character code 251 (the unicode decimal number of that character).  That's the same code you get if you were to use charCodeAt() (http://www.w3schools.com/jsref/jsref_charCodeAt.asp).

I think you have to abandon your idea of using the ASCII code, at least for anything above ASCII 127.  You're going to have to find the unicode number for any characters that aren't allowed (or are allowed, whichever) and base your code on that.
ZvonkoSystems architectCommented:
Ahem...



<html>
<head>
<title>Zvonko &#42;</title>
<script>
var validChars = new Array();
validChars[0] = true;
validChars[8] = true;
validChars[9] = true;
for(var i= 32;i<=126;i++) validChars[i] = true;
validChars[128] = true;
validChars[138] = true;
validChars[140] = true;
validChars[142] = true;
for(var i=145;i<=148;i++) validChars[i] = true;
validChars[154] = true;
validChars[156] = true;
validChars[158] = true;
validChars[159] = true;
for(var i=161;i<=167;i++) validChars[i] = true;
validChars[176] = true;
for(var i=180;i<=182;i++) validChars[i] = true;
for(var i=191;i<=255;i++) validChars[i] = true;

function checkCode(e){
  var keyCode = (e.which)?e.which:e.keyCode;
  return (validChars[keyCode]==true);
}
</script>
</head>
<body>
<form>
<input type="text" mane="mytext" onkeydown="return checkCode(event)" >
</form>
</body>
</html>



thomas908Author Commented:
>><input type="text" mane="mytext" onkeydown="return checkCode(event)" >

Thanks for replying, Zvonko
Can we do it on form submit (onSubmit) rather than onkeydown



ZvonkoSystems architectCommented:
Sorry, it seams I missed something above.
OK, what do you want to do with unwanted characters? Remove or replace? Or only alert() that wrong characters were entered?
thomas908Author Commented:
only an alert that wrong char was entered.
ZvonkoSystems architectCommented:
OK:


<html>
<head>
<title>Zvonko &#42;</title>
<script>
var invalidChars = /[^\x20-\x7E\x80\x8A\x8C\x8E\x91-\x94\x9A\x9C\x9E\x9F\xA1-\xA7\xB0\xB4-\xB6\xBF-\xFF]/g;

function checkForm(theForm){
  if(iC=theForm.mytext.value.match(invalidChars)){
    alert("Invalid chars eneterd: "+iC);
    theForm.mytext.select();
    theForm.mytext.focus();
    return false;
  }
  return true;
}
</script>
</head>
<body>
<form onSubmit="return checkForm(this)">
<input type="text" name="mytext" >
<input type="submit" >
</form>
</body>
</html>



thomas908Author Commented:
Thanks Zvonko
Will it work with ASCII values above 127 as specifed by TedInAK above


 >>It doesn't have anything to do with hex...if you enter "û" at http://javascript.internet.com/miscellaneous/ascii- >>character-code.html, you'll see that javascript recognizes it as character code 251 (the unicode decimal number of  >>that character).  That's the same code you get if you were to use charCodeAt()  http://www.w3schools.com/jsref/jsref_charCodeAt.asp).

 >>I think you have to abandon your idea of using the ASCII code, at least for anything above ASCII 127.  You're going  >>to have to find the unicode number for any characters that aren't allowed (or are allowed, whichever) and base  >>your code on that.
ZvonkoSystems architectCommented:
You have to extend the expression to all printable character version that you want to allow.
Like this:


<html>
<head>
<title>Zvonko &#42;</title>
<script>
var invalidChars = /[^\x20-\x7E\x80\x8A\x8C\x8E\x91-\x94\x9A\x9C\x9E\x9F\xA1-\xA7\xB0\xB4-\xB6\xBF-\xFF€ŠŽ‘-”šœžŸ¡-§°´-¶¿-ÿ]/g;

function checkForm(theForm){
  if(iC=theForm.mytext.value.match(invalidChars)){
    alert("Invalid chars eneterd: "+iC);
    theForm.mytext.select();
    theForm.mytext.focus();
    return false;
  }
  return true;
}
</script>
</head>
<body>
<form onSubmit="return checkForm(this)">
<input type="text" name="mytext" >
<input type="submit" >
</form>
</body>
</html>


The reason is: event that you allow 128 is the character with that value blocked: €
By entering their printable representation is that character allowed again.
The set in the expression has to be read like this:

Get all characters that are NOT in the set. The first caret character is that negation not expression.





thomas908Author Commented:
Following are the values written in the text file

134 : ?
135 : ?
136 : ?
137 : ?
139 : ?
141 : ?
143 : ?
144 : ?
149 : ?
150 : ?
151 : ?
152 : ?
153 : ?
155 : ?
157 : ?
160 :  
168 : ¨
169 : ©
170 : ª
171 : «
172 : ¬
173 : ­
thomas908Author Commented:
PLease ignore my previous commnet.
It was meant to be posted for some other question
thomas908Author Commented:
Thanks everyone for helping
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
JavaScript

From novice to tech pro — start learning today.