Text Area Counter in ASP.NET

Back in the day, there were text area counters using javascript for validation. You could program the javascript to do a countdown while the user input text in the text area.

I know you can still do that with .NET the old way,but is there a new automated way with some type of control or ajax or something that you can just wire up?

thanks.
LVL 2
Starr DuskkASP.NET VB.NET DeveloperAsked:
Who is Participating?
 
sm394Connect With a Mentor Commented:
attached is the code snippet for Text Box counter Custom Server Control just add the reference either in code behind or web.config and use it like normal control
using System;
using System.ComponentModel;
using System.Web.UI;
using System.Web.UI.WebControls;
 
/// <summary>
/// CustomTextBox with text counter developed by Faizan email fazee511@hotmail.co.uk
/// </summary>
 
namespace CustomControls
{
    [DefaultProperty("Text")]
    [Description("Extended TextBox v1.0 (Developed by Faizan email fazee511@hotmail.co.uk)")]
 
    [ToolboxData("<{0}:CustomTextBox runat=server></{0}:CustomTextBox1>")]
    public class CustomTextBox : System.Web.UI.WebControls.TextBox
    {
 
 
        //====================================================
        protected override void Render(HtmlTextWriter output)
        {
            //-----------Handles values assignment triming i.e txtTextBox.Text=--------
            int characterLeft;
            if (MaxLength <= this.Text.Length)
            {
                characterLeft = 0;
                this.Text = this.Text.Substring(0, MaxLength);
            }
            else
            {
                characterLeft = MaxLength - this.Text.Length;
            }
 
            //-------------------------------------------------------------------------
            output.Write("<div style='" + WrapperInlineStyle + "'  class='dub3txb_outer' >");
            if (this.CountDisplay == CountDisplay.TopLeft)
            {
                output.Write("<p class='dub3txb_p_left'>");
                output.Write("<label id='" + this.ClientID + "_lblCount' class='dub3txb_label'>" + LabelText + characterLeft + "</label>");
                output.Write("</p>");
            }
            else
                if (this.CountDisplay == CountDisplay.TopRight)
                {
                    output.Write("<p class='dub3txb_p_right'>");
                    output.Write("<label id='" + this.ClientID + "_lblCount' class='dub3txb_label'>" + LabelText + characterLeft + "</label>");
                    output.Write("</p>");
                }
            base.CssClass = "dub3txb_txb";
            base.Attributes.Add("style", TextBoxInlineStyle);
            base.Render(output);
 
            if (this.CountDisplay == CountDisplay.BottomLeft)
            {
                output.Write("<p class='dub3txb_p_left'>");
                output.Write("<label id='" + this.ClientID + "_lblCount'  class='dub3txb_label'>" + LabelText + characterLeft + "</label>");
                output.Write("</p>");
            }
            else
                if (this.CountDisplay == CountDisplay.BottomRight)
                {
                    output.Write("<p class='dub3txb_p_right'>");
                    output.Write("<label id='" + this.ClientID + "_lblCount' class='dub3txb_label'>" + LabelText + characterLeft + "</label>");
                    output.Write("</p>");
                }
            output.Write("</div>");
        }
        //============================================================
        protected override void OnPreRender(EventArgs e)
        {
            base.OnPreRender(e);
 
            string checkMaxLength = "function checkMaxLength(textBox,e,maxLength) {\n" +
                //"alert(e); "+
                                      "e = (e) ? e : ((event) ? event : null);\n" +//firefox ie fix
                //"alert(e.keyCode); " +
                //"alert(textBox.value.length); " +
                //" if( ( textBox.value.length > (" + this.MaxLength + "-1) )  && e.keyCode!=8)\n " +
                                    " if( ( textBox.value.length > (maxLength-1) )  && e.keyCode!=8)\n " +
                                       "{\n" +
                                       "var cont=textBox.value;\n" +
                //"textBox.value = cont.substring(0,(" + this.MaxLength + "));\n" +
                                        "textBox.value = cont.substring(0,(maxLength));\n" +
                                        "return false; \n" +
                                        "}\n" +
                                    " else \n" +
                                    "{ \n" +
                                    "  return true; \n" +
                                    "} \n" +
                                  "} \n";
 
 
            //----------------------------------------------------------------------------------
 
            string checkCount = "function checkCount(textBox,e,lblCount,labelText,maxLength) {\n" +
                //"document.getElementById('lblCount').innerHTML=10-textBox.value.length;"+
                //"var count= "+this.MaxLength + "-textBox.value.length;" +
                //"var count= (" + this.MaxLength + "> textBox.value.length)?" + this.MaxLength + "-textBox.value.length:0 ; \n" +
                                   "var count= (maxLength> textBox.value.length)? maxLength-textBox.value.length:0 ; \n" +
                //"document.getElementById('lblCount').innerHTML= 'Characters left: '+ count ;\n" +
                                   "lblCount.innerHTML=labelText + count ;\n" +
                //"var txt =  document.forms[0].txtCount;" +
                //"txt.value=10-textBox.value.length;" +
                                 "} \n";
 
 
            if (this.TextMode == TextBoxMode.MultiLine)
            {
                Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "checkLength", checkMaxLength, true);
                //this.Attributes.Add("onkeypress", "return checkMaxLength(this,event);");
            }
            //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
            Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "checkCount", checkCount, true);
            //this.Attributes.Add("onkeypress", "checkCount(this);return checkMaxLength(this);");
 
