Tuesday, September 28, 2010

How to search a GridView on a key press event

Demo:

I am using asp.net UpdatePanel control to partial page update. As there is no keyup event for the asp.net TextBox control, I add an attribute to the control in the page load, which postbacks the update panel on the keyup event of the TextBox.
this.txtDepartment.Attributes.Add("onkeyup", 
    string.Format("javascript:__doPostBack('{0}','')"this.upnlGridView.ClientID));
 For selecting, I have used DataTable’s Select(...) method.
DataRow[] rows = this.DataTable.Select(string.Format("Department LIKE '%{0}%'"this.txtDepartment.Text));
Then to identify the update panel postback event I have used __EVENTTARGET parameter of the Request’s Form[...] collection. If the __EVENTTARGET is equal to update panel’s ClientID then perform search based on TextBox value.
string target = this.Request.Form["__EVENTTARGET"];
if (!string.IsNullOrEmpty(target) && target.Equals(this.upnlGridView.ClientID))
{
    if (!string.IsNullOrEmpty(this.txtDepartment.Text))
    {
        DataRow[] rows = this.DataTable.Select(
            string.Format("Department LIKE '%{0}%'"this.txtDepartment.Text));
        this.grvItems.DataSource = this.LoadData(rows);
        this.grvItems.DataBind();
    }
    else
    {
        this.grvItems.DataSource = this.DataTable;
        this.grvItems.DataBind();
    }
}
For the demonstration purposes I have constructed a DataTable, but certainly you may get data from the database. To keep the example simple I have not implemented the search and paging. I leave it up to you to add suitable code. And also if it take a while to update you can improve the user experience by adding UpdateProgress where you can place little spinning image.

Example:
<%@ Page Language="C#" %>
<%@ Import Namespace="System.Data" %>
<html>
<head id="Head1" runat="server">
 <script runat="server">
        string[] departments = { "Development""Accounting", 
                                   "Sales""Marketting""Management""Human Resouces" };
        private DataTable DataTable
        {
            get { return (DataTable)Session["DataTable"]; }
            set { Session["DataTable"] = value; }
        }
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            if (!this.IsPostBack)
            {
                DataTable dt;
                if (this.DataTable == null)
                    dt = this.DataTable = this.LoadData();
                else dt = this.DataTable;
                this.grvItems.DataSource = dt;
                this.grvItems.DataBind();
                this.txtDepartment.Attributes.Add("onkeyup",
                    string.Format("javascript:__doPostBack('{0}','')"this.upnlGridView.ClientID));
            }
            else
            {
                string target = this.Request.Form["__EVENTTARGET"];
                if (!string.IsNullOrEmpty(target) && target.Equals(this.upnlGridView.ClientID))
                {
                    if (!string.IsNullOrEmpty(this.txtDepartment.Text))
                    {
                        DataRow[] rows = this.DataTable.Select(
                            string.Format("Department LIKE '%{0}%'"this.txtDepartment.Text));
                        this.grvItems.DataSource = this.LoadData(rows);
                        this.grvItems.DataBind();
                    }
                    else
                    {
                        this.grvItems.DataSource = this.DataTable;
                        this.grvItems.DataBind();
                    }
                }
            }
        }
        protected void PageIndexChanging(object sender, GridViewPageEventArgs e)
        {
        }
        protected void Sorting(object sender, GridViewSortEventArgs e)
        {
        }
        private DataTable LoadData()
        {
            return this.LoadData(null);
        }
        private DataTable LoadData(DataRow[] rows)
        {
            DataTable dt = this.GetTable();
            if (rows == null)
            {
                ///
                /// To demonstrate I have loaded data table in the code
                /// You may load this data from database.
                ///
                Random r = new Random();
                for (int i = 0; i < 300; i++)
                    dt.Rows.Add(
                        string.Format("E{0:000}", i),
                        departments[r.Next(0, 5)],
                        "Employee" + i,
                        string.Format("07967781{0:000}", i),
                        string.Format("employee{0:000}@company.com", i));
            }
            else
                foreach (DataRow r in rows) dt.Rows.Add(r[0], r[1], r[2], r[3], r[4]);
            return dt;
        }
        private DataTable GetTable()
        {
            DataTable dt = new DataTable();
            dt.Columns.Add("EmpID"String.Empty.GetType());
            dt.Columns.Add("Department"String.Empty.GetType());
            dt.Columns.Add("Name"String.Empty.GetType());
            dt.Columns.Add("Phone"String.Empty.GetType());
            dt.Columns.Add("Email"String.Empty.GetType());
            return dt;
        }         
 </script>
