Back in December 2006 I wrote an article titled adding a quick character counter to a textbox in ASP.NET. Over 2 years later, and the article still gets a lot of views as well as a fair few comments – it seems there are a few people out there who needed character counters on their textboxes!
After getting a couple of recent comments from people who couldn't get it to work in a Master Page I thought I'd post a quick update to the article and include a couple of methods which work with Master Pages.
(Note: If I had to do something like this today, I'd use jQuery, which would be a lot simpler, however all I want to do here is to post a quick update to my original article. Also, please excuse the poor code formatting - I've not had a chance to setup a C# code formatter, although I know there are plenty of them out there).
The quick and simple version
First, the quick and simple version – lets get this working in a master page nice and quickly. Simply change the first parameter of your onkeyup and onkeydown events to be 'this', as shown below:
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder" runat="server">
<h4>Count This Text</h4>
<asp:TextBox ID="txtToCount" TextMode="MultiLine"
runat="server" onkeyup='textCounter(this, this.form.remLen, 160);'
onkeydown="textCounter(this, this.form.remLen, 160);" />
<br />
<input readonly="readonly" type="text" name="remLen" size="3" maxlength="3" value="160" /> characters left
</asp:Content>
The JavaScript function for this example is the same as my previous post, but here it is again for completeness:
<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>
A quick note here – if you're using Visual Studio 2005, then it might complain that onkeyup and onkeydown aren't valid events for an asp:TextBox – don't worry about that, it's not Visual Studio which needs to know about those events, it's the browser, and in that context they're perfectly valid. They've fixed this issue in Visual Studio 2008, but from a few of the comments in the previous article there are still a lot of people out there using 2005.
Using a .NET control for the counter output
The above sample is very quick and basic – but it will only work with a html control for the display of the counter. If you need your output to go to an ASP.NET control, then we can hack things about to achieve that.
First, our content in the master page. It's the same as before, but I'm displaying the counter in an asp:TextBox, and as I'm no longer using a simple html input for the counter, I've replaced this.form.remLen with a variable called outputField.
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder" runat="server">
<h4>Count This Text</h4>
<asp:TextBox ID="txtToCount" TextMode="MultiLine"
runat="server" onkeyup='textCounter(this, outputField, 160);'
onkeydown="textCounter(this, outputField, 160);" />
<br />
<asp:TextBox ID="txtOutput" Text="160" runat="server" />
</asp:Content>
Next I assign the outputField variable a value. I do this by grabbing the ClientID for my ASP.NET control, and storing in my variable. I've placed this in my head ContentPlaceHolder, but you can put it anywhere you like. When the page loads, the variable will look something like 'ctl00_ContentPlaceHolder_txtOutput'.
<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="server">
<script language="javascript" type="text/javascript">
var outputField = '<%= txtOutput.ClientID %>';
</script>
</asp:Content>
Finally, we need to modify our JavaScript function slightly. The previous version was sent through a reference to the actual control, whereas now all we're passing through is the ID of an element in the DOM. So we modify the JavaScript to use the ID and grab the reference to the control:
<script type="text/javascript">
function textCounter(field, countfield, maxlimit) {
var output = document.getElementById(countfield);
if (output == null) {return;}
if (field.value.length > maxlimit)
field.value = field.value.substring(0, maxlimit);
else
output.value = maxlimit - field.value.length;
}
</script>
And we're done. You may wonder why the need for the JavaScript variable? Why can't we simply use txtOutput.ClientID in the declaration of our onkeyup and onkeydown events like this:
<asp:TextBox ID="txtToCount" TextMode="MultiLine" runat="server" onkeyup='textCounter(this, "<%= txtOutput.ClientID %>", 160);' onkeydown='textCounter(this, "<%= txtOutput.ClientID %>", 160);' />
This is becasue the ASP.NET parser can not parse the tag "<% = %>" for a server side control (i.e. any control with runat="server"), so the above control would be rendered in HTML as:
<textarea name="ctl00$ContentPlaceHolder$txtToCount" rows="2" cols="20" id="ctl00_ContentPlaceHolder_txtToCount" onkeyup="textCounter(this, "<%= txtOutput.ClientID %>", 160);" onkeydown="textCounter(this, "<%= txtOutput.ClientID %>", 160);"></textarea>
Which is obviously not going to work.
Summary
A couple of things to mention - I've only tested the above examples in Firefox 3 and IE 7. Also, if you're looking to do something like this, or anything with JavaScript then you should check out jQuery. It makes any JavaScript related work a LOT simpler, and is a lot cleaner than the methods I've posted above.
Hope this helps!
Link: ASP.NET Text Character Counter (Original article)
Posted on Saturday, February 7, 2009 5:53 PM |