?
Solved

Text Area Counter in ASP.NET

Posted on 2009-04-15
19
Medium Priority
?
507 Views
Last Modified: 2012-05-06
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.
0
Comment
Question by:Starr Duskk
  • 10
  • 7
  • 2
19 Comments
 
LVL 5

Expert Comment

by:Buginator
ID: 24153262
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
 
LVL 13

Accepted Solution

by:
sm394 earned 2000 total points
ID: 24153428
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
 
LVL 5

Expert Comment

by:Buginator
ID: 24153471
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
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 2

Author Comment

by:Starr Duskk
ID: 24158536
sm394,
Thanks!
What kind of project do I create to put this in? A Class library?
 
0
 
LVL 2

Author Comment

by:Starr Duskk
ID: 24158687
Do you know if there is a VB version?
 
thanks.
 
0
 
LVL 2

Author Comment

by:Starr Duskk
ID: 24158781
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
 
LVL 13

Expert Comment

by:sm394
ID: 24159408
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
 
LVL 13

Expert Comment

by:sm394
ID: 24159581
you can also compile this c# version in to dll and use that dllinto vb proj
0
 
LVL 2

Author Comment

by:Starr Duskk
ID: 24159789
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
 
LVL 13

Expert Comment

by:sm394
ID: 24159982
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
 
LVL 2

Author Comment

by:Starr Duskk
ID: 24160062
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
 
LVL 2

Author Comment

by:Starr Duskk
ID: 24160192
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
 
LVL 2

Author Comment

by:Starr Duskk
ID: 24160245
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
 
LVL 2

Author Comment

by:Starr Duskk
ID: 24160370
sm394,
This is excellent, I want to thank you so much for providing it for me!
Bobi
 
0
 
LVL 2

Author Comment

by:Starr Duskk
ID: 24160494
Can you provide the missing class file too?
thanks!
 
0
 
LVL 13

Expert Comment

by:sm394
ID: 24162921
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
 
LVL 2

Author Comment

by:Starr Duskk
ID: 24162954
Well, either way, you did a great job and I couldn't have done this without your code.
Thanks a lot!
 
0
 
LVL 13

Expert Comment

by:sm394
ID: 24163020
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
 
LVL 13

Expert Comment

by:sm394
ID: 24163398
@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

Featured Post

How to Use the Help Bell

Need to boost the visibility of your question for solutions? Use the Experts Exchange Help Bell to confirm priority levels and contact subject-matter experts for question attention.  Check out this how-to article for more information.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

ASP.Net to Oracle Connectivity Recently I had to develop an ASP.NET application connecting to an Oracle database.As I am doing it first time ,I had to solve several problems. This article will help to such developers  to develop an ASP.NET client…
It was really hard time for me to get the understanding of Delegates in C#. I went through many websites and articles but I found them very clumsy. After going through those sites, I noted down the points in a easy way so here I am sharing that unde…
We’ve all felt that sense of false security before—locking down external access to a database or component and feeling like we’ve done all we need to do to secure company data. But that feeling is fleeting. Attacks these days can happen in many w…
Please read the paragraph below before following the instructions in the video — there are important caveats in the paragraph that I did not mention in the video. If your PaperPort 12 or PaperPort 14 is failing to start, or crashing, or hanging, …
Suggested Courses
Course of the Month15 days, 20 hours left to enroll

850 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question