Statistics
Visits: 105083
Page Visits: 139167
Active visitors (monthly): 5364
Feed Count: 45
Most visited page: Adding value as a technical analyst
Category : ASP.NET WebForms

Popup Calendar Control

I want a simple Calendar control. The Calendar control should function like a FileUpload control. It should have a textbox and a button. On click on a button, the calendar control should open. On selecting a date in the calendar control, the popup window should close, and the textbox should be filled with the date. I want this Popup Calendar control to be used across multiple pages in the application

We can create a Calendar UserControl. The User control should open another page with a calendar control in a separate Popup window. The HTML markup of the reusable Calendar control (PopupCalendar.ascx) is as follows:


<asp:TextBox ID="txtDate" runat="server"></asp:TextBox>
<asp:Button ID="btnOpen" runat="server" Text=".." Width="20"
OnClientClick="return openWin(this);" />

Note that OnClientClick of the Button control has the javascript to open a new window. The javascript is as follows:

<script type="text/javascript">


    function openWin(btn) {

        var adjustLeft = 35;
        var adjustTop = 15;
        
        var left = btn.offsetLeft + getLeft(btn.parentNode);
        left += window.screenLeft + adjustLeft;
        
        var top = btn.offsetTop + getTop(btn.parentNode);
        top += window.screenTop + adjustTop;

        window.open('calendar.aspx?id=<%= txtDate.ClientID %>', '_blank', 
        'menubar=no, toolbar=no, status=no, resizeable=no, scrollbars=no,' + 
        'location=no, width=250, height=220, left=' + left + ', top=' + top);
        
        return false;
    }

    function getLeft(par) {
        if (par.tagName.toUpperCase()!="BODY") {
            return par.offsetLeft + getLeft(par.parentNode);
        }

        return 0;
    }

    function getTop(par) {
        if (par.tagName.toUpperCase() != "BODY")
            return par.offsetTop + getTop(par.parentNode);

        return 0;
    }

</script>

The javascript looks a bit more complex than the standard window.open because we want to open the window right near the button control. Also, the textbox id is passed as querystring to Calendar.aspx which is the page that will be opened in the Popup window. The markup for the Calendar.aspx page is below:

<form id="form1" runat="server">
    <div>
        <asp:Calendar ID="cal" runat="server" OnDayRender="cal_DayRender"></asp:Calendar>
    </div>
</form>

We are over-riding the Calendar's OnDayRender event. In this event handler, we are replacing the existing control in the Calendar control with our custom Hyperlink control. Our hyperlink control will call a javascript within this page to set the text in the parent window TextBox. The code for the event handler is below:

protected void cal_DayRender(object sender, DayRenderEventArgs e)
{
    e.Cell.Controls.RemoveAt(0);

    HyperLink hl = new HyperLink();
    string click = string.Format("javascript: setDate('{0}');", e.Day.Date.ToShortDateString());
    hl.NavigateUrl = click;
    hl.Text = e.Day.Date.Day.ToString();
    hl.ForeColor = System.Drawing.Color.Black;
    e.Cell.Controls.Add(hl);
}

In the above code, the javascript function - setDate() is called with the SelectedDate. This javascript function will set the text of the TextBox1 from the parent window. It will also close the popup window (itself).

    function setDate(date) {
        window.opener.document.getElementById('<%= Request.QueryString["id"] %>').value = date;
        window.close();
    }

Permalink | No Comments | Leave your comment
 

Difference between ReadOnly and Disabled

What is the difference between ReadOnly="true" and Enabled="false" for a TextBox control?

When a textbox is in ReadOnly mode or is disabled, we cannot get the text of the textbox on page postback. (TextBox1.Text will be empty). However, in the case of ReadOnly mode, the TextBox text is sent as part of Form's postback data. The textbox value can be retrieved using Request.Form["TextBox1"] where TextBox1 is the ClientID of the TextBox. When a textbox is disabled, the TextBox text does not come as part of form postback. So Request.Form["TextBox1"] will be empty.

