Monday, March 25, 2013

jQuery Enhanced Custom Date Control(Asp .NET/C#)

Adding jQuery to ASP.NET controls allows you to further enhance your custom controls.  One way to do this is by adding java script to pages and initializing your controls after the page is done loading.  Another way is to add the java script to the control in the PreRender method.

Step 1:  Add jQuery and jQuery UI Javascript and CSS files to your project.

The jQuery files can be found here and the jQuery UI files can be found here,  Or you can just download the sample project using the link at the end of this post.

Step 2:  Adding References to the .js and .css files.

You can add the references to each page you plan to use your controls on, or if you are using mater pages you can add the references there.
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>One More IT Blog</title>
    <link rel="stylesheet" href="css/smoothness/jquery-ui-1.10.1.custom.css" /> 
    <link rel="stylesheet" href="Scripts/chosen/chosen.css" />  
    <script src="Scripts/jquery-1.9.1.js"></script>
    <script src="Scripts/jquery-ui-1.10.1.custom.js"></script>
    <script src="Scripts/chosen/chosen.jquery.js"></script>

Step 3:  Create a class extending the TextBox or the TextBoxReqValidator control created in one of the previous posts.

public class TextBoxReqValidator : TextBoxReqValidator
{

Step 4: OnPreRender

We will register our script in the OnPreRender method.  The script attaches the data picker functionality to our text box control.
        #region Pre Render
        /// <summary>
        /// PreRender
        /// </summary>
        /// <param name="e"></param>
        protected override void OnPreRender(EventArgs e)
        {
            base.OnPreRender(e);
            if (Enabled == true)
            {
                // Check to see if the client script is already registered.
                if (!this.Page.ClientScript.IsStartupScriptRegistered(String.Format("jQuery_{0}", this.ClientID)))
                {
                    String script = "$(document).ready(function(){$('#" +
                        this.ClientID + "').datepicker(); });";
                    script = "<script type=\"text/javascript\">" + script + "</script>";
                    this.Page.ClientScript.RegisterStartupScript(this.Page.GetType(), String.Format("jQuery_{0}", this.ClientID), script, false);
                }
            }
        }
        #endregion

Usage Example:

Markup
<%@ Page Title="" Language="C#" MasterPageFile="~/Site1.Master" AutoEventWireup="true" CodeBehind="DateControlsDemo.aspx.cs" Inherits="CustomControls.DateControlsDemo" %>
<%@ Register Assembly="CustomControls" Namespace="CustomControls.Controls" TagPrefix="cc1" %>
<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
    <cc1:DatePickerJQ runat="server" Id="DatePickerJQ"></cc1:DatePickerJQ>
    <br />
    <asp:Button ID="Submit" runat="server" CausesValidation="true" Text="Submit" />
</asp:Content>

Example:


Complete Source:

 CustomControls_DateTextBox.zip

Demo:

Demo 1

Demo 2 



Monday, March 4, 2013

Custom Multi Select ListBox with built-in Validator(Asp .NET/C#)

In my previous posts I walked thru the steps of adding a required validator and custom properties to a control.  In this post I will show how to do the same to a list box control.

Step 1:  Create a class extending the ListBox control and add private RequiredFieldValidator variable.

    public class ListBoxReq : ListBox
    {
        #region Validator
        /// <summary>
        /// Validator
        /// </summary>
        private RequiredFieldValidator req;
        #endregion

Step 2:  Add properties you will want to set on the validator.

Notice that the Validation Group property overrides the textbox property and also sets the corresponding property on the validator if the validator is not null.  The Required property will be used to enable and disable the validator.  The rest of the properties will be used to set properties on the validator control.

#region Properties
/// <summary>
/// ValidationGroup Property
/// </summary>
public virtual string ValidationGroup
{
    get
    {
        string o = base.ValidationGroup;
        return o;
    }
    set
    {
        String oldValue = ValidationGroup;
        if (value != oldValue)
        {
            if (req != null)
            {
                req.ValidationGroup = value;
            }
            base.ValidationGroup = value;
        }
    }
}

/// <summary>
/// InvalidMessage Property
/// </summary>
[Browsable(true)]
[Description("InvalidMessage"), Category("Custom"), DefaultValue("")]
public virtual String InvalidMessage
{
    get
    {
        object o = ViewState["InvalidMessage"];
        if (o != null)
            return (String)o;
        return string.Empty; // Default value
    }
    set
    {
        String oldValue = InvalidMessage;
        if (value != oldValue)
        {
            if (req != null)
            {
                req.ErrorMessage = value;
            }
            ViewState["InvalidMessage"] = value;
        }
    }
}

/// <summary>
/// Required Property
/// </summary>
[Browsable(true)]
[Description("Required"), Category("Custom"), DefaultValue(false)]
public virtual bool Required
{
    get
    {
        object o = ViewState["Required"];
        if (o != null)
            return (bool)o;
        return false; // Default value
    }
    set
    {
        bool oldValue = Required;
        if (value != oldValue)
        {
            ViewState["Required"] = value;
        }
    }
}

/// <summary>
/// ClientScript Property
/// </summary>
[Browsable(true)]
[Description("ClientScript"), Category("Custom"), DefaultValue(true)]
public virtual bool ClientScript
{
    get
    {
        object o = ViewState["ClientScript"];
        if (o != null)
            return (bool)o;
        return true; // Default value
    }
    set
    {
        bool oldValue = ClientScript;
        if (value != oldValue)
        {
            if (req != null)
            {
                req.EnableClientScript = value;
            }
            ViewState["ClientScript"] = value;
        }
    }
}
#endregion

Step 3:  On Init

We will instantiate the RequiredFieldValidator in the OnInit event, we also set the validator properties.  You can see the full life cycle of the page and controls and the order of the events here.  Since we don't want our code to execute at design time we check if we're in design mode at the top of our method. This code is almost the same as the previous example except we force the SelectionMode property to allow multiple selections.

#region On Init
/// <summary>
/// Init
/// </summary>
/// <param name="e"></param>
protected override void OnInit(EventArgs e)
{
    //if we want this control to render at design time we need this code.
    if (this.DesignMode)
    {
        base.OnInit(e);
        return;
    }
    //default to multi select
    this.SelectionMode = ListSelectionMode.Multiple;
    //instantiate and setup the validator
    req = new RequiredFieldValidator();
    req.Enabled = false;
    req.ControlToValidate = this.ID;
    req.ErrorMessage = this.InvalidMessage;
    req.Text = "Required";
    req.EnableClientScript = ClientScript;
    req.ValidationGroup = this.ValidationGroup;
    req.Display = ValidatorDisplay.Dynamic;
    Controls.Add(req);
}
#endregion

Step 4: Render

If the field is required we will render the textbox  and the validator controls.
#region Render
/// <summary>
/// Render 
/// </summary>
/// <param name="writer">Writer</param>
public override void RenderControl(HtmlTextWriter writer)
{
    //if we want this control to render at design time we need this code.        
    if (this.DesignMode)
    {
        base.RenderControl(writer);
        return;
    }
    //if required property is set to true enable the validator
    if (Required == true)
    {
        base.Render(writer);
        writer.Write("<span style=\"color:red;\">*</span>");
        req.Enabled = true;
        req.RenderControl(writer);
    }
    else
    {
        base.RenderControl(writer);
    }
}
#endregion

Usage Example:

Markup
<%@ Page Title="" Language="C#" MasterPageFile="~/Site1.Master" AutoEventWireup="true" CodeBehind="ListBoxDemo.aspx.cs" Inherits="CustomControls.ListBoxDemo" %>
<%@ Register Assembly="CustomControls" Namespace="CustomControls.Controls" TagPrefix="cc1" %>
<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
    <cc1:ListBoxReq ID="ListBox" runat="server" Width="350px" Required="true">
        <asp:ListItem Text="Option 1" Value="1"></asp:ListItem>
        <asp:ListItem Text="Option 2" Value="2"></asp:ListItem>
        <asp:ListItem Text="Option 3" Value="3"></asp:ListItem>
        <asp:ListItem Text="Option 4" Value="4"></asp:ListItem>
    </cc1:ListBoxReq>
    <br />
    <asp:CheckBox ID="ListBoxReqCheckBox" runat="server" Checked="true" Text="Required"
        AutoPostBack="true" OnCheckedChanged="ListBoxReqCheckBox_CheckedChanged" />
        <asp:button id="Submit" runat="server" causesvalidation="true" text="Submit" />
</asp:Content>

Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace CustomControls
{
    public partial class ListBoxDemo : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {

        }

        protected void ListBoxReqCheckBox_CheckedChanged(object sender, EventArgs e)
        {
            ListBox.Required = ListBoxReqCheckBox.Checked;
        }
    }
}

Examples:

Required Field:

Required Field after validation:



Complete Source:

 CustomControls_ListBox.zip

Demo:

Demo 1

Demo 2