RadTextBox for ASP.NET AJAX integration with PasswordStrength extender from AJAX Control Toolkit

Thread is closed for posting
2 posts, 1 answers
  1. Answer
    Telerik Admin
    Telerik Admin avatar
    1679 posts
    Member since:
    Oct 2004

    Posted 14 Dec 2010 Link to this post

    Requirements

    RadControls version

    2010 Q3
    .NET version

    .NET 3.5 or above
    Visual Studio version

    2008, 2010
    programming language C#
    browser support

    all browsers supported by RadControls


    PROJECT DESCRIPTION
    RadTextBox for ASP.NET AJAX can be used as a password field in login forms. When presenting your users with the option of specifying a password, you may often need to indicate the strength of the entered password back to the user. The ASP.NET AJAX Control Toolkit provides a PasswordStrength extender that can be used with TextBox controls to indicate the strength of the user specified password based on predefined criteria. This project demonstrates how the PasswordStrength extender from the toolkit can be extended to support RadTextBox.

    The main reason PasswordStrength cannot be used with RadTextBox off-the-shelf is that the extender specifies controls of type TextBox as targets only. This means that you need to subclass the extender to specify the TargetControlType attribute with RadTextBox's type:

    [TargetControlType(typeof(RadTextBox))]
    public class RadTextBoxPasswordStrength : PasswordStrength
    {
         
    }

    Now the subclassed RadTextBoxPasswordStrength extender can be attached to RadTextBox instances. This is not enough, though. To check the password strength, the extender will try to attach to an input element with the specified target control's ID on the client. However, RadTextBox renders its hidden validation input with its own ClientID, not the visible input the user types in. The extender needs the visible input, not the hidden field. To work around, we need to overwrite the client-side PasswordStrengthExtenderBehavior.get_element() propety. The object is the client-side behavior component associated with the PasswordStrength extender and get_element() is the property that returns the HTML DOM element the extender is attached to (for more information on how extender controls work, refer to the MSDN Creating an Extender Control topic). We need to modify the property to return the visible RadTextBox input, not the hidden validation field:

    Sys.Extended.UI.PasswordStrengthExtenderBehavior.prototype.get_element = function ()
    {
        var e = Sys.Extended.UI.PasswordStrengthExtenderBehavior.callBaseMethod(this, 'get_element');
        return e.className === 'rdfd_' ? document.getElementById(e.id + '_text') : e;
    }

    The above code checked if the input that is to be returned contains a CSS class that is attached only to the validation field of a RadTextBox control. If this is the case, we need to find the visible text box that has the same ID as the validation + "_text".

    To integrate the above script modification to our subclassed extender control, we can override the control's OnPreRender method to register the above javascript as a startup script:

    [TargetControlType(typeof(RadTextBox))]
    public class RadTextBoxPasswordStrength : PasswordStrength
    {
        protected override void OnPreRender(EventArgs e)
        {
            base.OnPreRender(e);
     
            ScriptManager.RegisterStartupScript(Page, typeof(Page),
                "RadTextBoxPasswordStrength_getElementFix",
                GetClientObjectFixScript(),
                true);
        }
     
        private string GetClientObjectFixScript()
        {
            return @"Sys.Extended.UI.PasswordStrengthExtenderBehavior.prototype.get_element = function ()
                {
                    var e = Sys.Extended.UI.PasswordStrengthExtenderBehavior.callBaseMethod(this, 'get_element');
                    return e.className === 'rdfd_' ? document.getElementById(e.id + '_text') : e;
                };";
        }
    }

    And that's the complete subclassed extender control. It can extend RadTextBox in addition to the standard TextBox control. Check out the project to see it working.
  2. Veli
    Admin
    Veli avatar
    2002 posts

    Posted 27 Jan 2011 Link to this post

    A small fix. In IE, the custom RadTextBoxPasswordStrength extender is throwing a JS error in the dispose phase of the client page life cycle. This is because the original PasswordStrength extender is trying to clear the event handlers of the extender's target HTML element. In our case, this is the visible RadTextBox input element, the same we return in the modified get_element() client property. At the same time, however, RadTextBox has already cleared any attached event handlers from this textbox, so the extender tries to clear non-existent event handlers. This is causing a JS error in Internet Explorer.

    To work around, we need to overwrite the dispose() method of the PasswordStrength extender and wrap the original code in try-catch block. Here is the modified definition of the RadTextBoxPasswordStrength extender:

    namespace Custom
    {
        [TargetControlType(typeof(RadTextBox))]
        public class RadTextBoxPasswordStrength : PasswordStrength
        {
            protected override void OnPreRender(EventArgs e)
            {
                base.OnPreRender(e);
     
                ScriptManager.RegisterStartupScript(Page, typeof(Page),
                    "RadTextBoxPasswordStrength_getElementFix",
                    GetClientObjectFixScript(),
                    true);
            }
     
            private string GetClientObjectFixScript()
            {
                var disposingScript = @"
                    var PSEB = Sys.Extended.UI.PasswordStrengthExtenderBehavior;
                    PSEB.prototype._dispose = PSEB.prototype.dispose;
                    PSEB.prototype.dispose = function ()
                    {
                        try { this._dispose.apply(this, arguments); } catch (e) { };
                    }
                    ";
     
                var getElementScript = @"Sys.Extended.UI.PasswordStrengthExtenderBehavior.prototype.get_element = function ()
                    {
                        var e = Sys.Extended.UI.PasswordStrengthExtenderBehavior.callBaseMethod(this, 'get_element');
                        return e.className === 'rdfd_' && !this._isDisposing ? document.getElementById(e.id + '_text') : e;
                    };";
     
     
                return disposingScript + "\r\n" + getElementScript;
            }
        }
    }

    Substituting this class definition in the above attached project fixes the error in IE.

    Veli
    the Telerik team
    Browse the vast support resources we have to jump start your development with RadControls for ASP.NET AJAX. See how to integrate our AJAX controls seamlessly in SharePoint 2007/2010 visiting our common SharePoint portal.
Back to Top