The above difference is useful in some scenarios. For eg, you have a TextBox with AJAX CalendarExtender. You do not want the user to enter any text in the textbox. So, you can set the TextBox to be ReadOnly. However on postback, you will not get TextBox1.Text set by calendar control. So you can use Request.Form["TextBox1"] to get the selected date. Sample code is shown below:


<asp:TextBox ID="Text1" runat="server" ReadOnly="true" />
<cc:CalendarExtender runat="server"  TargetControlID="Text1">
</cc:CalendarExtender> 


protected void Page_Load(object sender, EventArgs e)
{
    Response.Write("Form: " + Request.Form["Text1"] + "<br />");
    Response.Write("TB: " + Text1.Text + "<br />");
}

Permalink | No Comments | Leave your comment
 

Image with Text for Verification

I want to create an image with text for verification, similar to the ones used in Google, Yahoo in user registration. How can I create this?

The HTML markup for the sample page with image verification will look like something like this:


<form id="form1" runat="server">
<div>
    <asp:Image ID="VerImage" runat="server" ImageUrl="~/ImageViewer.ashx"/>
    <asp:TextBox ID="VerText" runat="server" />
    <asp:CustomValidator id="VerifyVal" runat="server" ValidateEmptyText="true" 
	ControlToValidate="VerText" OnServerValidate="VerifyVal_ServerValidate">*
    </asp:CustomValidator>
    <asp:Button Text="Verify" runat="server" />
</div>
</form>

The image is rendered using a ImageViewer.ashx handler. The textbox text is verified using a CustomValidator. In the server-side, we handle the Page load event and CustomValidator ServerValidate event. In the Page load event we create a verification text and store it in a session variable. In the ServerValidate event, we pick the verification text from the Session variable and validate the text in the textbox. The code is as below:

protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        string verText = "Sample";
        Session["Verify"] = verText;
    }
}

protected void VerifyVal_ServerValidate(object source, ServerValidateEventArgs args)
{
    args.IsValid = false;
    string verText = (string)Session["Verify"];
    if (!String.IsNullOrEmpty(verText))
    {
        if (VerText.Text == verText)
        {
            args.IsValid = true;
        }
    }
}

The image rendering is performed in a handler class - ImageViewer.ashx. The ProcessRequest method gets the verification text from the session variable. This is possible only if the handler class derives from IRequiresSessionState (System.Web.SessionState). IRequiresSessionState is a marker interface. So, no new methods have to be defined.

After getting the verification text, an image object is created from a background image file. Using the graphics object of the image object, we can draw the string. Once the string is drawn, the image object can be streamed into the Response object. The code for the handler is below:


public class ImageViewer : IHttpHandler, IRequiresSessionState
{

    public void ProcessRequest(HttpContext context)
    {    
        Image image = Image.FromFile(context.Server.MapPath("~/red.jpg"));
        Graphics gp = Graphics.FromImage(image);

        string text = "Default";
        if (context.Session!=null && context.Session["Verify"]!=null)
            text = (string)context.Session["Verify"];

        Font font = new Font(new FontFamily("Arial"), image.Height/3);
        Brush brush = Brushes.White;
        PointF point = new PointF(image.Width/4, image.Height/4);
        gp.DrawString(text, font, brush, point);

        image.Save(context.Response.OutputStream, System.Drawing.Imaging.ImageFormat.Gif);
    }

    public bool IsReusable
    {
        get
        {
            return false;
        }
    }
}

Permalink | No Comments | Leave your comment
 

Confirm Backdating

I have a calendar control. If the user wants to backdate (ie, SelectedDate < Today), then I want to display a confirm messagebox asking the user: 'Are you sure you want to backdate?'

Calendar Control has a OnDayRender event that you can handle. In the eventhandler, for all date before today's date, add the javascript: confirm() function to the OnClick attribute as follows:


