[ Download Source Code ]
Building the Control
In this section, we will discuss the CreateChildControls() method, which is used to create the interface of the login control. The building block of the Login control’s interface is an HTML table, which is used to hold all the server controls that make up this composite control. If you have a look at the CreateChildControls() method, we start by adding some HTML tags, representing the table and its rows and columns.
After that, I add the first control, which is the UserName TextBox:
// Configure & Add UserName TextBox
_UserName = new TextBox();
_UserName.ID = "username";
_UserName.Attributes.Add("autocomplete","off");
_UserName.Attributes["onclick"] = disableCLick();
_UserName.Attributes["onload"] = "setFocus()";
_UserName.MaxLength= 64;
_UserName.Width= 100;
_UserName.CssClass ="Txt";
_UserName.EnableViewState = false;
_UserName.TabIndex = 1;
this.Controls.Add(_UserName);
As you can see, the UserName TextBox has been configured and then added to the Controls collection. Next, we add a RequiredFieldValidator programmatically to ensure that the user will enter a value in that text box:
// Configure & Add RequiredFieldValidator for UserName TextBox
_UserNameReq = new RequiredFieldValidator();
_UserNameReq.ID = "usernameReq";
_UserNameReq.ErrorMessage = "*";
_UserNameReq.ControlToValidate ="username";
_UserNameReq.ToolTip = "Username Required";
_UserNameReq.Display = System.Web.UI.WebControls.ValidatorDisplay.Dynamic;
this.Controls.Add(_UserNameReq);
If you continue checking the code, you will notice that the same procedure is used to add the Password TextBox and its RequiredFieldValidator, the Error Label, and the Submit Button.
Now we check the above-created properties to know which additional features are to be displayed in the control.
First, we check the RememberMe property discussed earlier. If its value is true, we add the check box, otherwise we do not.
// Check if rememberme checkbox is on
int flag = 0; // flag used for setting tabindex
if ( RememberMe )
{
_AutoLogin = new CheckBox();
_AutoLogin.ID = "autoLogin";
_AutoLogin.Checked = true;
_AutoLogin.Text = "Remember me";
_AutoLogin.CssClass = "LoginCheck";
_AutoLogin.TabIndex = 3;
this.Controls.Add(new LiteralControl("<tr><td colspan=\"2\" align=\"right\">"));
this.Controls.Add(_AutoLogin);
this.Controls.Add(new LiteralControl("</td><td></td></tr>\r\n"));
flag = 1;
}
Notice the presence of the variable named flag. This flag is used to determine the tab index of the Submit button. Suppose that the RememberMe property has a value of false, which means that the check box will not be added. In this case, the tab index of the Submit button would be 3. Suppose now that the RememberMe property has a value of true, which means that we must add the check box and give it a tab index of 3. In this case, the Submit button would need a tab index of 4. The flag variable is to help calculate the right tab index.
If you continue to check the code, you will notice that we check the value of the CreateAccount property. If its value is true, we configure and add a link to the page that allows the user to create a new account. Later on, we check the value of the ForgotPassword property. If its value is true, we configure and add a link to the page that allows the user to retrieve his password. One thing to mention here is that the URL of both pages can be configured by the page developer.
If you check the configuration section for the UserName and Password Textbox controls, you would notice the use of a private method named disableClick(), which provides the client-side script needed to prevent the user from submitting the web form by pressing the Enter key when the focus is inside either of those text boxes. This way, the form will be submitted only if the user clicks the Submit button.
Another client-side function is SetFocus, which is used to set the focus to the UserName TextBox upon loading of the page. Notice that the SetFocus() function has been added in the OnPreRender() method, which is the best place to add client-side scripts, as stated by Scott Mitchell in his article, "Injecting Client-Side Script from an ASP.NET Server Control."