</head>
<body>    
 <form id="form1" runat="server">
        <asp:ScriptManager runat="server" ID="PageScriptManager" />
        Search Department: 
        <asp:TextBox 
            runat="server" 
            ID="txtDepartment"                    
            AutoPostBack="true" />
        <asp:UpdatePanel runat="server" ID="upnlGridView">
            <ContentTemplate>
                <hr />
                <asp:GridView 
                    runat="server" 
                    ID="grvItems" 
                    AllowPaging="true" 
                    AllowSorting="true" 
                    OnSorting="Sorting" 
                    OnPageIndexChanging="PageIndexChanging" 
                    CellPadding="5">                
                </asp:GridView>
            </ContentTemplate>
        </asp:UpdatePanel>
 </form>
</body>
</html>

'Please send me code'

In a break, I had a look in to Asp.net Web Forms forum to see if there is anything that I can help. Indeed yes, there is a post surely I will be a help to the poster by the meaning of its title. Without any hesitant I clicked on the link. I was surprised by post description as it said...

I want to do such and such... and send me the code for that.

Although I had a thought that would be a help to the poster, my psychology made my so reluctant to say a word. I was so embarrassed to send someone a piece of code. I thought are we actually sending code? No we guiding them through the correct path by providing the best possible answer, I said to myself. I don’t know, but description of this particular post made me think twice about the psychology of the poster? Is he trying to get something done by others or is he desperately needs a help?  Is he abusing the kindness and patience of other asp.net community members? I lost my confidence about the fact that poster genuinely need a help. At least if poster is smart enough, he or she may have used the words carefully and trick community members to get their work done. But not too smart, I have seen people post ‘requirement definitions’ which need couple of development team meeting to discuss, with the title with ‘need an idea’. I closed the browser and leaned back to work.

Monday, September 27, 2010

How to dynamically add a row of controls based on TextBox value : Asp.net - Part 3

Demo:

<%@ Page Language="C#" %>
<html>
<head id="Head1" runat="server">
    <script runat="server">
        public int NumberOfRows
        {
            get { return int.Parse(this.Request.Form[this.txtRows.UniqueID] ?? "1"); }
            set { this.txtRows.Text = value.ToString(); }
        }
        public int NumberOfColums
        {
            get { return int.Parse(this.Request.Form[this.txtColmns.UniqueID] ?? "4"); }
            set { this.txtColmns.Text = value.ToString(); }
        }
        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);
            Table table = new Table();
            for (int i = 0; i < this.NumberOfRows; i++)
            {
                TableRow tr = new TableRow();
                for (int j = 0; j < this.NumberOfColums; j++)
                {
                    TableCell td = new TableCell();
                    td.Controls.Add(new TextBox() { ID = "Cell" + i + j });
                    tr.Controls.Add(td);
                }
                table.Rows.Add(tr);
            }
            this.phCells.Controls.Add(table);
        }                   
    </script>
</head>
<body>
 <form id="form1" runat="server">
        Rows: <asp:TextBox runat="server" ID="txtRows" Text="1" />
        - Coloums: <asp:TextBox runat="server" ID="txtColmns" Text="4" />
        <hr />
        <asp:PlaceHolder runat="server" ID="phCells"></asp:PlaceHolder>
        <asp:Button runat="server" ID="btnCreate" Text="Create" />  
 </form>
</body>
</html>

How to dynamically add a row of controls based on Drop Down List Value : Asp.net - Part 2

Demo:

<%@ Page Language="C#" %>
<html>
<head id="Head1" runat="server">
    <script runat="server">
        public int NumberOfRows
        {
            get { return int.Parse(this.Request.Form[this.ddlRows.UniqueID] ?? "1"); }
            set { this.ddlRows.Text = value.ToString(); }
        }
        public int NumberOfColums
        {
            get { return int.Parse(this.Request.Form[this.txtColmns.UniqueID] ?? "4"); }
            set { this.txtColmns.Text = value.ToString(); }
        }
        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);
            Table table = new Table();
            for (int i = 0; i < this.NumberOfRows; i++)
            {
                TableRow tr = new TableRow();
                for (int j = 0; j < this.NumberOfColums; j++)
                {
                    TableCell td = new TableCell();
                    td.Controls.Add(new TextBox() { ID = "Cell" + i + j });
                    tr.Controls.Add(td);
                }
                table.Rows.Add(tr);
            }
            this.phCells.Controls.Add(table);
        }               
    </script>