protected void cal_DayRender(object sender, DayRenderEventArgs e)
{
	if(e.Day.Date < DateTime.Today)
		e.Cell.Attributes.Add("OnClick", "return confirm('Are you sure
					you want to backdate?');");
}

Permalink | 1 Comment | Leave your comment
 
Commented by Rahul at 10-Feb-2010 05:15 AM
Can you provide more clarity on this??

Inserting Image into the database

How do I insert an image into the database?

In the ASPX page, have a asp:FileUpload control and a Submit button. On clicking the submit button, the following code inserts into the table - Image and column - ImageStream, of type varbinary


<asp:FileUpload ID="fup" runat="server" />
<asp:Button ID="btnSubmit" runat="server" Text="Hello" OnClick="btnSubmit_Click" />


protected void btnSubmit_Click(object sender, EventArgs e)
{
    byte [] bytes = fup.FileBytes;

    SqlConnection conn = new SqlConnection("Data Source=localhost; Database=Pubs; Integrated Security=true;");
    conn.Open();
    string sql = "INSERT INTO IMAGE (ImageStream) VALUES (@bytes)";
    SqlCommand comm = new SqlCommand(sql, conn);
    comm.Parameters.AddWithValue("@bytes", bytes);
    comm.ExecuteNonQuery();

}

Permalink | 1 Comment | Leave your comment
 
Commented by Ravi at 10-Oct-2009 06:17 PM
This is very helpful to me

Dynamically creating rows of textboxes

How do I add textboxes to an existing table of textboxes? How do I retrieve the values of the newly added textboxes?

The challenge here is that dynamically added controls are not automatically recreated for you by the ASP.Net framework on page postback. This means if you create textboxes dynamically, then you have to re-create these textboxes on every postback.

In the ASPX page, create asp:Table and asp:HiddenField as below:


<asp:HiddenField ID="hdnCount" Value="1" runat="server" />
<asp:Table ID="tblMain" runat="server">
 <asp:TableHeaderRow>
  <asp:TableHeaderCell>Name</asp:TableHeaderCell>
  <asp:TableHeaderCell>
     <asp:Button ID="btnAdd" runat="server" Text="Add" OnClick="btnAdd_Click"/>
     <asp:Button ID="btnSave" runat="server" Text="Save" OnClick="btnSave_Click" />
  </asp:TableHeaderCell>
 </asp:TableHeaderRow>
 <asp:TableRow>
    <asp:TableCell>
        <asp:TextBox ID="txtName1" runat="server" Width="200"></asp:TextBox>
    </asp:TableCell>
 </asp:TableRow>
</asp:Table>

In the code-behind, the textboxes can be created using code like this in Page_Load()


protected void Page_Load(object sender, EventArgs e)
{
    CreateTextBoxes(); 
}

private void CreateTextBoxes()
{
    int count = int.Parse(hdnCount.Value);

    // Recreate the textboxes on each postback
    for (int i = 2; i <= count; i++)
    {
        TextBox tb = new TextBox();
        tb.ID = "txtName" + i.ToString();
        tb.Width = 200;
        tb.Text = Request.Form["txtName" + i.ToString()];

        TableRow tr = new TableRow();
        TableCell tc = new TableCell();


        tc.Controls.Add(tb);
        tr.Cells.Add(tc);
        tblMain.Rows.Add(tr);
    }
}


The code for adding and saving textbox values is as follows:


protected void btnAdd_Click(object sender, EventArgs e)
{
    int count = int.Parse(hdnCount.Value);
    count++;
    hdnCount.Value = count.ToString();

    TextBox tb = new TextBox();
    tb.ID = "txtName" + count.ToString();
    tb.Width = 200;

    TableRow tr = new TableRow();
    TableCell tc = new TableCell();


    tc.Controls.Add(tb);
    tr.Cells.Add(tc);
    tblMain.Rows.Add(tr);

    
}

protected void btnSave_Click(object sender, EventArgs e)
{
    
    int rowCount = int.Parse(hdnCount.Value);

    for (int rowNumber=1; rowNumber<=rowCount; rowNumber++ )
    {
        TextBox tb = (TextBox)tblMain.Rows[rowNumber].Cells[0].FindControl
		("txtName" + rowNumber.ToString());
        if (tb != null)
            Response.Write(tb.Text + "<br/>");
    }
}


Permalink | No Comments | Leave your comment