The character counter on the contact form is a fairly simple client-side script. I have implemented it from the server-side (in VB.NET) and registered it with the .NET architecture. The server-side code builds the actual client-side code, registers the code with .NET, and adds an attribute to the multiline text box ("txtBody") which contains the body text of our message. The code to create the script block (I called the function itself "countText") and register it with .NET follows: Dim sbText As New StringBuilder Dim strFunction As String = String.Empty Dim strType As Type = GetType(String) Dim strName As String = "countText" 'create the function using a StringBuilder object. With sbText .Append("function countText(int) {" & vbCrLf) .Append(vbTab & "var textCount = document.getElementById(""" & txtBody.ClientID & """).value;" & vbCrLf) .Append(vbTab & "var strCountText = 'Remaining characters: ' + eval(" & txtBody.MaxLength & " - textCount.length);" & vbCrLf) .Append(vbTab & "if(textCount.length > " & (txtBody.MaxLength - (txtBody.MaxLength * 0.1)) & "){" & vbCrLf) .Append(vbTab & vbTab & "strCountText = 'Remaining characters: ONLY ' + eval(" & txtBody.MaxLength & " - textCount.length) + '';" & vbCrLf) .Append(vbTab & "}" & vbCrLf) .Append(vbTab & "if(textCount.length > " & (txtBody.MaxLength - 1) & "){" & vbCrLf) .Append(vbTab & vbTab & "document.getElementById(""" & txtBody.ClientID & """).value = document.getElementById(""" & txtBody.ClientID & """).value.substring(0,""" & txtBody.MaxLength & """);" & vbCrLf) .Append(vbTab & vbTab & "strCountText = 'Remaining characters: 0';" & vbCrLf) .Append(vbTab & "}" & vbCrLf) .Append(vbTab & "document.getElementById(""divCountText"").innerHTML = strCountText;" & vbCrLf) .Append(vbTab & "return true;" & vbCrLf) .Append("}" & vbCrLf) 'convert the StringBuilder object contents to a string. strFunction = sbText.ToString() 'whack the contents of the StringBuilder object. .Remove(0, .Length) End With 'Register our function as a client script block. If Not ClientScript.IsClientScriptBlockRegistered(strName) Then ClientScript.RegisterClientScriptBlock(strType, strName, strFunction, True) End If 'tidy up - destroy our StringBuilder object. sbText = Nothing Note that countText() starts with the MaxLength value assigned to the txtBody text box, and once a commenter has used 90% of the characters available, the appearance of the counter changes. In my case, I'm allowing 250 characters in the feedback form. Once a person has only 25 available characters remaining, the font color is changed to red and the word "ONLY" precedes the figures reported by the counter. With the script block code in place, we need to add an onkeyup attribute to the textarea control to trigger the counter. txtBody.Attributes.Add("onkeyup", "countText(" & txtBody.MaxLength & ");") Finally, don't forget to place a call to your subroutine that does all the mojo in your Page_Load() event handler. For example, I called mine PrepBodyCounter(): Public Sub Page_Load(ByVal Sender As Object, ByVal e As EventArgs) Handles Me.Load 'Assemble text and navigation Call AssembleNavigation() 'Assemble form functionality Call PrepBodyCounter() . . . That should be it! Contact me using the site's contact form if you have questions. Feel free to use the code in your projects. A shout out in your project would be thoughtful. Also, drop me a line and let me know how you might have tweaked things to better suit your needs. Finally, I wouldn't profess to be THE expert on matters represented in my code -- so drop me a line if you have constructive suggestions, too. I'd like to hear from you! Best, halfgk copyright 2006 halfgk.com