A textbox character counter is a pretty simple piece of functionality, and there's a lot of different ways to apply one to your application. The following method is nice and simple, and can be done using only clientside JavaScript if required, or combined with server side code in order to create a more dynamic effect (ie, turning the counter on/off conditionally).
First, we'll add the most basic static implementation of the field counter to a form using only a JavaScript function and event handlers in the aspx file, then we'll look at how we can extend the functionality and dynamic nature of the counter by using server side code.
Basic Implementation
First, we need to add a small JavaScript function somewhere. For now, just add it somewhere in your form body, or if you have a common library of JavaScript functions in a .js file, simply add it in there. The function looks like this: <script type="text/javascript">
function textCounter(field, countfield, maxlimit)
{
if (field.value.length > maxlimit)
field.value = field.value.substring(0, maxlimit);
else
countfield.value = maxlimit - field.value.length;
}
</script>
Now add the event handlers to the text field, which in this case is called 'txtMessage':
<asp:TextBox ID="txtMessage" TextMode="MultiLine" Width="200px" Rows="3" runat="server" onkeyup="textCounter(txtMessage, this.form.remLen, 160);" onkeydown="textCounter(txtMessage, this.form.remLen, 160);" />
Finally, add the HTML input field which will display the counter:
<input readonly="readonly" type="text" name="remLen" size="3" maxlength="3" value="160" /> characters left
That's the basic implementation done. Pretty simple.
You should now be able to load your form, and type text in the textbox while the counter updates. Once you hit your character limit, you'll be prevented from typing any more characters in the box.
This all works fine in a simple example, but there are some serious limitations with the static implementation. What happens if txtMessage is embedded inside another element, such as a DataGrid or Repeater? It's name will no longer simply be 'txtMessage', as the name of the parent control will be added when it's rendered to the browser. What happens if we want to remove the character counter for any reason based on the contents of the page? Finally, what about if we want to change the way our JavaScript function performs for any reason? These are all limitations we can overcome with serverside code.
Adding some Server Side smarts
First, lets revisit the JavaScript function. Maybe for some reason we don't want to add it to a .js library, or to the .aspx file, then as an alternative we can dynamically add the function in either the Page_Load or the OnLoad event of our page using Page.ClientScript.RegisterClientScriptBlock (if you're using ASP.NET 1.1 then this is Page.RegisterClientScriptBlock), like so:
protected void Page_Load(object sender, EventArgs e)
{
string theFunction = @"<script language=javascript>
function textCounter(field, countfield, maxlimit)
{
if (field.value.length > maxlimit)
field.value = field.value.substring(0, maxlimit);
else
countfield.value = maxlimit - field.value.length;
}
</script>";
Page.ClientScript.RegisterClientScriptBlock(this.GetType(),
"ClientScriptFunction", theFunction);
}
In this simple example it doesn't seem overly useful, however consider the fact that you could dynamically change the way the JavaScript behaves here in the code (possibly based on the state of the page), and dynamically output a different function based on different scenarios. Using String.Format you can cleanly manipulate this function, and substitute parts of it at will - for example, if your JavaScript function contained text messages that were displayed to the user, then this would be an easy place to add multi language support.
Now, lets change the event handlers on the txtMessage field so they're created dynamically when the page loads. Remove the onkeyup and onkeydown events from your definition of txtMessage in the aspx file, and add the following code to your Page_Load or OnLoad event in code:
string theFunction = "javascript:textCounter(" + txtMessage.ClientID + ",this.form.remLen,160);";
txtMessage.Attributes.Add("onKeyDown", theFunction );
txtMessage.Attributes.Add("onKeyUp", theFunction);
This solves a couple of issues for us. Firstly, we no longer need to worry about what the exact name of our textbox control 'txtMessage' ends up being. It can be nested inside repeaters, grids, whatever - txtMessage.ClientID will always return the full and proper name for us. This also means we can apply counters across multiple textboxes on a form, however we'd obviously need to add multiple output fields to our form somewhere and modify the JavaScript function accordingly. We also have the ability to change which control we want to apply the counter to - if we need to select which textbox is having the counter applied to it when the form loads, then we can do that simply by using it's ClientID property. Adding the events in code also allows us to easily disable the counter if we need to. For example, consider that txtMessage resides on a form which is used to send a message via SMS or Email. The 160 character limitation isn't required for email, so if that's what the user has selected, then we can simply not add the event handlers to the txtMessage control when the page is (re)loaded. in this case, you might want to enclose the html output field and text in a panel, and show/hide that accordingly as well as shown in the following simple example:
if(rbModeSelect.SelectedValue == MessageTypesEnum.SMS.ToString())
{
string theFunction = "javascript:textCounter(" + txtMessage.ClientID + ",this.form.remLen,160);";
txtMessage.Attributes.Add("onKeyDown", theFunction);
txtMessage.Attributes.Add("onKeyUp", theFunction);
pnlSMSCharsRemaining.Visible = true;
}
else
{
txtMessage.Attributes.Remove("onKeyDown");
txtMessage.Attributes.Remove("onKeyUp");
pnlSMSCharsRemaining.Visible = false;
}
Tags: ASP.NET
Summary
The above example shows you how to implement a pretty simple character counter to a text field. However it should also give you an insight into some of the functionality that is available when you combine client side script with server side code. I'll discuss this further in one of my next articles, expanding on these concepts as well as showing a few more advanced techniques.
EDIT: 07 Feb 09, For those of you who are trying to get something like this to work with Master Pages, I've created a quick update post: ASP.NET Text Character Counter – the Master page version