Validating TextArea

From PikaDocs

Table of contents

What is a Textarea field?

A textarea field is an HTML field that has horizontal and vertical scroll bars and allows the user to type what might seem like unlimited text. However, the field length is generally not unlimited.

Take for example, the field Eligibility Notes on Pika's Eligibility tab. In MySQL this is a field in the cases table called elig_notes that is a varchar(150). It can contain a maximum of 150 characters. If you submit more than that, MySQL will throw away everything over 150 and won't tell you. Pika won't tell you either.

So, to try to save yourself lost data, you can use javascript to count the number of characters, and not let the user submit the form if they have typed more than 150 in the box.

Say you type the following characters into the field in Pika:

aaaaaaaaaa
bbbbbbbbbb
cccccccccc
dddddddddd
eeeeeeeeee
ffffffffff
gggggggggg
hhhhhhhhhh
iiiiiiiiii
jjjjjjjjjj
kkkkkkkkkk
llllllllll
mmmmmmmmmm

How many characters are there? Well, there are 10 letters per line, so the letters alone make 130 characters. If a newline is 1 character there are 12 additional characters for a total of 142. If a newline is 2 characters there are 24 additional characters for a total of 154.

MySQL thinks a newline is 2 characters. I can't find proof of this in the MySQL documentation, though. So how do I know? Well, if you put that text above into the Eligibility Notes field, and submit it, when you come back to the page, what is in the field? Here's what:

aaaaaaaaaa
bbbbbbbbbb
cccccccccc
dddddddddd
eeeeeeeeee
ffffffffff
gggggggggg
hhhhhhhhhh
iiiiiiiiii
jjjjjjjjjj
kkkkkkkkkk
llllllllll
mmmmmm

MySQL threw away the last 4 m's. Since we know the maximum size of the field is 150, then there must be 150 characters. The only way that could be true is if MySQL is counting the newline as 2 characters. 136 letters + 24 characters for the newline = 150 characters. So, moving on....

Using Javascript to validate the textarea field

The next thing to cover is how to use javascript to count up the characters in the field and stop the form from submitting if it is over the limit.

Here's some example javascript you could use for this. Paste this code at the bottom of subtemplates/case_elig.html

<script type="text/javascript" language="JavaScript">
function pk_checkElig_Notes (val) {             // see if the elig_notes field has more than allowed characters
  if (val.length==0)            // don't validate an empty field
    return true;
    
  var lengthElig_Notes = 150;   // the size of the character field elig_notes in your cases table 
  
  // now check the field length
  if (val.length > lengthElig_Notes)
    {
      alert('Sorry, the Eligibility Notes field only allows ' + lengthElig_Notes + 
            ' characters, and it currently has ' + val.length + 
            ' characters. Please remove ' + (val.length - lengthElig_Notes) + ' characters.');
      return false; 
   }
 else
   return true; 
}
</script>


Now, at the top of subtemplates/case_elig.html find the line that says form action= and comment it out. (Surround it with these characters:
<!--
and
-->
which are HTML comment markers). Put the following line in as the form action line for now:
<form action="%%[base_url]%%/ops/update_case.php" method="post" name="ws" onSubmit="calc_income();pk_checkElig_Notes(document.ws.elig_notes.value);">

A Subtle Problem

If you start using this javascript, or a bit that you write yourself, you will discover something. You will discover that using IE on Windows, you won't be able to submit the form when using that bit of data up above. IE will tell you that you are over 150 characters. Firefox, on the other hand, will let you put in 155 characters and won't stop you from submitting the form. MySQL will still throw away those extra 5 characters though. Try it and see, if you want to convince yourself that it happens.

It took me quite a while to figure out why it does happen. Here's a good blog post (http://www.sitepoint.com/blogs/2004/02/16/line-endings-in-javascript/) on the subject. Part of what it says is:

....Firefox treats newlines as ‘\n’ no matter what platform it runs on
....on IE for Windows and IE for Macintosh because those 
browsers use ‘\r\n’ and ‘\r’ respectively.

So do you see what happens? Firefox is counting a newline as only one character, a '\n'. IE for Mac counts it only as '\r'. But IE on Windows counts is as '\r\n'. Now, I don't think that you can say one of these ways is truly correct. But what you can say is that for this validation to make sense, we need javascript to do the same thing MySQL does. That is, count a newline as 2 characters.

A Subtle Fix

So, to solve this we had better manipulate the newlines that are in the textarea and if they are only 1 character, we make them two. Then javascript's counting will match MySQL's, and we won't lose any data.

Here is revised javascript code. Now it is broken into 2 functions. Use this to replace the javascript example I gave above.

<script type="text/javascript" language="JavaScript">
function pk_checkElig_Notes (val) {             // see if the elig_notes field has more than allowed characters
  if (val.length==0)            // don't validate an empty field
    return true;
    
  var lengthElig_Notes = 150;           // the size of the character field elig_notes in your cases table 
  
  // first call a function to fix the newlines for MySQL type counting
  val = pk_fixnewlines_textarea (val);
  // now check the field length
  if (val.length > lengthElig_Notes)
    {
      alert('Sorry, the Eligibility Notes field only allows ' + lengthElig_Notes + 
            ' characters, and it currently has ' + val.length + 
            ' characters. Please remove ' + (val.length - lengthElig_Notes) + ' characters.' +
            ' A Return or Enter counts as 2 characters.');
      return false; 
   }
 else
   return true; 
}


function pk_fixnewlines_textarea (val) {             
  // Adjust newlines so can do correct character counting for MySQL. MySQL counts a newline as 2 characters.
  if (val.indexOf('\r\n')!=-1)
    ; // this is IE on windows. Puts both characters for a newline, just what MySQL does. No need to alter
  else if (val.indexOf('\r')!=-1)
    val = val.replace ( /\r/g, "\r\n" );        // this is IE on a Mac. Need to add the line feed
  else if (val.indexOf('\n')!=-1)
    val = val.replace ( /\n/g, "\r\n" );        // this is Firefox on any platform. Need to add carriage return
  else 
    ;                                           // no newlines in the textarea  
  return val;
}
</script>

A More Comprehensive Approach

Well, that covers the solution to this problem. But you are left with a bunch of javascript code stuck in your subtemplates/case_elig.html file which could become hard to maintain. And what about validating other textarea fields. Well, this isn't the be-all and end-all solution, but if you are interested in something more comprehensive, take a look at the approach I am using over at Vermont validation. I separate out most of the javascript into a single file, which I then include into each of my subtemplates as needed.




Note from Andrew: I think the code will work for a Mac client, but I don't have access to one to test. You would need to apply the javascript code I provide onto a Pika server (Windows or Linux) and access that server using a web browser on a Mac. I think that the code will work, but if someone is willing to test it and confirm, that would be great. Put a note right here if you confirm that it works.

> -----Original Message-----
> From: Aaron Worley 
> Sent: Thursday, August 10, 2006 11:03 AM
> To: Andrew Cameron
> Cc: Pika Users Listserv (E-mail)
> Subject: Re: [Pika Users] RE: validating the length of a 
> textarea field
> with javascript
> 
> 
> Andrew, I confirmed that your code works for Firefox/Mac, 
> Safari/Mac,  
> IE/Win and Firefox/Win.  It's counting newlines as 2 characters on  
> all 4 browsers I tested.
> 
> -Aaron

Original entry by Andrew Cameron 2006/8/9
Legal Services Lawline of Vermont (http://www.lawlinevt.org/) and Vermont Legal Aid (http://www.vtlegalaid.org/)