</head>
<body>
 <form id="form1" runat="server">
        Rows: 
        <asp:DropDownList runat="server" ID="ddlRows">
            <asp:ListItem Selected="True">5</asp:ListItem>
            <asp:ListItem>10</asp:ListItem>
            <asp:ListItem>15</asp:ListItem>
            <asp:ListItem>20</asp:ListItem>
            <asp:ListItem>25</asp:ListItem>
        </asp:DropDownList>
        - Coloums: <asp:TextBox runat="server" ID="txtColmns" Text="4" />
        <hr />
        <asp:PlaceHolder runat="server" ID="phCells"></asp:PlaceHolder>
        <asp:Button runat="server" ID="btnCreate" Text="Create" /> 
 </form>
</body>
</html>

How to show the selected image file without saving file in the disk before upload


Demo:
 
I was thinking a way to show images before actually uploading them to server. I would say to preview images using javascript. Obviously asp.net file input control does not like post-backs when it has a selected file. This idea is to preview the selected image by saving the file as byte[] array in the session and assigning the file to a src (ImageUrl) of a image element(asp.net Image) in a subsequent request. I have used jQuery to simplify the battle with asp.net rendered domain model. First hurdle, simple jQuery ajax didnt posted my selected image file. So I needed to find a way to post my selected file, then found a nice little plugin so called jQuery AjaxForm. This plugin nicely did the trick. I manage to change the form action for a bit and post the form to GenericHanlder. As soon I found the posted file, I get the converted file in to a System.Drawing.Image and saved it in the session. Finally carefully reverted the asp.net from action to it's original value.
HttpPostedFile file = context.Request.Files[0];
image = Bitmap.FromStream(file.InputStream);
context.Session["image"] = image;
If we request GenericHanlder again, it can retreive the image from session and serve as an image. So what I did was in the success event of jQuery AjaxForm post, assign the GenericHandler.ashx to src of the preview image. As a result, there will be a second subsequent request just after the first form post to the Generic Hander. Now I distinguish the two requests and for the second request I serve the image from the session after converting image object in to a byte[] array using a momery stream.
MemoryStream stream = new MemoryStream();
image.Save(stream, format);
context.Response.BinaryWrite(stream.ToArray());
Download jQuery Ajax Form
Download jQuery
Memeory Consumption with heavy load:
Saving the image in the session is only between two consecutive requests. First request creates the image and save it in the session. Then the second request consumes the image, remove the image from session and dispose it. So memory use of the server is instantaneous. Producer consumer fashion.

Markup:
<%@ Page Language="C#" %>
<html>
<head id="Head2" runat="server">
    <script src="Scripts/jquery-1.4.1.min.js" type="text/javascript"></script>
    <script src="Scripts/jquery-form.js" type="text/javascript"></script>
    <script language="javascript" type="text/javascript">
        function ShowFile() {
            var formId = '<%= this.Form.ClientID %>';
            var imageId = '<%=this.imageView.ClientID %>';
            var fileUploadId = '<%=fuFileUpload.UniqueID %>';
            var r = Math.floor(Math.random() * 999999);
            var action = $('#' + formId).attr('action');
            $('#' + formId).attr('action''GenericHandler.ashx?f=' + fileUploadId);
            $('#' + formId).ajaxForm(function () {
                $('#' + imageId).attr('src''GenericHandler.ashx?s=' + fileUploadId + '&r=' + r);
                $('#' + imageId).show();
                $('#' + formId).attr('action', action);
            });
            $('#' + formId).submit();
        }
    </script>
</head>
<body>
    <form id="form2" runat="server">
    <asp:FileUpload runat="server" ID="fuFileUpload" onchange="javascript:ShowFile();" />
    <asp:Button ID="Button1" runat="server" Text="Save" />
    <hr />
    <asp:Image ID="imageView" runat="server" alt="Thumbnail" Style="displaynone" />
    </form>
</body>
</html>