            this.Attributes.Add("onkeyup", "checkCount(this,event,document.getElementById('" + this.ClientID + "_lblCount'),'" + LabelText + "'," + MaxLength + ");return checkMaxLength(this,event," + MaxLength + ");");
 
            //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
        }//end on pre render
        //============================================================================
        /// <summary>
        /// Count display direction
        /// </summary>
        [Description("Sets the direction of character left count")]
        [Category("Dub3")]
        [DefaultValue(CountDisplay.BottomLeft)]
        public CountDisplay CountDisplay
        {
            get
            {
                object o = ViewState["CountDisplay"];
                return (o != null ? (CountDisplay)o : CountDisplay.BottomLeft);
            }
            set
            {
                ViewState["CountDisplay"] = value;
            }
        }
        /// <summary>
        /// Label text
        /// </summary>
        [Description("Sets the label text")]
        [Category("Dub3")]
        [DefaultValue("Characters left:")]
        public string LabelText
        {
            get
            {
                object o = ViewState["LabelText"];
                return (o != null ? (string)o : "Characters left:");
            }
            set
            {
                ViewState["LabelText"] = value;
            }
        }
 
        /// <summary>
        /// Textbox inline style
        /// </summary>
        [Description("Sets textbox inline style")]
        [Category("Dub3")]
        [DefaultValue("")]
        public string TextBoxInlineStyle
        {
            get
            {
                object o = ViewState["TextBoxInlineStyle"];
                return (o != null ? (string)o : "");
            }
            set
            {
                ViewState["TextBoxInlineStyle"] = value;
            }
        }
 
        /// <summary>
        /// wrapper inline style
        /// </summary>
        [Description("Sets wrapper inline style")]
        [Category("Dub3")]
        [DefaultValue("")]
        public string WrapperInlineStyle
        {
            get
            {
                object o = ViewState["WrapperInlineStyle"];
                return (o != null ? (string)o : "");
            }
            set
            {
                ViewState["WrapperInlineStyle"] = value;
            }
        }
 
 
    }//end class
 
    #region enums
 
    public enum CountDisplay
    {
        TopLeft,
        TopRight,
        BottomLeft,
        BottomRight
    }
 
    #endregion
}

Open in new window

0
 
BuginatorCommented:
Yes, it's very possible. You are right about that you have to use AJAX.

But I wouldn't have done it like that, that's why I'm not posting code with this post. Remember that each single keypress will require a dedicated request from the server when using ajax, and that steals valuable resources. But of course, if it isn't a popular site, then it might not be important. A post with 500 characters require 500 server request. 10 users at a time multiplied with 500 request = 5000 request, which is alot for someting unnecessary! It is nevertheless not something what we would call a "best practice" way of doing it. Why don't you want to use javascript?
0
 
BuginatorCommented:
Interesting solution sm394, but it still ends up with using javascript as the final character counter (which I think is a good thing). I haven't tested your code, but it might be what the user want, since it seems to be a relatively automated control. I just got the impression that the user wanted to avoid javascript.
0
Upgrade your Question Security!

Your question, your audience. Choose who sees your identity—and your question—with question security.

 
Starr DuskkASP.NET VB.NET DeveloperAuthor Commented:
sm394,
Thanks!
What kind of project do I create to put this in? A Class library?
 
0
 
Starr DuskkASP.NET VB.NET DeveloperAuthor Commented:
Do you know if there is a VB version?
 
