I was asked recently as to how best handle client side cut & pastes using asp:textbox. The main problem was when the TextMode is set to multiline the MaxLenght parameter is ignored.
Client side: JavaScript solution
function textCounter(field, countfield, maxlimit)
{
var thisfield = $get(field);
var counter = $get(countfield);
if (thisfield.value.length > maxlimit)
thisfield.value = thisfield.value.substring(0, maxlimit);
else
counter.innerHTML = maxlimit - thisfield.value.length;
}
Notice $get. This is the dom equivelent to document.getElementById courtsey of the asp.net ajax javascript client library. http://asp.net/AJAX/Documentation/Live/ClientReference/Global/GetShortCutMethod.aspx
$get is interchangable with document.getElementById.
Client side: ASP.NET
</asp:TextBox ID="txt_headline" runat="server" MaxLength="50" TextMode="MultiLine" ToolTip="Please enter only 50 chars" Width="300px">
<span id="count_headline" style="font-weight: bold">50</span> characters
To get this code working we need to bind the form attributes onKeyDown, onKeyUp, onChange
Importantly, we use onChange to catch our paste function
Server Side C#
protected void Page_Load(object sender, EventArgs e)
{
textcounter(); //call to bind attributes
}
private void textcounter()
{
//validation
txt_headline.Attributes.Add("onKeyDown", "j a v a s c r i p t:textCounter('" + txt_headline.ClientID + "', 'count_headline', 50);");
txt_headline.Attributes.Add("onKeyUp", "j a v a s c r i p t:textCounter('" + txt_headline.ClientID + "', 'count_headline', 50);");
txt_headline.Attributes.Add("onChange", "j a v a s c r i p t:textCounter('" + txt_headline.ClientID + "', 'count_headline', 50);");
}
Please replace j a v a s c r i p t with javascript in above example
Now, when we run our colution we will have a text counter & we will also capture paste events to lock out string longer than we require. We are capturing the changes after KeyDown, KeyUp and importantly OnChange (cut & paste)
Futher enchancements
By default, when I create a simple form I would expressively as validation
</b>
</asp:TextBox ID="txt_headline" runat="server" MaxLength="50" TextMode="MultiLine" ToolTip="Please enter only 50 chars"
Width="300px">
<span id="count_headline" style="font-weight: bold">50</span> characters</asp:RequiredFieldValidator
ID="RequiredFieldValidator1" runat="server" ControlToValidate="txt_headline"
Display="Dynamic" ErrorMessage="<br />Headline Required!">
</asp:RegularExpressionValidator ID="RegularExpressionValidator3" runat="server" ControlToValidate="txt_headline"
Display="Dynamic" ErrorMessage="<br />Headline cannot contain < or >" ValidationExpression="[^<>]*">
To enrich this solution for simple form why not use ValidatorCallOutExtender as documented
http://www.asp.net/AJAX/AjaxControlToolkit/Samples/ValidatorCallout/ValidatorCallout.aspx
</asp:RegularExpressionValidator ID="RegularExpressionValidator1" runat="server" ControlToValidate="txt_headline" Display="Dynamic" ErrorMessage="<br />Headline cannot contain < or >" ValidationExpression="[^<>]*">
</cc1:ValidatorCalloutExtender ID="txt_headline " runat="server" TargetControlID="RequiredFieldValidator1">
This requires the use of the AjaxControlKit to be added to you project, and brings much of the rich form interaction we have come to expect.
This article, however does not exclude the idea of good server side validation. Never expect that your user relies on JavaScript to validate. Personally I add universal validation to my entity class saving the labourous task of repeatitly importing/writing validation routines. But that is for another blog.