Generic Handler:
public class GenericHandler : IHttpHandlerIRequiresSessionState
{
    public void ProcessRequest(HttpContext context)
    {
        string f = context.Request.QueryString.Get("f");
        string s = context.Request.QueryString.Get("s");
        if (!string.IsNullOrEmpty(f))
        {
            HttpPostedFile file = context.Request.Files[f];
            if (file == null)
                HttpContext.Current.ApplicationInstance.CompleteRequest();
            else
            {
                List<string> keys = new List<string>();
                foreach (string key in context.Session.Keys) if (key.StartsWith(f)) keys.Add(key);
                foreach (string key in keys) context.Session.Remove(key);
                System.Drawing.Image image = Bitmap.FromStream(file.InputStream);
                context.Session[f + "image"] = image;
                context.Session[f + "contextType"] = context.Request.Files[0].ContentType;
                context.Response.Flush();
                HttpContext.Current.ApplicationInstance.CompleteRequest();
            }
        }
        else if (!string.IsNullOrEmpty(s))
        {
            string ck = s + "contextType";
            string ik = s + "image";
            if (context.Session[ck] == null || context.Session[ik] == null)
            {
                HttpContext.Current.ApplicationInstance.CompleteRequest();
                if (context.Session[ck] != null) context.Session.Remove(ck);
                if (context.Session[ik] != null) context.Session.Remove(ik);
            }
            else
            {
                using (System.Drawing.Image image = (System.Drawing.Image)context.Session[ik])
                {
                    context.Response.Clear();
                    context.Response.ClearHeaders();
                    string type = context.Session[ck].ToString().ToLower();
                    System.Drawing.Imaging.ImageFormat format = 
                                                            System.Drawing.Imaging.ImageFormat.Gif;
                    bool isValid = true;
                    if (type.Contains("bmp")) format = System.Drawing.Imaging.ImageFormat.Bmp;
                    else if (type.Contains("jpg") || type.Contains("jpeg")) format = 
                                                            System.Drawing.Imaging.ImageFormat.Jpeg;
                    else if (type.Contains("png")) format = System.Drawing.Imaging.ImageFormat.Png;
                    else if (type.Contains("gif")) format = System.Drawing.Imaging.ImageFormat.Gif;
                    else if (type.Contains("wmf")) format = System.Drawing.Imaging.ImageFormat.Wmf;
                    else if (type.Contains("tiff") || type.Contains("tif")) format = 
                                                            System.Drawing.Imaging.ImageFormat.Tiff;
                    else if (type.Contains("exif")) format = System.Drawing.Imaging.ImageFormat.Exif;
                    else isValid = false;
                    if (isValid)
                    {
                        using (MemoryStream stream = new MemoryStream())
                        {
                            image.Save(stream, format);
                            context.Response.BinaryWrite(stream.ToArray());
                            context.Response.ContentType = type;
                        }
                    }
                    context.Session.Remove(ck);
                    context.Session.Remove(ik);
                    HttpContext.Current.ApplicationInstance.CompleteRequest();
                }
            }
        }
    }
    public bool IsReusable
    {
        get
        {
            return false;
        }
    }
}

References:
Many thanks to following people for their work, without them I would not have achive this.
  1. jQuery Form:
  2. Converting image to a byte stream:
  3. Generating random number usign java script:

How to issue a id value to a web page without having duplicates

Stored Procedure:
CREATE PROCEDURE GetNewId
AS
BEGIN
    DECLARE @NewId INT;
    SET @NewId = -1;
    SELECT TOP 1 @NewId = Id FROM dbo.DataTable WHERE IsSaved = 0 ORDER BY ID ASC;
    IF( @NewId = -1)
    BEGIN
        SELECT @NewId = MAX(Id) + 1 FROM dbo.DataTable;
        INSERT INTO dbo.DataTable(Id, IsSaved) VALUES (@NewId, 0);
    END
    SELECT @NewId
END
Code:
protected override void OnLoad(EventArgs e)
{
    base.OnLoad(e);
    ///
    /// Get
    ///        
    if (!this.IsPostBack)
    {
        using (SqlConnection con = new SqlConnection("ConnectionString"))
        {
            con.Open();
            SqlCommand cmd = new SqlCommand("GetNewId", con);
            cmd.CommandType = CommandType.StoredProcedure;
            string newNumber = cmd.ExecuteScalar().ToString();
            this.txtNumber.Text = newNumber;
            con.Close();
        }
    }
}
protected void Save(object sender, EventArgs e)
{
    ///
    /// Save, actually by that time we have a record for newNumber
    /// So again in the save method we have to update the relevent record
    ///
    using (SqlConnection con = new SqlConnection("ConnectionString"))
    {
        string sql = @"
    UPDATE dbo.DataTable
    SET 
     @IsSaved = 1,
        ...
        ...
    WHERE Id = @Id;
";
        con.Open();
        SqlCommand cmd = new SqlCommand(sql, con);
        cmd.Parameters.Add(new SqlParameter("@Id"int.Parse(this.txtNumber.Text)));
        ///
        /// add other parameters
        /// 
        cmd.ExecuteNonQuery();
        con.Close();
    }
}