thanks.
 
0
 
Starr DuskkASP.NET VB.NET DeveloperAuthor Commented:
I got it converted to VB and used a class library project.
Let me know if I should have used a different kind.
thanks!
 
0
 
sm394Commented:
That's your choice How would you like to break things for reusability
 if you got WebSite Project then you can place in App Code folder
or
in case of WebApplication Project  as you said you can add  class lib proj or CustomServerControl proj into your existing solution

then simply do web.config settings and you are ready to go . ofcourse you can compile custom text box control into dll as well and just ref that dll rather then class library project
web.config settings
      <pages   >
                  <controls>

                        <add tagPrefix="cc" namespace="CustomControls" assembly="CustomControls"/>
                  </controls>
            </pages>
0
 
sm394Commented:
you can also compile this c# version in to dll and use that dllinto vb proj
0
 
Starr DuskkASP.NET VB.NET DeveloperAuthor Commented:
For any future users...
I found a bug in this...
It only registers the javascript for checkmaxlength if the textbox is multiline, but it calls the checkmaxlength function, no matter what in the add.attributes:

if (this.TextMode == TextBoxMode.MultiLine)
{
Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "checkLength", checkMaxLength, true);

}
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "checkCount", checkCount, true);

this.Attributes.Add("onkeyup", "checkCount(this,event,document.getElementById('" + this.ClientID + "_lblCount'),'" + LabelText + "'," + MaxLength + ");return checkMaxLength(this,event," + MaxLength + ");");
0
 
sm394Commented:
the control is intended only for multiline text box
you  can tweak the source code to fit your needs
in your case remove the if condition  and simply register the checkMaxLength js function

if (this.TextMode == TextBoxMode.MultiLine)
{
Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "checkLength", checkMaxLength, true);

}


with only


Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "checkLength", checkMaxLength, true);

0
 
Starr DuskkASP.NET VB.NET DeveloperAuthor Commented:
Did you write this? Because I'm pointing out that the control is written to allow you to define the TextMode and it does not override it to force Multiline. As well, it checks for multiline and doesn't register an important part of the script unless it is.
I do understand how to fix it, but I thought I should point this out for future users.
I'm am rewriting it as a forced multiline control myself. You don't really need a textcounter on a singleline textbox.
 
0
 
Starr DuskkASP.NET VB.NET DeveloperAuthor Commented:
I should also point out that bottomright and bottomleft produce the same result, as do topright and topleft. Both only put the text on the left.
thanks again!
 
0
 
Starr DuskkASP.NET VB.NET DeveloperAuthor Commented:
Also, it appears a CSS class should go with this to accommodate the rights, but it wasn't included.
It calls for this missing class:
dub3txb_p_right
0
 
Starr DuskkASP.NET VB.NET DeveloperAuthor Commented:
sm394,
This is excellent, I want to thank you so much for providing it for me!
Bobi
 
0
 
Starr DuskkASP.NET VB.NET DeveloperAuthor Commented:
Can you provide the missing class file too?
thanks!
 
0
 
sm394Commented:
as you can see from the code i supplied there is plenty of left over code i.e the control is not fully tested and finished.
the css bit
i.e

.dub3txb_p_left
{
    float: left;
}
.dub3txb_p_right
{
    float: right;
}
.dub3txb_outer
{
    width:300px;
}

ref the css
and in your aspx

<cc:CustomTextBox runat="server" ID="test"  TextMode="MultiLine"   CountDisplay="BottomRight" MaxLength="10"></cc:CustomTextBox>
   
now control should render char left according to option set in CountDisplay property

0
 
Starr DuskkASP.NET VB.NET DeveloperAuthor Commented:
Well, either way, you did a great job and I couldn't have done this without your code.
Thanks a lot!
 
0
 
sm394Commented:
you can also use this property to set inline styles e.g.

WrapperInlineStyle="border:dashed 1px black; width:300px;"
in that case you don't need
.dub3txb_outer
{
    width:300px;
}
0
 
sm394Commented:
@Bob you are welcome
just in case if someone needed to force mulitline by default simply add
  this.TextMode = TextBoxMode.MultiLine   in OnPreRender Event
in that case we don't need to set multiLine TextMode property in aspx

 protected override void OnPreRender(EventArgs e)
        {
            base.OnPreRender(e);
            this.TextMode = TextBoxMode.MultiLine;

Hope that helps
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.