ASP.Net Elastic TextBox with jQuery

Posted: 10/08/2010

I just wanted to share a simple TextBox I created (that may need some brushing, see XML comments). The idea is that when the TextBox gets the focus, it will expand to a specified height and width and then when it loses focus it will contract back to it's more compact size. This is an ASP.Net WebForms server control that inherits from TextBox. Enjoy!

Imports Microsoft.VisualBasic
Imports System.Text
Imports System.Web.UI.WebControls
Imports System.Web.UI
Imports System.ComponentModel

''' <summary>
''' A text box that will expand to a given height/width when it has the focus and then retract when it loses focus.
''' </summary>
''' <remarks>
''' A few notes, first, the string built in OnInit can be changed to a StringBuilder for better performance.  Also
''' current the code is only setable from the markup because RegisterClientScriptBlock doesn't allow for re-registration
''' of the JavaScript, so when the heights/widths are updated, it's disregarded.  Until I figure out how to fix this I've
''' removed the ViewState.  Personally, I like it this way because I almost never change the properties of the TextBox from
''' the code behind, and, it will continue to keep the Text property that is posted back, which is all that I want for my
''' purposes.
''' </remarks>
<ToolboxData("<{0}:ElasticTextBox ID='ElasticTextBoxID' runat=""server""> </{0}:ElasticTextBox>"), _
Description("A TextBox that will enlarge when the TextBox gets focus, and shrink once it loses focus on the blur event.")> _
Public Class ElasticTextBox
    Inherits System.Web.UI.WebControls.TextBox
    ''' <summary>
    ''' Sets up the jQuery javascript and registers it with the page.
    ''' </summary>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Protected Overrides Sub OnInit(ByVal e As System.EventArgs)
        MyBase.OnInit(e)
        Me.EnableViewState = False
        Me.TextMode = TextBoxMode.MultiLine
        Dim script As String = <string>
                                $(function() {
                                    $("#$CLIENTID$").focus(function(){
                                        $(this).animate({"height": "$STRETCHHEIGHT$px",}, "fast" );
                                        $(this).animate({"width": "$STRETCHWIDTH$px",}, "fast" );
                                        return false;
                                    });
                                    $("#$CLIENTID$").blur(function() {
                                        $("#$CLIENTID$").animate({"height": "$HEIGHT$px",}, "fast" );
                                        $("#$CLIENTID$").animate({"width": "$WIDTH$px",}, "fast" );
                                        return false;
                                    });
                                });
                               </string>
        ' Set a default height & width
        If Me.Height.IsEmpty = True Then
            Me.Height = 15
        End If
        If Me.Width.IsEmpty = True Then
            Me.Width = 150
        End If
        Me.Style.Add("height", Me.Height.Value & "px")
        If Me.Width.IsEmpty = False Then
            Me.Style.Add("width", Me.Width.Value & "px")
        End If
        script = script.Replace("$CLIENTID$", Me.ClientID)
        script = script.Replace("$HEIGHT$", Me.Height.Value)
        script = script.Replace("$STRETCHHEIGHT$", Me.StretchHeight.Value)
        script = script.Replace("$WIDTH$", Me.Width.Value)
        script = script.Replace("$STRETCHWIDTH$", Me.StretchWidth.Value)
        ' Remove spaces, but replace the return line back to normal, I really need a script to handle
        ' javascript minimizing
        script = script.Replace(" ", "").Replace("returnfalse", "return false")
        If Me.UseAjaxScriptManager = True Then
            ScriptManager.RegisterClientScriptBlock(Me.Page, Me.Page.GetType, Me.ClientID, script, True)
        Else
            Me.Page.ClientScript.RegisterClientScriptBlock(Me.Page.GetType, Me.ClientID, script, True)
        End If
    End Sub
    Private _stretchHeight As New System.Web.UI.WebControls.Unit(85)
    ''' <summary>
    ''' The height that the control should stretch to when it receives the focus.  The default value is 85.
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Property StretchHeight() As System.Web.UI.WebControls.Unit
        Get
            Return _stretchHeight
        End Get
        Set(ByVal value As System.Web.UI.WebControls.Unit)
            _stretchHeight = value
        End Set
    End Property
    Private _stretchWidth As New System.Web.UI.WebControls.Unit(150)
    ''' <summary>
    ''' The width that the control should stretch to when it receives the focus.  The default value is 150
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Property StretchWidth() As System.Web.UI.WebControls.Unit
        Get
            Return _stretchWidth
        End Get
        Set(ByVal value As System.Web.UI.WebControls.Unit)
            _stretchWidth = value
        End Set
    End Property
    Private _useAjaxScriptManager As Boolean = False
    ''' <summary>
    ''' If true, will use the ScriptManager instead of the Page.ClientScript.
    ''' </summary>
    ''' <value>The default value is False</value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Property UseAjaxScriptManager() As Boolean
        Get
            Return _useAjaxScriptManager
        End Get
        Set(ByVal value As Boolean)
            _useAjaxScriptManager = value
        End Set
    End Property
End Class