Sunday, September 26, 2010

How to create a good quality thumbnail from posted image file

public void SaveImage(object sender, EventArgs e) 
{ 
    string imageName = this.fupNewImage.FileName; 
    System.Drawing.Image postedImage = System.Drawing.Image.FromStream(this.fupNewImage.PostedFile.InputStream); 
    if (postedImage.Width == 750 && postedImage.Height == 482) 
    { 
        System.Drawing.Image thumbnail = this.CreateThumbnail(this.fupNewImage.PostedFile.InputStream); 
        thumbnail.Save("thumbnailPath"); 
    } 
}
public System.Drawing.Image CreateThumbnail(Stream source)
{
    System.Drawing.Image imgToResize = System.Drawing.Image.FromStream(source);
    Size size = new Size(156, 100);
    int sourceWidth = imgToResize.Width;
    int sourceHeight = imgToResize.Height;
    float nPercent = 0;
    float nPercentW = 0;
    float nPercentH = 0;
    nPercentW = ((float)size.Width / (float)sourceWidth);
    nPercentH = ((float)size.Height / (float)sourceHeight);
    if (nPercentH < nPercentW)
        nPercent = nPercentH;
    else
        nPercent = nPercentW;
    int destWidth = (int)(sourceWidth * nPercent);
    int destHeight = (int)(sourceHeight * nPercent);
    Bitmap b = new Bitmap(destWidth, destHeight);
    Graphics g = Graphics.FromImage((System.Drawing.Image)b);
    g.InterpolationMode = InterpolationMode.High;
    g.SmoothingMode = SmoothingMode.HighQuality;
    g.Clear(Color.Transparent);
    g.DrawImage(imgToResize, 0, 0, destWidth, destHeight);
    g.Dispose();
    return (System.Drawing.Image)b;
}

How to save only changes (stop posting back if there are no any changes)

Demo:
For this we can utlize a nice little jQuery plugin called DirtyForm
Download dirty form:
Download jQuery:
Example:
<%@ Page Language="C#"  %>
<html>
<head id="Head1" runat="server">
 <script src="Scripts/jquery-1.4.1.min.js" type="text/javascript"></script>
 <script src="Scripts/jquery-dirtyform.js" type="text/javascript"></script>
 <script language="javascript" type="text/javascript">
     var isDirty = false;
     $(document).ready(function () {
         $('#<%= this.Form.ClientID %>')
     .dirty_form()
     .dirty(function (event, data) {
         isDirty = true;
     });
     });
     function Save() {
         if (!isDirty) {
             alert("You didn't change anything");
             return false;
         }
         return true;
     }
 </script>
 <script runat="server">
  protected void Save(object sender, EventArgs e)
  {
       this.lblUpdateTime.Text = string.Format("Last Updated On: {0}", DateTime.Now.ToString("hh:mm:ss"));
  }
 </script>
</head>
  <body>    
    <form id="form1" runat="server">
        <asp:TextBox runat="server" ID="txtName"></asp:TextBox><br />
        <asp:TextBox runat="server" ID="txtAddress"></asp:TextBox><br />
        <asp:TextBox runat="server" ID="txtPostcode"></asp:TextBox><br />
        <asp:TextBox runat="server" ID="txtEmail"></asp:TextBox><br />
        <asp:Button 
            runat="server" 
            ID="btnSave" 
            OnClick="Save" 
            OnClientClick="return Save();" 
            Text="Save" /><br />
        <asp:Label runat="server" ID="lblUpdateTime" />        
     </form>
   </body>
</html>

Saturday, September 25, 2010

How to calculate days/hours difference

  1. How to calculate Hours
  2. How to calculate Days

How to calculate day difference

Demo:
Example:
Start Date               Duration              End Date
5/8/2010 9:00        4 Hrs                    5/8/2010 13:00
5/14/2010 13:00    4 Hrs                    5/14/2010 17:00
5/13/2010 9:00      8 Hrs                    5/13/2010 17:00
5/11/2010 13:00    8 Hrs                    5/12/2010 12:00
5/5/2010 9:00        12 Hrs                  5/6/2010 12:00
5/28/2010 13:00    12 Hrs                  5/29/2010 16:00
5/28/2010 13:00    16 Hrs                  5/30/2010 11:00
5/28/2010 13:00    20 Hrs                  5/30/2010 16:00
5/28/2010 9:00      20 Hrs                  5/30/2010 12:00
Discussion:
Code:
<%@ Page Language="C#" %>
<html>
<head id="Head1" runat="server">
    <script runat="server">
        private int startHour = 7;
        private int endHour = 19;
        private int workDaysPerWk = 5;
        protected override void OnLoad(EventArgs e)
        {
            this.lblEndTime.ForeColor = System.Drawing.Color.Green;
            this.lblEndTime.Text = string.Empty;
            try
            {
                this.startHour = int.Parse(this.txtStartHour.Text);
                this.endHour = int.Parse(this.txtEndHour.Text);
            }
            catch
            {
                this.lblEndTime.ForeColor = System.Drawing.Color.Red;
                this.lblEndTime.Text = "Error";
            }
            base.OnLoad(e);
            if (!this.IsPostBack)
            {
                DateTime now = DateTime.Now;
                if (now.DayOfWeek == DayOfWeek.Saturday) now = now.AddDays(2);
                if (now.DayOfWeek == DayOfWeek.Sunday) now = now.AddDays(1);
                this.calHoliday.SelectedDate = now;
                this.FindTimeIntervals();
            }
 
        }
        protected void FindTimeIntervals(object sender, EventArgs e)
        {
            this.FindTimeIntervals();
        }
        private void FindTimeIntervals()
        {
            DateTime date = this.calHoliday.SelectedDate;
            DateTime start = new DateTime(date.Year, date.Month, date.Day, startHour, 0, 0);
            this.ddlLeaveStart.Items.Clear();
            for (int i = 0; i < (endHour - startHour) * 2; i++)
                this.ddlLeaveStart.Items.Add(
                    new ListItem(start.AddMinutes(i * 30).ToString("yyyy MM dd - hh:mm tt"), 
                        start.AddMinutes(i * 30).ToString()));
        }
        protected void DayRender(object sender, DayRenderEventArgs e)
        {
            if (e.Day.IsWeekend)
                e.Cell.Enabled = false;
        }
        protected void FindStartTime(object sender, EventArgs e)
        {
            try
            {
                int workHours = endHour - startHour;
                DateTime end = DateTime.Parse(this.ddlLeaveStart.SelectedValue);
                int duration = int.Parse(this.txtDuration.Text);
                if (duration > workHours)
                {
                    int days = (duration - duration % workHours) / workHours;
                    duration = duration % workHours;
                    if (days > workDaysPerWk)
                    {
                        int weeks = (days - days % workDaysPerWk) / workDaysPerWk;
                        days = days % workDaysPerWk;
                        end = end.AddDays(weeks * 7);
                    }
                    end = end.AddDays(days);
                }
                end = end.AddHours(duration);
                if (end.Hour >= endHour || end.Hour < startHour) end = end.AddHours((24 - endHour) + startHour);
                if (end.DayOfWeek == DayOfWeek.Saturday || end.DayOfWeek == DayOfWeek.Sunday) end = end.AddDays(2);
                this.lblEndTime.Text = end.ToString("yyyy MM dd - hh:mm tt");
            }
            catch
            {
                this.lblEndTime.ForeColor = System.Drawing.Color.Red;
                this.lblEndTime.Text = "Invalid Input";
            }
        }
 
    </script>
</head>
<body>
    <form id="form1" runat="server">
        Start Hour: <asp:TextBox runat="server" ID="txtStartHour" Text="7" /> 
        End Hour: <asp:TextBox runat="server" ID="txtEndHour" Text="19" /> 
        <asp:Button runat="server" ID="btnSet" Text="Set" />
        <hr />
        Date: <asp:Calendar runat="server" ID="calHoliday" OnDayRender="DayRender" 
                                                OnSelectionChanged="FindTimeIntervals" />
        Time: <asp:DropDownList runat="server" ID="ddlLeaveStart"  />
        Duration: <asp:TextBox runat="server" ID="txtDuration" Text="12" />
        <asp:Button runat="server" ID="Find" OnClick="FindStartTime" Text="Find" />
        You should come back on: <asp:Label runat="server" ID="lblEndTime" />
    </form>
</body>
</html>

Azure Storage Account Types

Defferent Types of Blobs Block blobs store text and binary data. Block blobs are made up of blocks of data that can be managed individually...