Tuesday, October 27, 2009

AJAX Controls

INDEX

1. UpdatePanel Control

2. UpdateProgress

3. Timer controls

4. Accordion

5. AnimationExtender

6. AutoComplete

7. CalendarExtender

8. CascadingDropDown List

9. CollapsiblePanelExtender

10. ColorPickerExtender

11. ComboBox

12. ConfirmButtonExtender



Sample ASP.NET AJAX Application

Introduction

This tutorial creates a basic sample application that uses features of Microsoft ASP.NET AJAX. You can read more about what ASP.NET AJAX is, what technical issues it is designed to solve, and what its important components are in the following introductory ASP.NET AJAX documents:
In this tutorial you will build an application that displays pages of employee data from the AdventureWorks sample database. The application uses the UpdatePanel control to refresh only the part of the page that has changed, without the page flash that occurs with a postback. This is referred to as a partial-page update. The sample application also uses the UpdateProgress control to display a status message while the partial-page update is processing.
You can see the code in action in this tutorial by clicking the Run It button. To implement the procedures in your own development environment you need:
* Microsoft Visual Studio 2005 or Microsoft Visual Web Developer Express Edition.
* The latest release of Microsoft ASP.NET AJAX installed and configured. For more information, see Installing ASP.NET AJAX.
* An ASP.NET AJAX Web site.
* The AdventureWorks sample database. You can download and install the AdventureWorks database from the Microsoft Download Center. (Search for "SQL Server 2005 Samples and Sample Databases (December 2006)").

Creating an ASP.NET AJAX-Enabled Web Site

You can create ASP.NET AJAX-enabled Web sites in Visual Studio by using the template installed with ASP.NET AJAX.
To create an ASP.NET AJAX-enabled Web Site
1. Start Visual Studio.
2. In the File menu, click New Web Site.
The New Web Site dialog box is displayed.
3. Under Visual Studio installed templates, select ASP.NET AJAX-Enabled Web Site.
4. Enter a location and a language, and then click OK.

Adding an UpdatePanel Control to an ASP.NET Web Page

After you create an AJAX-enabled Web site, you create an ASP.NET Web page that includes an UpdatePanel control. Before you add an UpdatePanel control to the page, you must add a ScriptManager control. The UpdatePanel control relies on the ScriptManager control to manage partial-page updates.
To create a new ASP.NET Web page
1. In Solution Explorer, right-click the name of the site and then click Add New Item.
The Add New Item dialog box is displayed.
2. Under Visual Studio installed templates, select Web Form.
3. Name the new page Employees.aspx and clear the Place code in separate file check box.
4. Select the language you want to use.
5. Click Add.
6. Switch to Design view.
7. In the AJAX Extensions tab of the toolbox, double-click the ScriptManager control to add it to the page.
UpdatePanel Tutorial
8. Drag an UpdatePanel control from the toolbox and drop it underneath the ScriptManager control.
UpdatePanel Tutorial

Adding Content to an UpdatePanel Control

The UpdatePanel control performs partial-page updates and identifies content that is updated independently of the rest of the page. In this part of the tutorial, you will add a data-bound control that displays data from the AdventureWorks database.
To add content to an UpdatePanel control
1. From the Data tab of the toolbox, drag a GridView control into the editable area of the UpdatePanel control.
2. In the GridView Tasks menu, click Auto Format.
3. In the Auto Format panel, under Select a scheme, select Colorful and then click OK.
4. In the GridView Tasks menu, select from the Choose Data Source list.
The Data Source Configuration wizard is displayed.
5. Under Where will the application get data from, select Database and then click OK.
6. In the Configure Data Source wizard, for the Choose Your Data Connection step, configure a connection to the AdventureWorks database and then click Next.
7. For the Configure the Select Statement step, select Specify a custom SQL statement or stored procedure and then click Next.
8. In the SELECT tab of the Define Custom Statement or Stored Procedures step, enter the following SQL statement:
SELECT FirstName, LastName FROM HumanResources.vEmployee ORDER BY LastName, FirstName
9. Click Next.
10. Click Finish.
11. In the GridView Tasks menu, select the Enable paging check box.
12. Save your changes, and then press CTRL+F5 to view the page in a browser.
Notice that there is no page flash when you select different pages of data. This is because the page is not performing a postback and updating the whole page every time.


Adding an UpdateProgress Control to the Page

The UpdateProgress control displays a status message while new content for an UpdatePanel control is being requested.
To add an UpdateProgress control to the page
1. From the AJAX Extensions tab of the toolbox, drag an UpdateProgress control onto the page and drop it underneath the UpdatePanel control.
2. Select the UpdateProgress control, and in the Properties window, set the AssociatedUpdatePanelID property to UpdatePanel1.
This associates the UpdateProgress control with the UpdatePanel control that you added previously.
3. In the editable area of the UpdateProgress control, type Getting Employees ... .
4. Save your changes, and then press CTRL+F5 to view the page in a browser.
If there is a delay while the page runs the SQL query and returns the data, the UpdateProgress control displays the message that you entered into the UpdateProgress control.

Adding a Delay to the Sample Application

If your application updates each page of data quickly, you might not see the content of the UpdateProgress control on the page. The UpdateProgress control supports a DisplayAfter property that enables you to set a delay before the control is displayed. This prevents the control from flashing in the browser if the update occurs very fast. By default, the delay is set to 500 milliseconds (.5 second), meaning that the UpdateProgress control will not be displayed if the update takes less than half a second.
In a development environment, you can add an artificial delay to your application to make sure that the UpdateProgress control is functioning as intended. This is an optional step and is only for testing your application.
To add a delay to the sample application
1. Inside the UpdatePanel control, select the GridView control.
2. In the Properties window, click the Events button.
3. Double-click the PageIndexChanged event to create an event handler.
4. Add the following code to the PageIndexChanged event handler to artificially create a three-second delay:

CS

//Include three second delay for example only.
System.Threading.Thread.Sleep(3000);

VB

'Include three second delay for example only.
System.Threading.Thread.Sleep(3000)
note
The handler for the PageIndexChanged event intentionally introduces a delay for this tutorial. In practice, you would not introduce a delay. Instead, the delay would be the result of server traffic or of server code that takes a long time to process, such as a long-running database query.
5. Save your changes, and then press CTRL+F5 to view the page in a browser.
Because there is now a three-second delay every time that you move to a new page of data, you will be able to see the UpdateProgress control.
To see the full example in action, click the Run It button.


ASP.NET AJAX, previously called "Atlas", is a Microsoft implementation of an AJAX based framework, created for ASP.NET (although it can be used on other platforms as well). AJAX stands for Asynchronous JavaScript and XML, which, very simply put, is a way of transferring data between the server and client without the sending the entire page, and thereby creating a complete postback. This allows for a richer experience for the user, since loading dynamic content can be done in the background, without refreshing and redrawing the entire page. If you have ever used Gmail or Outlook Web Access, you have used an Ajax enabled webapplication, and especially Google have made Ajax very popular.

While it's perfectly possible to use Ajax without Microsoft ASP.NET AJAX, a lot of things are way easier, since Microsoft has wrapped some of most tedious parts of Ajax into their implementation. For instance, the 3 most popular browsers requires different ways of using Ajax, and have different JavaScript implementations. ASP.NET AJAX simplifies this a lot and allows you to write the same code to target all 3 major browsers.
-->First of all, you need some basic ASP.NET knowledge. If you don't already have this, then be sure to check out our great ASP.NET tutorial. It will get you started. Using ASP.NET AJAX gets a lot easier if you have a proper IDE, and we recommend Visual Web Developer 2008 Express, as described in our ASP.NET tutorial.

After you've installed the latest version, start up Visual Web Developer, and use the template "ASP.NET website" when you select "New Web Site..." from the File menu.

Read on in the following chapters, where we will get you started with ASP.NET AJAX.

-->As usual, we will use the good old "Hello, world!" as our very first example. We will begin with the code, and then we'll do a bit of explanation afterwards. If you haven't already done so, you should create a new ASP.NET website project in Visual Web Developer. The IDE will create a Default.aspx and Default.aspx.cs file for you, which will look just like any other ASP.NET enabled page. Let's add some AJAX to it:
<%@ Page Language="C#" AutoEventWireup="true"  CodeFile="Default.aspx.cs" Inherits="_Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Hello, world!</title>
</head>
<body>
    <form id="form1" runat="server">
        <asp:ScriptManager ID="MainScriptManager" runat="server" />
        <asp:UpdatePanel ID="pnlHelloWorld" runat="server">
            <ContentTemplate>
                <asp:Label runat="server" ID="lblHelloWorld" Text="Click the button!" />
                <br /><br />
                <asp:Button runat="server" ID="btnHelloWorld" OnClick="btnHelloWorld_Click" Text="Update label!" />
            </ContentTemplate>
        </asp:UpdatePanel>
    </form>
</body>
</html>
In the CodeBehind, there's nothing new except for this event which you should add:
protected void btnHelloWorld_Click(object sender, EventArgs e)
{
    lblHelloWorld.Text = "Hello, world - this is a fresh message from ASP.NET AJAX! The time right now is: " + DateTime.Now.ToLongTimeString();
}
In the markup part, we use two new things, when compared to regular ASP.NET: The ScriptManager control and the UpdatePanel control. The ScriptManager makes sure that the required ASP.NET AJAX files are included and that AJAX support is added, and has to be included on every page where you wish to use AJAX functionality. After the manager, we have one of the most used controls when working with AJAX, the UpdatePanel. This control allows you to wrap markup which you would like to allow to be partially updated, that is, updated without causing a real postback to the server. More about the UpdatePanel in a coming chapter. Besides those two controls, everything else is standard controls, with no modifications that would indicate alternate behavior.

Try running the example site, and click the button. The label will be updated with our usual Hello world text, and the current time. Try repeatedly clicking the button, and you will see the label get the current timestamp each time. Notice the wonderful absence of a blinking window and a running status bar - everything is done without updating anything but the label! We've just created our first AJAX enabled page. If you wish to see how this page would work without AJAX, try setting the "enablepartialrendering" of the ScriptManager to false like this:
<asp:ScriptManager ID="MainScriptManager" runat="server" enablepartialrendering="false" />
This will disallow the use of partial rendering on the page, and show you how it would work without AJAX.

In the following chapters we will look into the various AJAX controls and how to use them.
The UpdatePanel control is probably the most important control in the ASP.NET AJAX package. It will AJAX'ify controls contained within it, allowing partial rendering of the area. We already used it in the Hello world example, and in this chapter, we will go in depth with more aspects of the control.

The tag has two childtags - the ContentTemplate and the Triggers tags. The ContentTemplate tag is required, since it holds the content of the panel. The content can be anything that you would normally put on your page, from literal text to web controls. The Triggers tag allows you to define certain triggers which will make the panel update it's content. The following example will show the use of both childtags.
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>UpdatePanel</title>
</head>
<body>
    <form id="form1" runat="server">
        <asp:ScriptManager ID="ScriptManager1" runat="server" />
        <asp:UpdatePanel runat="server" id="UpdatePanel" updatemode="Conditional">
        <Triggers>
            <asp:AsyncPostBackTrigger controlid="UpdateButton2" eventname="Click" />
        </Triggers>
            <ContentTemplate>
                <asp:Label runat="server" id="DateTimeLabel1" />
                <asp:Button runat="server" id="UpdateButton1" onclick="UpdateButton_Click" text="Update" />               
            </ContentTemplate>
        </asp:UpdatePanel>
        <asp:UpdatePanel runat="server" id="UpdatePanel1" updatemode="Conditional">           
            <ContentTemplate>
                <asp:Label runat="server" id="DateTimeLabel2" />
                <asp:Button runat="server" id="UpdateButton2" onclick="UpdateButton_Click" text="Update" />
            </ContentTemplate>
        </asp:UpdatePanel>
    </form>
</body>
</html>
Here is the CodeBehind. Just add the following method to the file:
protected void UpdateButton_Click(object sender, EventArgs e)
{
    DateTimeLabel1.Text = DateTime.Now.ToString();
    DateTimeLabel2.Text = DateTime.Now.ToString();
}
So, what's this example all about? Try running it, and click the two buttons. You will notice that then first button updates only the first datestamp, while the second button updates both. Why? We have set the Panels to update conditionally, which means that their content is only updated if something insides them causes a postback, or if one of the defined triggers are fired. As you can see, the first UpdatePanel carries a trigger which references the second button. This will ensure that the first panel is updated even when a control on a different UpdatePanel is used. The AsyncPostBackTrigger tag is pretty simple - it only takes two attributes, the controlid, a reference to the control which can trigger it, and the eventname, which tells which eventtype can cause the trigger to fire. If you wish for the content of a UpdatePanel to be updated no matter what, you may change the updatemode property to Always.

In general, you should only have UpdatePanels areound areas where you wish to do partial updates. Don't wrap your entire page within an UpdatePanel, and don't be afraid to use several panels, since this will give you more control of which areas update and when they do it.
One of the problems with Ajax, is the fact that since it's asynchronus and in the background, the browser will not show you any status. With fast servers and fast methods, this is not a big problem, but whenever you have a method which takes up a bit of time, the user is very likely to get impatient. Fortunately, ASP.NET AJAX solves this problem for us as well, with a nice control called UpdateProgress. It will use your own template to show that an asynchronus method is working. Have a look at the following example, which will show the control in action. It will be explained afterwards.
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>UpdateProgress control</title>
</head>
<body>
    <form id="form1" runat="server">
        <asp:ScriptManager ID="ScriptManager1" runat="server" />
        <asp:UpdateProgress runat="server" id="PageUpdateProgress">
            <ProgressTemplate>
                Loading...
            </ProgressTemplate>
        </asp:UpdateProgress>
        <asp:UpdatePanel runat="server" id="Panel">
            <ContentTemplate>
                <asp:Button runat="server" id="UpdateButton" onclick="UpdateButton_Click" text="Update" />
            </ContentTemplate>
        </asp:UpdatePanel>
    </form>
</body>
</html>
The following method should be added to your CodeBehind file:
protected void UpdateButton_Click(object sender, EventArgs e)
{
    System.Threading.Thread.Sleep(5000);
}
This simple example will just show you how easy it is to use the UpdateProgress control. Once the button is clicked, the script sleeps for 5 seconds (don't use code like that in your real projects - it's for demonstrational purposes only!), and the "Loading..." text is displayed on your page. You can use anything in the ProgressTemplate, including ordinary markup and other controls. A common use is an animated GIF, positioned strategically on the page using CSS positioning.

You can have multiple UpdateProgress controls on the page, and by using the AssociatedUpdatePanelID property, you can make sure that the UpdateProgress is only shown when a certain UpdatePanel is updated.

The DynamicLayout property is nice to know as well. It tells whether or not the page should reserve space for your progress control. If it's set to true, which is the default, the space is dynamic, hence it's not reserved, but taken when the control is shown. If you wish to reserve the space, set this property to false. To see the difference, add the property to our example and change it back and forth.

If some of your postbacks are fast, the UpdateProgress will only be shown for a very short amount of time, resulting in a blinking behavior, which may confuse your users. For that reason, you may specify a minimum amount of time to occur before showing the progress control. This can be done with the DisplayAfter attribute. Specify a number of milliseconds to elapse before showing the progress control, e.g. 2000 if you wish to wait for 2 seconds.


Timer controls
Timer controls allow you to do postbacks at certain intervals. If used together with UpdatePanels, which is the most common approach, it allows for timed partial updates of your page, but it can be used for posting back the entire page as well. In this chapter we will focus on using timers with UpdatePanels, so if you haven't already read the chapter on UpdatePanels, please do so now.

Here is a small example of using the Timer control. It simply updates a timestamp every 5 seconds.
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Timers</title>
</head>
<body>
    <form id="form1" runat="server">
        <asp:ScriptManager ID="ScriptManager1" runat="server" />
        <asp:Timer runat="server" id="UpdateTimer" interval="5000" ontick="UpdateTimer_Tick" />
        <asp:UpdatePanel runat="server" id="TimedPanel" updatemode="Conditional">
            <Triggers>
                <asp:AsyncPostBackTrigger controlid="UpdateTimer" eventname="Tick" />
            </Triggers>
            <ContentTemplate>
                <asp:Label runat="server" id="DateStampLabel" />
            </ContentTemplate>
        </asp:UpdatePanel>
    </form>
</body>
</html>
We only have a single CodeBehind function, which you should add to your CodeBehind file:
protected void UpdateTimer_Tick(object sender, EventArgs e)
{
    DateStampLabel.Text = DateTime.Now.ToString();
}
This is all very simple. We have a normal UpdatePanel, which carries a Trigger reference to our new Timer control. This means that the panel is updated when the Timer "ticks", that is, fires the Tick event. The Timer control uses the interval attribute to define the number of milliseconds to occur before firing the Tick event. As you can see from our CodeBehind code listing, we just update the DateStampLabel each time the Timer fires. This could be done more efficient with a simple piece of JavaScript, which updates the time on the clientside instead of involving the server. The example is only used to demonstrate the potential of the Timer control.

Another approach is including the Timer inside the UpdatePanel. Doing so would save us from defining a trigger, but you should be aware of the fact that the behavior will be different, depending on whether you have the Timer inside or outside an UpdatePanel. When a Timer is inside an UpdatePanel, the Timer is not re-constructed until the UpdatePanel is fully updated. That means that if you have a Timer with an interval of 60 seconds, and the update takes 5 seconds, the next event won't be fired 60 seconds after the previous, but 65 seconds after. On the other hand, if the Timer is outside the UpdatePanel, the user will only look at the content of the panel for 55 seconds before it's updated again.

You should always remember that even though partial updates are not as heavy on the server as real postbacks, the server is still contacted, and when using timers, you may get a lot of partial postbacks, which can slow things down. Always use as high intervals as possible, and consider if contacting the server is really necessary or not.


Working with Accordion AJAX Control
Introduction
There are series of controls (Extenders or simply first class control) in the AJAX control Toolkit. One of them is of particular interest in this article, the Accordion control. This control would enrich your website and gives it a professional look. In addition, the Accordion control of presenting large amount of information in a relatively small space.
Accordion and Accordion Pane(s)
It is time to enrich your web page. The accordion control is composed of parent control and multiple child controls called accordion panes. This accordion control is fully customizable in the sense of the design as well as the contents.
Requirements
In order to be able to work with AJAX ASP.NET Control Toolkit, the following should be available:
· Microsoft Visual Studio 2005 or you can also use the Visual Web Developer Express 2005 (offered for free from Microsoft on http://msdn.microsoft.com/express)
· Download AJAX extensions from http://ajax.asp.net and install them on your computer after installing Visual studio.
· Download AJAX control toolkit from http://ajax.asp.net link to code project or directly from code project (it is a zip file).
· After download, open Visual Studio or Visual Web Developer and add a tab in the Toolbox named AJAX Toolkit.
· Right Click in this tab and choose add items. Browse to the sample directory of where you did extract the toolkit and then to bin directory and choose the DLL.
· This is all. You have AJAX control Toolkit installed and you can start building your controls.
Well, you should be ready by now to begin AJAX Toolkit implementation.
Creating Your Accordion Solution
Follow the easy steps below to create your solution.
1. Start your Visual Studio 2005 IDE
2. Choose Create Web Site from the menu
3. In this sample application we will use the Visual Basic language for the sample application
4. Name the solution AccordionSample
5. Choose ASP.NET AJAX Control Toolkit Web Site
6. Choose File System in the location box
7. Click OK to create the project
8. Visual Studio 2005 will create your project with a Default.aspx page and most probably a readme.txt. Go ahead, get rid of the latter file.
9. Open Default.aspx page in design view.
10. You noticed that there is a control on the page already called Script Manager. (Well, AJAX is really a script based implementation of the language JavaScript). In Short, Script Manager control manages client script for Microsoft ASP.NET AJAX pages. By default, the Script Manager control registers the script for the Microsoft AJAX Library with the page. This enables client script to use the type system extensions and to support features such as partial-page rendering and Web-service calls.
11. Now drag a Accordion Control from the Toolkit and drop it on the form in design mode.
12. It is preferable if you create a style sheet as included in Listing 1. (If you do not create this style sheet, you will end up with an accordion with no color unless you go and specify every style item by yourself).
Listing 1 - StyleSheet.css content
/* Accordion */
.accordionHeader
{
    border: 1px solid #2F4F4F;
    color: white;
    background-color: #2E4d7B;
      font-family: Arial, Sans-Serif;
      font-size: 12px;
      font-weight: bold;
    padding: 5px;
    margin-top: 5px;
    cursor: pointer;
}
 
#master_content .accordionHeader a
{
      color: #FFFFFF;
      background: none;
      text-decoration: none;
}
 
#master_content .accordionHeader a:hover
{
      background: none;
      text-decoration: underline;
}
 
.accordionHeaderSelected
{
    border: 1px solid #2F4F4F;
    color: white;
    background-color: #5078B3;
      font-family: Arial, Sans-Serif;
      font-size: 12px;
      font-weight: bold;
    padding: 5px;
    margin-top: 5px;
    cursor: pointer;
}
 
#master_content .accordionHeaderSelected a
{
      color: #FFFFFF;
      background: none;
      text-decoration: none;
}
 
#master_content .accordionHeaderSelected a:hover
{
      background: none;
      text-decoration: underline;
}
 
.accordionContent
{
    background-color: #D3DEEF;
    border: 1px dashed #2F4F4F;
    border-top: none;
    padding: 5px;
    padding-top: 10px;
}
13. Now go back to default.aspx and open it in source view (nice HTML Tags)…
14. If you have added the style sheet…Go to the head section and after the title section, add the listing 2 in order to include the style sheet to the page.
Listing 2 - Style Sheet Link Reference
<link href="StyleSheet.css" rel="stylesheet" type="text/css" />
15. In the Accordion Tag line make them as in listing 3. Notice the use of some additional tags for the accordion. The FadeTransitions is used to create the effect of smooth sliding. Selected Indexed is used to open a pane by default in our case it is the first pane. Transition duration is giving in milliseconds to specify how much to take to perform the total opening. And last, the two style association from the style sheet to give the accordion some color as specified in the style sheet.
Listing 3 - Accordion Specs in Source Mode
<ajaxToolkit:Accordion ID="Accordion1" runat="server" FadeTransitions="True" 
SelectedIndex="0" TransitionDuration="300"  HeaderCssClass="accordionHeader" 
ContentCssClass="accordionContent">
16. Now we have our accordion, we have to add panes to it. However, before adding panes we have to add the panes section inside the accordion.
17. After adding the pane section, you can create as many panes as you like. But please note that every pane should have a header and a content tags.
18. In order how I did construct my panes, take a look at listing 4.
Listing 4 - The complete pane section in HTML
<Panes>
<ajaxToolkit:AccordionPane id="AccordionPane1" runat="server">
<Header> AJAX PANE</Header>
<Content>
AJAX HAS BEEN KNOW TO ENHANCE USER INTERFACE<br />
AJAX HAS BEEN KNOW TO ENHANCE USER INTERFACE<br />
AJAX HAS BEEN KNOW TO ENHANCE USER INTERFACE<br />
AJAX HAS BEEN KNOW TO ENHANCE USER INTERFACE<br />
</Content>
</ajaxToolkit:AccordionPane>
<ajaxToolkit:AccordionPane id="AccordionPane2" runat="server">
<Header>MY TEST PANE
</Header>
<Content>
THIS IS JUST A TEST OF PANE CONTENT<br />
THIS IS JUST A TEST OF PANE CONTENT<br />
THIS IS JUST A TEST OF PANE CONTENT<br />
</Content>
</ajaxToolkit:AccordionPane>
<ajaxToolkit:AccordionPane id="AccordionPane3" runat="server">
<Header>THIS IS LAST PANE
</Header>
<Content>
HOPE YOU LIKE WHAT YOU SEE<br />
THIS IS JUST A TEST OF PANE CONTENT<br />
HOPE YOU LIKE WHAT YOU SEE<br />
</Content>
</ajaxToolkit:AccordionPane>
</Panes>
19. Please note that coding was necessary here. Also note that the panes can contain any HTML tags you like.
The final output will look like the figures shown below
Figure 1 - The Default Output
Figure 2 - Output when the second pane is clicked
Downloads


Animation Extender Example ASP.NET AJAX

October 12, 2007 16:13 by John M
I found myself struggling on how to use the ASP.NET AJAX Control Toolkit Animation Extender. I wanted to use a simple example on a website that was basically the example they give on the Toolkit website. I wanted the user to click a link and it would “fly-out” a window to show more information. I tried to follow the example online however, I found myself missing an important part to it…the CSS aspect of it. I wanted to write a quick example of how to do this without you trying to read Microsoft’s source code and example online.
Step 1: The following styles will need to be used in order for this to work. I would recommend placing the classes into a stylesheet.
.flyOutDiv
{
display: none;
position: absolute;
width: 400px;
z-index: 3;
opacity: 0;
filter:(progid:DXImageTransform.Microsoft.Alpha(opacity=0));
font-size: 14px;
border: solid 1px #CCCCCC;
background-color: #FFFFFF;
padding: 5px;
}
.flyOutDivCloseX
{
background-color: #666666;
color: #FFFFFF;
text-align: center;
font-weight: bold;
text-decoration: none;
border: outset thin #FFFFFF;
padding: 5px;
}
Step 2: Place the DIV on your web page and the link button that we will use for our target control ID to activate the animation. You will notice the OnClientClick=”return false;” this is so the link button does not post back.








some content here for whatever text


Step 3: Add the AnimationExtender to the web page











































You'll notice in step 3 there are 2 animation extenders. One is to show and move the DIV and the second is to close, move and hide the DIV. The StyleAction tag in the second extender are very important because this is what sets the DIV back to the default view as if you just loaded the web page again.
Using the Animation Extender in AJAX Toolkit
In this tutorial, we will be looking at how to use the AnimationExtender in the AJAX Control Toolkit from Microsoft. This tutorial is aimed toward users of Visual Studio.NET 2008, but should work with 2005 providing the AJAX Extensions are installed.
This tutorial uses the Microsoft AJAX.NET Toolkit, which can be downloaded from the following link:
www.asp.net/Ajax/ajaxcontroltoolkit/

If you need help installing the Toolkit, please see this article.
In this tutorial, we will be explore using the AnimationExtender to utilize JavaScript to animate controls in our web application. The first thing we will need to do is to add a ScriptManager to our ASPX page, which will allow us to implement AJAX:
I just signed up at Server Intellect and couldn't be more pleased with my Windows Server! Check it out and see for yourself.
The next thing we will do is add an ASP.NET Panel control onto our page and drag an AnimationExtender from the Toolkit toolbox to our ASPX page:
.Animation1
{
position: absolute;
padding:3px;
border: solid 1px #000;
}

..





Animation imminent.





Notice that we have declared a CSS class for our Panel to use. If we do not make the Panel's position absolute, then we will not be able to manipulate its position on the page.
Now in order to actually animate the Panel, we are required to insert further parameters into the Extender, for example:


If you're looking for a really good web host, try Server Intellect - we found the setup procedure and control panel, very easy to adapt to and their IT team is awesome!
We keep everything within the Extender tags, and notice that they are not all specified as attributes. There are a number of triggers we can use for animations, which include OnLoad, OnClick, OnMouseOver, OnMouseOut, OnHoverOver, and OnHoverOut. In this example we are using the OnLoad trigger so that when the page loads, the Panel will be animated 300 pixels horizontally over a period of 1 second. We are also able to set the number of frames per second with the Fps attribute.
Now when this page is run, the Panel will be animated as soon as the page is done loading. Now, if we wanted to animate on a button click, then we would use the OnClick trigger.
To do this, let's add a button and another panel to our ASPX page:

.Animation2
{
display:none;
position:absolute;
width:1px;
height:1px;
left:400px;
top:600px;
padding:3px;
border:solid 1px #000;
}

..




Animation2 imminent.







We are using Server Intellect and have found that by far, they are the most friendly, responsive, and knowledgeable support team we've ever dealt with!
We create another CSS class for the new panel and notice we also change the OnLoad trigger as in the last example to OnClick. We are also required to set an AnimationTarget as our TargetControl is now the button, not the panel. The animation sequence is similar to the last, except we use Scale to increase the size of the Panel as well.
Our ASPX page looks something like this:

..





Animation imminent.














Animation2 imminent.







as you can see when the search button is clicked, the entire virtual earth map control fades out until the results come back. so my only problem (as i wanted to use the microsoft ajax library) was that it wasn't a server control or wasn't an update panel. so i had to use an animation extender, but also had to do it only on the client (as the virtual earth control is a client-only control right now as well).
here's what i did (thanks to some guidance from a colleague as well). i basically added an element on my page that was a fake element -- a div with no visibility...think of it as an ajax placeholder:
   1:  <div id="FakeTarget" runat="server" style="display:none"></div>

then i added animation extenders on there (one for fade in and one for fade out) and attached them to the fake target element as the extenders require a target element to attach to at runtime.
   1:  <ajax:AnimationExtender ID="mapfadeout" runat="server" Enabled="true" TargetControlID="FakeTarget">
   2:      <Animations>
   3:          <OnClick>
   4:              <Sequence>
   5:                  <OpacityAction AnimationTarget="map" Opacity=".4" />
   6:              </Sequence>
   7:          </OnClick>
   8:      </Animations>
   9:  </ajax:AnimationExtender>
  10:  <ajax:AnimationExtender ID="mapfadein" runat="server" Enabled="true" TargetControlID="FakeTarget">
  11:      <Animations>
  12:          <OnClick>
  13:              <Sequence>
  14:                  <OpacityAction AnimationTarget="map" Opacity="1" />
  15:              </Sequence>
  16:          </OnClick>
  17:      </Animations>
  18:  </ajax:AnimationExtender>

my next step was in my javascript function to instantiate these behaviors when i wanted...so in my client script i got a handle to the extenders and manually called their play function...and did the same in my callback function getting the net effect you see in the above image...here's the script:
   1:  var onclick = $find("mapfadeout").get_OnClickBehavior().get_animation();
   2:  onclick.set_target("map");
   3:  onclick.play();

you may think that it is lame to have two extenders, but if you look at how i would have accomplished this using the updatepanelanimationextender if i was able to use a server control, then it is still similar -- that extender has OnUpdating/OnUpdated event handlers...so same thing, just in one extender...net effect is the same.
i hope this helps guide anyone doing something similar!


AjaxToolkit: AutoCompleteExtender
Here is the solution

<%
@ Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" tagprefix="ajaxToolkit"%>
Which says that the reference assembly "AjaxControlToolkit.dll" should be registered on the page by using above method. We should also have tagprefix="ajaxToolkit" which is similar to .
In this article I have very simple database table called as "Tbl_Countries" with fields as:
CountryId int primary key,
CountryName varchar(50)
I am using a web service called as "AutoComplete.asmx" whose code behind gets automatically added to the "App_Code" folder.
Note: Very important part is you need to give a reference of "AjaxControlToolkit.dll".
Here is complete code for "AutoComplete.asms.cs".
using System;
using System.Web;
using System.Collections;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.Data;
using System.Data.SqlClient;
using System.Configuration;
///



/// Summary description for AutoComplete
///

[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.Web.Script.Services.ScriptService]
public class AutoComplete : System.Web.Services.WebService
{
[WebMethod]
public string[] GetCountriesList(string prefixText)
{
DataSet dtst = new DataSet();
SqlConnection sqlCon = new SqlConnection(ConfigurationManager.AppSettings["ConnectionString"]);
string strSql = "SELECT CountryName FROM Tbl_Countries WHERE CountryName LIKE '" + prefixText + "%' ";
SqlCommand sqlComd = new SqlCommand(strSql, sqlCon);
sqlCon.Open();
SqlDataAdapter sqlAdpt = new SqlDataAdapter();
sqlAdpt.SelectCommand = sqlComd;
sqlAdpt.Fill(dtst);
string[] cntName = new string[dtst.Tables[0].Rows.Count];
int i = 0;
try
{
foreach (DataRow rdr in dtst.Tables[0].Rows)
{
cntName.SetValue(rdr["CountryName"].ToString(), i);
i++;
}
}
catch { }
finally
{
sqlCon.Close();
}
return cntName;
}
}
Let us take another page called as "default.aspx" in which I am having a tag and in which a tag in which you can specify path of webservices. You have already registered Assembly="AjaxControlToolkit" on this page so you can use that.

So my entire code will look something like this
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<%@ Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" tagprefix="ajaxToolkit"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server">
<Services>
<asp:ServiceReference Path="AutoComplete.asmx" />
</Services>
</asp:ScriptManager>
<div>
<asp:TextBox ID="txtCountry" runat="server"></asp:TextBox>
<ajaxToolkit:AutoCompleteExtender runat="server" ID="autoComplete1" TargetControlID="txtCountry" ServicePath="AutoComplete.asmx"ServiceMethod="GetCountriesList" MinimumPrefixLength="1" EnableCaching="true" />
</div>
</form>
</body>
</html>
Following snapshot gives you clear idea as how the AutoCompleteExtender works.

AutoComplete TextBox (Using AJAX AutoCompleteExtender) from Database

Recently I tried AutoComplete extender (AJAX toolkit) in one of my on going web application. What I suppose to do is, user shall be able to get the AutoSense list of available products from database on typing the name of the product in a TextBox. When user types some letters in the Textbox, a popup panel will come to action and displayed the related words. So that the user can choose exact word from the popup panel. BTW, Ajax extension and Ajax Tool Kit should already be installed to implement any AJAX extenders. Here are the steps how to accomplish an AutoComplete TextBox from Database:
· We start by creating new website. Create a new website by selecting “ASP.NET AJAX-Enabled Web Site” from installed templates in “New Web Site” window.
· ScriptManager” would already be there in your webpage (Default.aspx), as we have selected AJAX Enabled Website.
· Now drag and drop a Textbox from your Toolbox and AutoCompleteExtender to your webpage.
· Then add a webservice to your project as WebService.asmx.
· First of all, you need to Import “System.Web.Script.Services” namespace and add the “ScriptService” reference to the webserive.
· Next, just need to write a simple webmethod ‘GetProducts’ to fetch the data from the Product table which will return the string array with product names.
· We will pass the “PrefixText” to this webmethod; I mean the characters that are typed by the user in the textbox to get the exact AutoComplete Product list form Database that start with the characters typed by the user.
· Here is the complete webmethod for that:
using System;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Web;
using System.Collections;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.Web.Script.Services;

///


/// Summary description for WebService
///

[ScriptService]
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class WebService : System.Web.Services.WebService
{
public WebService()
{
//Uncomment the following line if using designed components
//InitializeComponent();
}
[WebMethod]
public string[] GetProducts(string prefixText)
{
string sql = "Select * from product Where name like @prefixText";
SqlDataAdapter da = new SqlDataAdapter(sql, ConfigurationManager.AppSettings["DBConn"]);
da.SelectCommand.Parameters.Add("@prefixText", SqlDbType.VarChar, 50).Value = prefixText + "%";
DataTable dt = new DataTable();
da.Fill(dt);
string[] items = new string[dt.Rows.Count];
int i = 0;
foreach (DataRow dr in dt.Rows)
{
items.SetValue(dr["name"].ToString(), i);
i++;
}
return items;
}
}

· you can see that we have passed prefixText as argument in above webmethod , which sends it to the query to fetch only the related words that starts with the prefixText values. Then it returns the result as an array of strings.
· In the your webpage, set the AutoCompleteExtender’s TargetControlID property to the TextBox Id. You also need to set ServicePath property as WebService.asmx, ServiceMethod as GetProducts and MinimimPrefixLength as 1.
· So, your web page design code will be something like:








Thats it! Quite simple and a useful feature that user would like to have. Find the sample Code available to Download in attechment.

The Atlas AutoCompleteExtender

Friday January 13, 2006 5:04AM
by Christian Wenz
AddThis Social Bookmark Button
One of the most anticipated new features of the Atlas December CTP is the AutoCompleteExtender which adds a feature like Google Suggests to a web page. Nikhil Kothari blogged about the new release, but I did not find a complete step-by-step example (although I honestly did not look very long for it). So I sat down and played around with it and found out how this feature works.
The first step is quite easy: Take the
control and put it in your code. Link it to an existing web control you would like to “auto-complete”, ideally a textbox control. Then, link these two controls using the TargetControlID attribute and provide the URL to a web service and the name of a web method within it:



ServiceMethod="GetValues" TargetControlID="vendor" />


On the server side, you have to write this web method. The only difficulty is to find out the method signature. Well, here it is:

public string[] MethodName(string PrefixText, int count) {}

Obviously,
PrefixText is the string to search for, and count the maximum number of matches to be returned and displayed. It is also important to know that only .NET Web Sevices are supported
This being said, it is very easy to write a little lookup code. You could query a database, or you just use a static dictionary as in the example below. I know that there are numerous possibilities to optimize the code, but hey, it works :-)
<%@ WebService Language="C#" Class="AutoCompleteSampleService" %>
using System;
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;
[WebService(Namespace = "http://hauser-wenz.de/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class AutoCompleteSampleService : System.Web.Services.WebService
{
[WebMethod]
public string[] GetValues(string PrefixText, int count)
{
string[] values = { "incomplete", "inconsistent", "incompatible", "impossible", "important", "increment", "include", "impose" };
int matches = 0;
for (int i = 0; i < values.Length; i++)
{
if (values[i].StartsWith(PrefixText))
{
matches++;
}
}
int size = Math.Min(matches, count);
string[] output = new string[size];
for (int i = 0; i < values.Length; i++)
{
if (size == 0)
{
break;
}
if (values[i].StartsWith(PrefixText))
{
output[--size] = values[i];
}
}
return output;
}
}

ASP.NET AJAX AutoComplete Example Using AutoCompleteExtender Control

The AutoCompleteExtender Control in the ASP.NET AJAX Toolkit is an awesome way to offer suggestions to users in your ASP.NET Web Applications. It is also very easy to use.
Create an ASP.NET AJAX Website and toss a TextBox and the AutoCompleteExtender Control on the page.
AutoCompleteExtender Control
Fill out the details of the control to specify the appropriate ServicePath andServiceMethod of the web service that the AutoCompleteExtender Control will call. In this case I have a web service, called MyAutocompleteService, with a web method, called GetSuggestions. The control will start offering me suggestions once the first character is typed into the TextBox and ask for up to 12 suggestions.
ID="AutoCompleteExtender1"
runat="server"
ServicePath="MyAutocompleteService.asmx"
ServiceMethod="GetSuggestions"
TargetControlID="TextBox1"
MinimumPrefixLength="1"
CompletionSetCount="12">

The GetSuggestions WebMethod on the WebService echos back what was typed in an just appends up to 12 characters ( A- L ) to the text typed in. Note the addition of the [ScriptService] Attribute to use the WebService with AJAX.
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[ToolboxItem(false)]
[ScriptService]
public class MyAutocompleteService : WebService
{
[WebMethod]
public string[] GetSuggestions(string prefixText, int count)
{
List<string> responses = new List<string>();
for (int i = 0; i <>
responses.Add(prefixText + (char)(i + 65));
return responses.ToArray();
}
}
The end result is a nice autcompletion service using ASP.NET AJAX for a richer user interface.
AutoCompleteExtender Control in AJAX Control Toolkit

The Atlas AutoCompleteExtender

One of the most anticipated new features of the Atlas December CTP is the AutoCompleteExtender which adds a feature likeGoogle Suggests to a web page. Nikhil Kothari blogged about the new release, but I did not find a complete example (although I honestly did not look very long for it).
So I sat down and played around with it and found out how this feature works. See the extended entry for a full example.
The first step is quite easy: Take the control and put it in your code. Link it to an existing web control you would like to "auto-complete", ideally a textbox control. Then, link these two controls using the TargetControlID attribute and provide the URL to a web service and the name of a web method within it:




ServiceMethod="GetValues" TargetControlID="vendor" />


On the server side, you have to write this web method. The only difficulty is to find out the method signature. Well, here it is:

public string[] MethodName(string PrefixText, int count) {}

Obviously,
PrefixText is the string to search for, and count the maximum number of matches to be returned and displayed. It is also important to know that only .NET Web Sevices are supported
This being said, it is very easy to write a little lookup code. You could query a database, or you just use a static dictionary as in the example below. I know that there are numerous possibilities to optimize the code, but hey, it works :-)

<%@ WebService Language="C#" Class="AutoCompleteSampleService" %>

using System;
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;

[WebService(Namespace = "http://hauser-wenz.de/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class AutoCompleteSampleService : System.Web.Services.WebService
{

[WebMethod]
public string[] GetValues(string PrefixText, int count)
{
string[] values = { "incomplete", "inconsistent", "incompatible", "impossible", "important", "increment", "include", "impose" };
int matches = 0;
for (int i = 0; i <>
{
if (values[i].StartsWith(PrefixText))
{
matches++;
}
}

int size = Math.Min(matches, count);
string[] output = new string[size];
for (int i = 0; i <>
{
if (size == 0)
{
break;
}
if (values[i].StartsWith(PrefixText))
{
output[--size] = values[i];
}
}
return output;
}

}

And that's it! Atlas generates script code to query the web service after at least three characters have been entered into the text field.



ASP.NET AJAX Calendar Extender – Tips and Tricks
The CalendarExtender is an ASP.NET AJAX control that is associated with a TextBox control. When the user clicks on the TextBox, a client-side Calendar control pops up. The user can then set a date by clicking on a day, navigate months by clicking on the left and right arrow and perform other such actions without a postback. In this article, we will see some tips and tricks that can be applied to a CalendarExtender control. If you are new to the CalendarExtender control, you can check out some information about it over here.
I assume you have some basic experience developing ASP.NET Ajax applications and have installed the ASP.NET Ajax Library and ASP.NET Control Toolkit. As of this writing, the toolkit version is Version 1.0.20229 (if you are targeting Framework 2.0, ASP.NET AJAX 1.0 and Visual Studio 2005) and Version 3.0.20229 (if targeting .NET Framework 3.5 and Visual Studio 2008).
All the tips shown below have been created using Version 3.0.20229 (targeting .NET Framework 3.5 and Visual Studio 2008).
Tip 1: How to display and hide a Calendar on the click of a Button
If you want to popup a Calendar on the click of a button, you can use set the PopupButtonID of the CalendarExtender to the ID of the button. In this case, we will be using an ImageButton as shown below:
<asp:ImageButton runat="Server" ID="ImageButton1" ImageUrl="~/Images/Icon1.jpg"AlternateText="Click here to display calendar" />
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<cc1:CalendarExtender ID="CalendarExtender1" runat="server"
TargetControlID="TextBox1" PopupButtonID="ImageButton1"/>
If you are using an earlier version of the toolkit, you may observe that the ImageButton causes a postback when you click on it again, to close the Calendar. To avoid the postback, use a HTML Image Control instead of the Server side Image Control as shown below:
<img alt="Icon" src="/Images/Icon1.jpg" id="Image1" />
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<cc1:CalendarExtender ID="CalendarExtender1" runat="server"
TargetControlID="TextBox1" PopupButtonID="Image1"/>
Note: In case you are clicking on the textbox to open the calendar, then in earlier versions of the toolkit, the calendar would not hide automatically when the user clicked anywhere outside the Calendar control. However this was fixed in the later versions. In fact, in the latest version, the Calendar hides automatically when a date is selected.
If for some reason you are facing issues with the Calendar not hiding automatically, make sure that you have the latest version of the AJAX Control Toolkit.
Tip 2: How to Add a CalendarExtender to a GridView
If you want to add a CalendarExtender to a GridView, use a template field with a TextBox and CalendarExtender as shown below:
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server" />
<div>
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataKeyNames="CategoryID"
DataSourceID="SqlDataSource1" ShowFooter="true" AllowPaging="True" AllowSorting="True">
<Columns>
<asp:BoundField DataField="CategoryID" HeaderText="CategoryID"
SortExpression="CategoryID" />
<asp:BoundField DataField="CategoryName" HeaderText="CategoryName"
SortExpression="CategoryName" />
<asp:TemplateField>
<ItemTemplate>
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<cc1:CalendarExtender ID="CalendarExtender1" runat="server"TargetControlID="TextBox1"PopupButtonID ="TextBox1"/>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="Data Source=SUPROTIM;Initial Catalog=Northwind;Integrated Security=True"
SelectCommand="SELECT [CategoryID], [CategoryName] FROM [Categories]" >
</asp:SqlDataSource>
</div>
</form>
Tip 3: Enable Year Navigation in CalendarExtender
When the calendar appears, click on the title of the calendar to change the view to Months in the current year. Clicking it again, switches the view to Years, showing 10 years at a time.
If you plan to do this programmatically, here’s some code for you. Use the OnClientShown event and switch the mode using javascript. This tip was shared by one of the Microsoft® support person at the asp.net forums.
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<cc1:CalendarExtender ID="CalendarExtender1"
runat="server" TargetControlID="TextBox1" OnClientShown="ChangeCalendarView" />
Then add this to the section
<head runat="server">
<title>CalendarExtender</title>
<script type="text/javascript">
function ChangeCalendarView(sender,args)
{
sender._switchMode("years", true);
}
</script>
</head>
Tip 4: Display only the day and month in the CalendarExtender
To select only the day and month without the year, use the Format property of the CalendarExtender and set it to “dd/MM” as shown below:
<cc1:CalendarExtender ID="CalendarExtender1" runat="server" Format="dd/MM" TargetControlID="TextBox1" />
Tip 5: How to Set Culture to work with CalendarExtender
Make sure that the ScriptManager has EnableScriptGlobalization="true" and EnableScriptLocalization="true".
<asp:ScriptManager ID="ScriptManager1" runat="server"
EnableScriptGlobalization="true" EnableScriptLocalization="true" />
Tip 6: How to make sure user does not select a date earlier than today or greater than today
There could be instances where you do not want the user to select a day earlier than the current date. For example: when you are providing the user a form to book tickets, you would not like him to choose an earlier date. To achieve this requirement, use the following javascript code.
Prevent the User from selecting a Date Earlier than today
<head runat="server">
<title>Calendar Extender</title>
<script type="text/javascript">
function checkDate(sender,args)
{
if (sender._selectedDate < new Date())
{
alert("You cannot select a day earlier than today!");
sender._selectedDate = new Date();
// set the date back to the current date
sender._textbox.set_Value(sender._selectedDate.format(sender._format))
}
}
</script>
</head>
Call the code:
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server" />
<div>
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<cc1:CalendarExtender ID="CalendarExtender1"
runat="server" OnClientDateSelectionChanged="checkDate" TargetControlID="TextBox1" />
</div>
</form>
Select Date Greater than today
In the javascript, just change this line
sender._selectedDate > new Date()
Note: You may argue that the user can still change the date by typing into the textbox or entering an invalid date. Well that can be easily handled using a ValidationControl and is covered in the next tip.
Tip 7: Add validation to the CalendarExtender Control
A simple way to add validation to the Calendar is to add a ValidationControl to the textbox associated with a CalendarExtender. You have two choices:
A. Add an ‘Extender’ to the ValidationControl. To do so, drag and drop a ValidationControl > click on the smart tag of the ValidationControl > choose ‘Add Extender’. From the Extender Wizard, choose ValidatorCalloutExtender. Using this approach makes it extremely easy to discover and attach control extenders to your controls. In VS 2005, you had to do this process manually, by wiring up control extenders.
B. You can choose not to add the Extender.
We will go ahead with option A. We will be adding two ValidationControls to the textbox. The first, a CompareValidator to check if the user does not enter an invalid date (Eg: May 32) and second, a RangeValidator to keep the date range as desired.
Adding CompareValidator
<asp:CompareValidator ID="CompareValidator1" runat="server"
ControlToValidate="TextBox1" Display="Dynamic" ErrorMessage="Invalid Date"
Operator="DataTypeCheck" Type="Date">
</asp:CompareValidator>
<cc1:ValidatorCalloutExtender ID="CompareValidator1_ValidatorCalloutExtender"
runat="server" Enabled="True" TargetControlID="CompareValidator1">
</cc1:ValidatorCalloutExtender>
Adding RangeValidator – We will restrict the user to select a date range starting from today to 15 days from now.
<asp:RangeValidator ID="RangeValidator1" runat="server"
ControlToValidate="TextBox1" ErrorMessage="RangeValidator"
Type="Date">
</asp:RangeValidator>
<cc1:ValidatorCalloutExtender ID="RangeValidator1_ValidatorCalloutExtender"
runat="server" Enabled="True" TargetControlID="RangeValidator1">
</cc1:ValidatorCalloutExtender>
In the code behind of your page, add this code
C#
protected void Page_Load(object sender, EventArgs e)
{
RangeValidator1.MinimumValue = System.DateTime.Now.ToShortDateString();
RangeValidator1.MaximumValue = System.DateTime.Now.AddDays(15).ToShortDateString();
}
VB.NET
Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs)
RangeValidator1.MinimumValue = System.DateTime.Now.ToShortDateString()
RangeValidator1.MaximumValue = System.DateTime.Now.AddDays(15).ToShortDateString()
End Sub
Well those were some tips associated with the CalendarExtender. As future versions of the toolkit are released, we should be hopeful that there will exist easier ways, of achieving the functionality discussed in this article. I hope this article was useful and I thank you for viewing it.

AJAX CalendarExtender setting off page_load when ImageButton clicked

Zones:

Programming for ASP.NET, .NET, Active Server Pages (ASP)

Tags:

calendarextender, ajax

I am using AJAX with .net 2005 and am having a problem with the calendar control and update progress control. I am posting the code with the calendar control only so somebody can hopefully help me solve this problem. Whenever I hit the calendar but for the calendar extender to display, my page load is always called even when I say autopostback false. And if I set causesvalidation to false, nothing happens. What is going on here? How do I use the calendarextender with imagebutton to not keep calling page_load?? The calendar extender is at the bottom of this page. Please help.

<%@ Page
Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>

<%@ Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="ajaxToolkit" %>

html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
http://www.w3.org/1999/xhtml
">
server">
ZC Sterling Report Archive Viewer



<
script language="javascript" type="text/javascript">
<!--
///
/// DatePicker
Javascript. Opens calendar in a popup window
///
/// String.
function calendarPicker(strField)
{
window.open('DatePicker.aspx?field=' + strField, 'calendarPopup', 'width=240,height=190,resizable=yes');
}
///

/// PopUpWindow JavaScript
///

/// String.
function displayMessage(alert){
alert(myMsg);
}
//

-->











ImageUrl="Resources/navyspacer1.gif"/>









































runat="server" valign="top" visible="true">




Report Archive Viewer


Width="410px">



DataTextField="PRODUCT_NAME" DataValueField="PRODUCT_KEY" AppendDataBoundItems="True"
AutoPostBack="True" OnSelectedIndexChanged="ddlProduct_SelectedIndexChanged"
TabIndex="1" BackColor="White">
-- Select a Product --




"
ProviderName="<%$ ConnectionStrings:RptArchiveConnection.ProviderName %>" SelectCommand='SELECT "PRODUCT_NAME", "PRODUCT_KEY" FROM "PRODUCT"'>











AppendDataBoundItems="True" TabIndex="2" DataSourceID="SqlDataSource1" DataTextField="CLIENT_NAME"
DataValueField="CLIENT_KEY" AutoPostBack="True">
-- Select a Client --
All Clients

"
ProviderName="<%$ ConnectionStrings:RptArchiveConnection.ProviderName %>" SelectCommand="SELECT CLIENT.CLIENT_KEY, CLIENT.CLIENT_NAME FROM CLIENT INNER JOIN CLIENT_PRODUCT ON CLIENT.CLIENT_KEY = CLIENT_PRODUCT.CLIENT_KEY WHERE (CLIENT_PRODUCT.PRODUCT_KEY = :productKey) ORDER BY CLIENT.CLIENT_NAME">

Name="productKey" />













AutoPostBack="True" TabIndex="3" OnSelectedIndexChanged="ddlReport_SelectedIndexChanged"
DataSourceID="SqlDataSourceReports" DataTextField="REPORT_TITLE" DataValueField="REPORT_DEFINITION_KEY">
-- Select a report --









<%----%>





















ErrorMessage="*" Width="3px" SetFocusOnError="True" Font-Bold="True">*


From Date



OnTextChanged="TextBoxToDate_TextChanged">

ErrorMessage="*" Width="3px" SetFocusOnError="True" Font-Bold="True">*


To Date
colspan="7">
ControlToValidate="TextBoxFromDate" ErrorMessage="To date must be greater than from date."
Operator="LessThanEqual" Width="282px" SetFocusOnError="True" Type="Date">

ErrorMessage="Please specify from date. ">

ErrorMessage="Please specify to date.">






Report Parameters
id="Td1">





AllowSorting="True" BorderStyle="None" BorderWidth="0px" EmptyDataText="No parameters are found for this report."
Height="98px" CellPadding="0" TabIndex="6" HorizontalAlign="Center">




'>




">

















Text="Find Reports" />






Search Results







PageSize="15" AllowPaging="True" AllowSorting="True" AutoGenerateColumns="False"
CellPadding="0" EmptyDataText="No reports meeting the specified criteria were found. Modify the search criteria and try again."
BorderStyle="None" BorderWidth="0px" CaptionAlign="Bottom">





NavigateUrl='<%# this.ResolveUrl("~/" + string.Format("zcreportviewer.aspx?rpath={0}",Eval("FileName"))) %>'>






'>




'>




'>







Visible="False" />







Calendar with an associated button:

ImageUrl="Resources/Calendar_scheduleHS.png" />

TargetControlID="Date5">



(Click the image button to show the calendar; this calendar dismisses automatically
when you choose a date)








ImageUrl="Resources/navyspacer1.gif"/>















"
ProviderName="<%$ ConnectionStrings:RptArchiveConnection.ProviderName %>">

"
ProviderName="<%$ ConnectionStrings:RptArchiveConnection.ProviderName %>" SelectCommand="SELECT DISTINCT A.REPORT_TITLE, A.REPORT_DEFINITION_KEY FROM REPORT_DEFINITION A, PRODUCT B, USER_REPORT C WHERE A.PRODUCT_KEY = B.PRODUCT_KEY AND B.PRODUCT_KEY = :productKey AND C.USER_ID = UPPER(:userID) ORDER BY A.REPORT_TITLE"
OnSelecting="SqlDataSourceReportsProduct_Selecting">

PropertyName="SelectedValue" />



"
ProviderName="<%$ ConnectionStrings:RptArchiveConnection.ProviderName %>" SelectCommand="SELECT A.REPORT_TITLE, A.REPORT_DEFINITION_KEY FROM REPORT_DEFINITION A, CLIENT_REPORT B, CLIENT C, USER_REPORT D WHERE A.REPORT_DEFINITION_KEY = B.REPORT_DEFINITION_KEY AND B.CLIENT_KEY = C.CLIENT_KEY AND B.CLIENT_KEY = :clientKey AND D.REPORT_ID = B.REPORT_ID AND D.USER_ID = UPPER('ksummers') Order By A.REPORT_TITLE "
OnSelecting="SqlDataSourceReports_Selecting">









How to patch the Ajax Control Toolkit CalendarExtender to add Decade support and InitialView – Part 1

This is an educational article intended to show how to enhance the publicly available Ajax Control Toolkit Calendar Extender control. All code here is added to a fresh download of the Ajax Control Toolkit. All code here is provided under the Microsoft Public Licence.
You can download the code for the latest version (20820) of the Ajax Control Toolkit from here:http://www.codeplex.com/AjaxControlToolkit.
The licence is available here:http://ajaxcontroltoolkit.codeplex.com/license
In this case, I am intending to improve the usability of birthdate selection.
Currently, when the user wants to enter a birthdate into the text box attached to the Calendar Extender control, they click in the text box, or click on the calendar image next to the text box. The calendar extender control then pops up a Day view, as follows:
Calendar Extender Day View
Calendar Extender Day View
But we want a birthdate, so you don’t want to select a day here as it will potentially be from the wrong month or year, so what you do to select a different month is to click on the Title bar. That’s the bit that shows “April, 2009″. The calender extender control then pops up the Month view, as follows:
Calendar Extender Month View
Calendar Extender Month View
Next, you want the year, so you click on the Title bar again. That now shows “2009″. The calendar extender control then pops up the Year view, as follows:
Calendar Extender Year View
Calendar Extender Year View
Ok, so say we want 26 May 1970. We now need to choose a different decade. But clicking on the title doesn’t allow you to select a new decade. Instead, you need to use the arrows to go forward or backwards between decades. So you would click the left arrow in the top left corner 3 times to get to the decade that you want, the 1970s, as follows:
Calendar Extender 1970-1979 year view
Calendar Extender 1970-1979 year view
Then you need to click on the year you want, 1970. On selection, it switches back to the month view. You click the month that you want, May, then it switches to the Day view. You can then select the day that you want, 26. On selecting this, the calendar closes, and the text box is populated with 26/05/1970 (or whatever your date format is for the selected region and setting in the calendar extender). That’s a lot of work to select a birthdate.


CascadingDropDown List
Introduction
I have seen in many forums people asking questions as “how to populate the cascadingdropdown with values from database
.” Although there was a sample provided for the same in the ASP.NET AJAX ControlToolkit, most of the learners (novice) following the walkthrough given athttp://ajax.asp.net/ajaxtoolkit/Walkthrough/CCDWithDB.aspx get struck at the CarsTableAdapters used in the webservice.
This article explains the step-by-step procedure on how to create CascadingDropDown using database values with the help of Microsoft SQL Server 2005 Express Edition. We will display the models available for a selected car using the cascadingdropdown.
Creating a new ASP.NET AJAX Enabled website
To create a new website in Visual Studio 2005 click, File >> New >> Web Site and select ASP.NET AJAX Enabled Web Site from the available templates. I named the application as CCDFromDatabaseand used C# as the coding language.
I used ASP.NET AJAX 1.0 Library in this sample. The latest library can be downloaded from Microsoft site [http://ajax.asp.net/downloads/default.aspx?tabid=47].
Figure 1
Add a reference to the latest AjaxControlToolkit.dll in your project. To add a reference, right click on the Project >> Add Reference >> Browse. Select the location to where you have downloaded theAjaxControlToolkit.dll.
You can find the latest AjaxControlToolkit.dll in the SampleWebSite/bin folder of the AjaxControlToolkit. The latest toolkit is available for download at[http://www.codeplex.com/AtlasControlToolkit/Release/ProjectReleases.aspx].
Figure 2
Creating the database for the project
Create a new database named SampleData.mdf. This database will contain 2 tables Cars (to store the cars data) and CarModels (to store the models for each car in Cars table).
Right click on the App_Data folder and select Add New Item. In the new item dialog box, select theSQL Database from the template and change the name to SampleData.mdf. Click Add.
Now the database is created and added to your project. You can view the data connection to theSampleData.mdf in the Server Explorer (Ctrl + W, L).
In the server explorer, under the SampleData.mdf, click on Tables and create 2 tables with the following structure.
Figure 3
Make the fields ModelId (CarModels) and CarId (Cars) as Identity columns for auto-increment number.
Note: The SampleData.mdf used in the project is available in the Source Code provided with this article.
Creating the datasets for accessing the Cars and CarModels data
Right click on the project in the solution explorer and click on Add New Item. In the dialog box select DataSet and name it as dsCars.xsd and click Add Button. Your dataset will be created underApp_Code folder under the root application folder.


Figure 4
As soon as the dataset was created, the TableAdapter Configuration Wizard pops up and you should configure the dataset using the wizard.
Configuring the DataSets
· From the data connection dropdownlist of the wizard, select the SampleData.mdf file and click Next.
Figure 5
· You are asked to save the SampleDataConnectionString in the web.config file. Check the box next to Yes and click Next.


Figure 6
· In the command type, choose Use SQL Statements and click Next.
· In the Enter a SQL Statement, enter the following query and click Next.
Figure 7
· In the Choose Methods to Generate, uncheck the Fill a DataTable and in the Return a DataTable Method name use GetAllCars.
Figure 8
· Wizard Results will be displayed with generated SELECT statement, table mappings and a Get method.
· Save the DataSet and Close it.
· Repeat the Creating DataSets again to add another dataset dsCarModels.xsd which holds data of CarModels for the selected Car.
Note: When creating the second dataset, you will not see the SampleData.mdf in the data connection dropdownlist of step 1. Since you have already stored the connection string in the web.config file, you will see SampleDataConnectionString (web.config) and you should select it.
· Use the following query in the Enter a SQL Statement of configuring the dataset.
SELECT ModelId, CarId, ModelName FROM CarModels WHERE (CarId = @carId)
Figure 9
· For the Return a DataTable Method name use GetModelsByCarId.
Figure 10
Creating a webservice to get data from database
Now we have the datasets configured, we write a webservice to get all the car models for a given CarId. This webservice will be used by our cascadingdropdown. Later in this article we will see how to configure the CascadingDropDown to use this webservice.
· Right Click on the project and click Add New. In the Add New Item dialog box, select WebService from the list and name it as CarsService.asmx.


Figure 11
· Two files will be created in your application. One file CarsService.asmx is created in the root of your application and the code-behind file for the webservice is created in the App_Code folder with name CarsService.cs.
Note: In Listing 11 the check box Place code in separate file is checked. Check the box for all the items you create for which it is applicable. This will separate the code file from the page file.
· Open the CarsService.cs location in the App_Code. This is the class file (WebService) where we write the web method to get all the car models for a given CarId.
· Add the following namespaces in bold to the existing file (CarsService.cs).
Listing 1
using System;
using System.Web;
using System.Collections;
using System.Web.Services;
using System.Web.Services.Protocols;
class=Bold>using System.Collections.Generic;
class=Bold>using AjaxControlToolkit;
class=Bold>using System.Data;
class=Bold>using System.Data.SqlClient;
· Your webservice should be decorated with the ScriptService attribute. Add the following line above the class definition.
Listing 2
///



/// Summary description for CarsService
///

[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.Web.Script.Services.ScriptService]
public class CarsService : System.Web.Services.WebService {
· We will write a WebMethod GetModelsByCarId which returns an array ofCascadingDropDownNameValue. The method signature should match exactly with the one given below including the parameter names.
Listing 3
[WebMethod]
public CascadingDropDownNameValue[] GetModelsByCarId(string knownCategoryValues, string category)
{
· The knowCategoryValues will contain the values of the Category defined in the CascadingDropDown control separated by “;” delimiter.
Listing 4
// Split the knownCategoryValues on ":" with ";" delimiter
// For the first dropdownlist, the values will be "undefined: id of the dropdownelement"
// ex: "undefined: 13;"
// The string at index 1 will be the CarId selected in the dropdownlist.
string[] _categoryValues = knownCategoryValues.Split(':', ';');
· By splitting the knowCategoryValues we will get the Id of the car selected in the dropdownlist at index 1 in the string[] _categoryValues
Listing 5
// Convert the element at index 1 in the string[] to get the CarId
int _carID = Convert.ToInt32(_categoryValues[1]);
· Create a generic List of type CascadingDropDownNameValue to hold the values returned by the CarsModelTableAdapters.
Listing
// Create a List of CascadingDropDownNameValue to hold the CarModels data
List _carModels = new List();
· Loop through all the DataRows in the DataTable returned by the GetModelsByCarId method and add them to the List of type CascadingDropDownNameValue.
Listing 7
// Create an instance of CarModels TableAdapter
dsCarModelsTableAdapters.CarModelsTableAdapter _carModelAdapter =
new dsCarModelsTableAdapters.CarModelsTableAdapter();
// For each datarow in the DataTable returned by the GetModelsByCarId method, add
// the modelname and modelid to the List
foreach (DataRow _row in _carModelAdapter.GetModelsByCarId(_carID)) {
_carModels.Add(new CascadingDropDownNameValue(_row["ModelName"].ToString(),
_row["ModelId"].ToString())); }
Note: The CascadingDropDown needs a CascadingDropDownNameValue[] to be displayed in the Target DropDownList.
Listing 8
// Web method to get all the car models for a given carId
// In params: knownCategoryValues from the cascading dropdown
// Out params: CascadingDropDownNameValue array
[WebMethod]
public CascadingDropDownNameValue[] GetModelsByCarId(string knownCategoryValues,
string category)
{
// Split the knownCategoryValues on ":" with ";" delimiter
// For the first dropdownlist, the values will be "undefined: id of the
// dropdownelement"
// ex: "undefined: 13;"
// The string at index 1 will be the CarId selected in the dropdownlist.
string[] _categoryValues = knownCategoryValues.Split(':', ';');
// Convert the element at index 1 in the string[] to get the CarId
int _carID = Convert.ToInt32(_categoryValues[1]);
// Create a List of CascadingDropDownNameValue to hold the CarModels
// data
List _carModels = new List();
// Create an instance of CarModels TableAdapter
dsCarModelsTableAdapters.CarModelsTableAdapter _carModelAdapter =
new dsCarModelsTableAdapters.CarModelsTableAdapter();
// For each datarow in the DataTable returned by the GetModelsByCarId
// method, add the modelname and modelid to the List
foreach (DataRow _row in _carModelAdapter.GetModelsByCarId(_carID))
{
_carModels.Add(new CascadingDropDownNameValue(_row["ModelName"].ToString(),
_row["ModelId"].ToString()));
}
// convert to array and return the vlaues
return _carModels.ToArray();
}
Designing your aspx page
Now we use the WebService and the CascadingDropDown in a page to display the Cars and CarModels.
· In the Default.aspx page add a reference to the AjaxControlToolkit.
Listing 9
<%@ Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="ajaxToolkit" %>
· On Default.aspx page, drag two DropDownList. Name them as ddlCars and ddlCarModels.
Listing 10
Car:<asp:DropDownList ID="ddlCars" runat="server" DataSourceID="ods_Cars"
DataTextField="CarName"
DataValueField="CarId"></asp:DropDownList>
Model:<asp:DropDownList ID="ddlCarModels" runat="server"></asp:DropDownList>
· Create an ObjectDataSource to display all the Cars available in the ddlCars dropdownlist. By default, all the cars available in Cars table will be shown when the page loads.
Listing 11
<asp:ObjectDataSource ID="ods_Cars" runat="server"
OldValuesParameterFormatString="original_{0}" SelectMethod="GetAllCars"
TypeName="dsCarsTableAdapters.CarsTableAdapter"></asp:ObjectDataSource>


· Add a CascadingDropDown control to the page and set the following properties.
Category = Cars [Category for the knowCategoryValues]
LoadingText = “Please wait..” [Message to be shown while the dropdownlist is loading]
ParentControlID = ddlCars [DropDownList from which the CategoryId should be taken (CarId in this example)]
PromptText=”Select a model” [Text to be displayed if a selection is not made]
TargetControlID = ddlCarModels [DropDownList into which the CascadingDropDownNameValue should be loaded]
ServicePath = “CarsService.asmx” [Path to the webservice]
ServiceMethod = “GetModelsByCarId” [WebMethod that should be called to get the values]
Listing 12
<ajaxToolkit:CascadingDropDown ID="CascadingDropDown1" runat="server"
Category="Cars" LoadingText="Please wait..." ParentControlID="ddlCars" PromptText="Select a model"
TargetControlID="ddlCarModels" ServicePath="CarsService.asmx"
ServiceMethod="GetModelsByCarId" />
Build the website (Ctrl + F6) and Run (F5). If you see the Enable Debug Dialog box, click Yes. The ASP.NET AJAX CascadingDropDown is in action getting values from the database.
Ok, so I finally began my journey towards web 2.0 programming yesterday with the Cascading Dropdownlist and thought I would share on how it works and hopefully help anyone having trouble using it! The example I am going to show will use a SQL database to get the values for the dropdown lists but the code should get you in the right direction regardless of the Data Access you choose.
First thing you need to do is disable EnableEventValidation in the page directive.
<%@ Page Language="C#" AutoEventWireup="true"
CodeFile="cascade.aspx.cs" Inherits="cascade"

EnableEventValidation="false" %>
After that we need to add a couple of ASP DropDownLists:









Now we need to add a ScriptManager and the CascadingDropDownList Control and point them to the dropdownlists, there are a few other properties of the Dropdown we need to set as well, but since we don't have a web service yet we will wait to add those properties until later. What's important here is that we are specifying which dropdownlist to control here with the TargetControlID property:







ID="CascadingDropDown1"

runat="server"

TargetControlID="DropDownList1">






ID="CascadingDropDown2"

runat="server"

TargetControlID="DropDownList2">



The next thing we need to do is create a Web Service that will provide data for our dropdownlists. For my service I created DataService.asmx with the codebehind file DataService.CS.
DataService.asmx only points to the CS file:
<%@ WebService Language="C#" CodeBehind="~/App_Code/DataService.cs"
Class="DataService" %>
The rest of the code goes into the CS file. The first thing to note is that the CascadingDropDown requires the method are as follows:
[WebMethod]
public CascadingDropDownNameValue[]

GetDropDownData(string knownCategoryValues, string category)
With the exception that you can call your method "GetDropDownData" anything you would like but the type and params must stay that way for the call to be made which makes getting your paramaters out of the call just a little tricky. Let's say our first DropDownList's category is department and the value for it is DeptID which equals 2.. Well calling the knownCategory string will return Department:2; now if there were two dropdownlists one with category Department and one with category Employee knowcategoryvalues would return Department:1;Employee:John; etc. Luckily they made it easy to access these values using a stringdictionary like you can see here:
StringDictionary kv =
CascadingDropDown.ParseKnownCategoryValuesString(
knownCategoryValues);
int DeptID;
if (!kv.ContainsKey("Department") ||
!Int32.TryParse(kv["Department"], out DeptID))
{
return null;
}
This example finds the entry with the key Department and then pulls out an int from it's value, so if our Catgory is Department and our value is 3 it would pull out a 3 which we can now use in our code to get the next list of items. If you wanted to just pull the value as a string you could change the code to look as so:
StringDictionary kv = CascadingDropDown.ParseKnownCategoryValuesString(
knownCategoryValues);
string DeptID = kv["Department"].ToString();
Either way it will pull the value. Ok, now that we have that out of the way let's look at the full code for our Web Service:
using System;
using System.Web;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Web.Services;
using System.Web.Services.Protocols;
using AjaxControlToolkit;
using System.Data;
using System.Data.SqlClient;
using System.Configuration;
///


/// Summary description for CarData
///

[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.Web.Script.Services.ScriptService()]

public class DataService : System.Web.Services.WebService
{
public DataService()
{
//Uncomment the following line if using designed components

//InitializeComponent();

}
[WebMethod]
public CascadingDropDownNameValue[]

GetDepartments(string knownCategoryValues, string category)
{
using (SqlConnection connection =

new SqlConnection(ConfigurationManager.ConnectionStrings["MyConnectionString"].ConnectionString))
{
using (SqlCommand command = new SqlCommand("GetDepartments", connection))
{
command.CommandType = CommandType.StoredProcedure;
connection.Open();
List values = new List();
using (SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
int id = (int)reader["DeptID"];
string Department = (string)reader["Department"];
values.Add(new CascadingDropDownNameValue(Department, Convert.ToString(id)));
}
}
return values.ToArray();
}
}
}
[WebMethod]
public CascadingDropDownNameValue[] GetEmployees(string knownCategoryValues, string category)
{
StringDictionary kv = CascadingDropDown.ParseKnownCategoryValuesString(
knownCategoryValues);
int DeptID;
if (!kv.ContainsKey("Department") ||
!Int32.TryParse(kv["Department"], out DeptID))
{
return null;
}
using (SqlConnection connection =
new SqlConnection(ConfigurationManager.ConnectionStrings["MyConnectionString"].ConnectionString))
{
using (SqlCommand command = new SqlCommand("GetEmployees", connection))
{
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add(new SqlParameter("@DeptID", Convert.ToString(DeptID)));
connection.Open();
List values = new List();
using (SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
int id = (int)reader["DeptID"];
string firstname = (string)reader["FirstName"];
values.Add(new CascadingDropDownNameValue(firstname, Convert.ToString(id)));
}
}
return values.ToArray();
}
}
}
}
At the top of the web service you will notice the namespace [System.Web.Script.Services.ScriptService()], without this you will only get errors, so make sure you place this in your web service! The Array returned also needs to be from CascadingDropDownNameValue so make sure when you create your array you use List values = new List(); and then populate the values!
Ok, now we can go back to your code and add our service path, service method, category and prompt text. Also in the second Dropdownlist we need to add a ParentControlID so it knows it will be updated by DropDownList1







ID="CascadingDropDown1"

runat="server"

TargetControlID="DropDownList1"

ServicePath="DataService.asmx"

ServiceMethod="GetDepartments"

Category="Department"

PromptText="pick Department">






ID="CascadingDropDown2"

runat="server"

TargetControlID="DropDownList2"

ServicePath="DataService.asmx"

ServiceMethod="GetEmployees"

ParentControlID="DropDownList1"

Category="Employee"

PromptText="pick employee">



Creating the Sample Application Using Visual Studio 2005, create a new Atlas application and name it as C:\CascadingDropDown. Drag and drop a CascadingDropDown control from the ToolBox onto the default.aspx page (see Figure 1).
Tip: The CascadingDropDown control is one of many controls available in the Atlas Control Toolkit, an extended library of Atlas controls developed by both Microsoft and community developers.
Next, insert a 2x2 table and populate it with two DropDownList controls as shown in Figure 1).
Figure 1. Sample Application Form: Here's how the default.aspx page should look after you place the controls
Switch to Source View and add two CascadingDropDownProperties elements, shown in bold in the following code:
runat="server">
Category="Author"
TargetControlID="DropDownList1"
ServiceMethod="GetAuthors"
ServicePath="WebService.asmx"
PromptText="Please select an author" />
Category="Title"
TargetControlID="DropDownList2"
ParentControlID="DropDownList1"
ServiceMethod="GetTitles"
ServicePath="WebService.asmx"
PromptText="Please select a title" />

Authors



ID="DropDownList1" runat="server" Width="215px">


Titles



runat="server" Width="392px">



The CascadingDropDownProperties element associates the CascadingDropDown control with a DropDownList control. Here's a brief explanation of the attributes for the element:
  • Category—indicates the name of the category the DropDownList represents; more on this later.
  • TargetControlID—specifies the control you are extending.
  • ParentControlID—specifies the control that affects the content of the control as indicated in the TargetControlID attribute; this attribute is optional.
  • ServiceMethod—specifies the name of the Web method that returns the list of values for the DropDownList control; you will define this later.
  • ServicePath—specifies the name of the Web service .asmx file containing the Web method specified in the ServiceMethod attribute.
  • PromptText—the text to display when no values are selected in the control.
Implementing Cascading DropDownList in ASP.NET GridView
I wrote this article sometime ago in response to a query asked by a dotnetcurry.com viewer. The user had a requirement where he had two dropdownlist in the GridView and the second one was to be populated at runtime based on the selected value of the first dropdownlist – A case of cascading dropdownlists.
Here’s an approach I followed without using a single line of code. We will be using the Categories and Products table of the Northwind database to show the cascading effect.
Viewers, who have prior experience in configuring the SqlDataSource, can jump directly to Step 5:
Step 1: Open VS 2008. Click File > New > Website. Choose ASP.NET Website from the list of installed template, choose target platform as .NET Framework 3.5, choose the desired language and enter the location where you would like to store the website on your FileSystem. I have created a folder called VS2008 Projects, so the location over here is C:\VS2008 Projects\ CascadingDropDownInGridView. After typing the location, click OK.
Step 2: Open Default.aspx. Switch to the Design mode of Default.aspx. Open the toolbox (Ctrl+Alt+X) > Data Tab > Drag and drop a SqlDataSource control on to the form. Click on the smart tag or right click SqlDataSource > Show Smart Tag > ‘Configure Data Source’ wizard. Click on ‘New Connection’ to open the ‘Add Connection’. Type your ‘Server Name’ and ‘Select a database Name’ to connect to. Over here, I have used (local) as the ‘ServerName’ and the database I am connecting to, is Northwind. Click on ‘Test Connection’ to make sure that there are no errors while connecting to the server. Click Ok.
Step 3: In the ‘Configure Data Source’, click ‘Next’. An option will be displayed to save the connection string to the configuration file. Select the checkbox ‘Yes, save this connection as:’, type a name for the connectionstring ‘NorthwindConnectionString’ and click Next.
Step 4: In the ‘Configure Select Statement’ > select ‘Specify Columns from Tables or Views’ radiobutton > Select ‘Categories’ table in the Name and choose CategoryID, CateogoryName as columns. Click Next > ‘Test Query’ to preview data > click Finish. The wizard adds a SqlDataSource control to the page as shown below.
<asp:SqlDataSource ID="SqlDataSource1" runat="server"
ConnectionString="<%$ ConnectionStrings:NorthwindConnectionString %>"
SelectCommand="SELECT [CategoryID], [CategoryName] FROM [Categories]">
</asp:SqlDataSource>
If you check your web.config, the connection string is added as shown below:
<connectionStrings>
<add name="NorthwindConnectionString" connectionString="Data Source=(local);Initial Catalog=Northwind;Integrated Security=True" providerName="System.Data.SqlClient"/>
</connectionStrings>
Step 5: Now add a GridView control to the page. We will add a BoundField and a TemplateField to display the CategoryID and CategoryName’s respectively. The TemplateField will contain our first dropdownlist displaying CategoryNames.
<form id="form1" runat="server">
<div>
<asp:SqlDataSource ID="SqlDataSource1" runat="server"
ConnectionString="<%$ ConnectionStrings:NorthwindConnectionString %>"
SelectCommand="SELECT [CategoryID], [CategoryName] FROM [Categories]">
</asp:SqlDataSource>
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
DataKeyNames="CategoryID" DataSourceID="SqlDataSource1">
<Columns>
<asp:BoundField DataField="CategoryID" HeaderText="CategoryID"
InsertVisible="False" ReadOnly="True" SortExpression="CategoryID" />
<asp:TemplateField HeaderText="Categories">
<ItemTemplate>
<asp:DropDownList ID="ddlCategories" AutoPostBack="true"
DataTextField="CategoryName" DataValueField="CategoryID"
DataSourceID="SqlDataSource1" runat="server" AppendDataBoundItems="true"
SelectedValue='<%# Bind("CategoryID") %>' />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</div>
</form>
Note: The SelectedValue='<%# Bind("CategoryID") %>' helps us select the CategoryName in the dropdownlist in accordance with the CategoryID, when the page is first loaded.
Step 6: So far so good. We now have to add the second dropdownlist whose values will be determined at runtime depending on the value selected in the first dropdownlist. In our case, when the user will select CategoryName in the first dropdown, corresponding Products will be displayed in the second dropdown.
Add another Template Field (with a second dropdownlist) in the GridView as well as one more SqlDataSource. This time the SqlDataSource2 will be bound to the ‘Products’ table. Moreover, the ‘SelectCommand’ of the SqlDataSource will accept a parameter, which will be the selected category. Let us see the markup for the same:
<asp:TemplateField HeaderText="Products">
<ItemTemplate>
<asp:DropDownList ID="ddlProducts"
DataTextField="ProductName" DataValueField="ProductID"
DataSourceID="SqlDataSource2" runat="server" />
<asp:SqlDataSource runat="server" ID="sqlDataSource2"
ConnectionString="<%$ ConnectionStrings:NorthwindConnectionString %>"
SelectCommand="SELECT [ProductID], [ProductName], CategoryID FROM [Products]"FilterExpression="CategoryID = '{0}'">
<FilterParameters>
<asp:ControlParameter Name="categoryParam" ControlID="ddlCategories"
PropertyName="SelectedValue" />
</FilterParameters>
</asp:SqlDataSource>
</ItemTemplate>
</asp:TemplateField>
Notice the element used as a child of the SqlDataSource2. This element is worth observing over here. The is a very handy feature of the SqlDataSource control especially when you have a requirement of filtering the results of a query based on a value that is known only at run time. So without making another roundtrip to the server, you can filter out the data that is made available by the SqlDataSource. All you have to do is to create filter expressions that contains parameter placeholders. So for each filter parameter placeholder, you use a parameter element.
In our case, we have created a filter parameter that gets its value from a DropDownList control.
Well that’s all the markup that is required to create cascading dropdownlist in a gridview. Run the application and you can now test the functionality of populating the second dropdownlist based on the selected value of the first dropdownlist. The application will look similar to the image below:
Cascading DDL
The entire markup is as shown below:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Cascading DropDownList In GridView</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:SqlDataSource ID="SqlDataSource1" runat="server"
ConnectionString="<%$ ConnectionStrings:NorthwindConnectionString %>"
SelectCommand="SELECT [CategoryID], [CategoryName] FROM [Categories]">
</asp:SqlDataSource>
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
DataKeyNames="CategoryID" DataSourceID="SqlDataSource1">
<Columns>
<asp:BoundField DataField="CategoryID" HeaderText="CategoryID"
InsertVisible="False" ReadOnly="True" SortExpression="CategoryID" />
<asp:TemplateField HeaderText="Categories">
<ItemTemplate>
<asp:DropDownList ID="ddlCategories" AutoPostBack="true"
DataTextField="CategoryName" DataValueField="CategoryID"
DataSourceID="SqlDataSource1" runat="server" AppendDataBoundItems="true"
SelectedValue='<%# Bind("CategoryID") %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Products">
<ItemTemplate>
<asp:DropDownList ID="ddlProducts"
DataTextField="ProductName" DataValueField="ProductID"
DataSourceID="SqlDataSource2" runat="server" />
<asp:SqlDataSource runat="server" ID="sqlDataSource2"
ConnectionString="<%$ ConnectionStrings:NorthwindConnectionString %>"
SelectCommand="SELECT [ProductID], [ProductName], CategoryID FROM [Products]"
FilterExpression="CategoryID = '{0}'">
<FilterParameters>
<asp:ControlParameter Name="categoryParam" ControlID="ddlCategories"
PropertyName="SelectedValue" />
</FilterParameters>
</asp:SqlDataSource>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</div>
</form>
</body>
</html>


CollapsiblePanelExtender

CollapsiblePanel Extender Properties

CollapseControlID: ID of the Panel Control that will perform the collapse action.
ExpandControlID: ID of the Panel Control that will perform the expand action.
You can set the same ID for both CollapseControlID and ExpandControlID so that expand/collapse action should be performed by the single Panel Control.
TargetControlID: ID of the Panel control that will operate the expand/collapse actions.
TextLabelID: ID of the Label control that will display the current status of the extender.
CollapsedText: Text to display the status of Panel when it is in the collapsed state. This text is displayed in Label control associated in the TextLabelID property.
ExpandedText: Text to display the status of Panel when it is in expanded mode.
Collapsed: If true then initializes the CollapsiblePanel with collapsed state.
ExpandDirection: You can specify the direction for the Panel whether it expands/collapse in vertical direction or horizontal direction.
CollapsedSize: Initial size of the Panel that will perform the expand/collapse action when it is in collapsed mode.
ExpandedSize: Initial size of the Panel that will perform the expand/collapse action when it is in expanded mode.
ScrollContents: If the expand size specified is less than the size of content inside the expand/collapse Panel then you can set this property true to allow scrolling.
AutoExpand/AutoCollapse: To allow the functionality of auto expand and collapse on mouse over event.
ImageControlID: ID of the image control that will display the image related to the status of CollapsiblePanel extender.
CollapsedImage: Path of the image to be displayed when the extender is in collapsed mode.
ExpandedImage: Path of the image to be displayed when the CollapsiblePanel is in expanded mode.

Sample Code for CollapsiblePanel Control Extender

CSS code
HTML code



Panel1






Panel2



Some text Some text Some text Some text Some text Some text Some text Some text
Some text Some text Some text Some text Some text Some text Some text Some text
Some text Some text Some text Some text Some text Some text Some text Some text

ID="CollapsiblePanelExtender1"
runat="server"
CollapseControlID="Panel1"
Collapsed="true"
ExpandControlID="Panel1"
TextLabelID="Label1"
CollapsedText="Show"
ExpandedText="Hide"
ExpandDirection="Vertical"
TargetControlID="Panel2"
ScrollContents="false">

Introduction
If you wanted to have a formatted text sensitive area that you can format as you like, it will not be a simple hyperlink. In addition, that text sensitive area should be able to expand and collapse dynamically with nice visual effects. You are speaking about a CollapsiblePanel that I am going to explain in this article.
About the control
Enriching your web page with AJAX has never been easier. It is as simple as adding one control and specifying some properties. Please note that we are only dealing with an extender and we always need a panel to complete the extender. Want to know how to do this? Then proceed with ensuring you have the requirements.
Requirements
In order to be able to work with ASP.NET AJAX Control Toolkit, the following should be available:
· Microsoft Visual Studio 2005 (any version) or you can also use the free of cost Visual Web Developer Express 2005
· Download ASP.NET 2.0 AJAX Extensions and install them on your computer after installing Visual studio 2005.
· Download ASP.NET AJAX Control Toolkit and install it on your computer after installing Visual studio 2005 and AJAX Extensions. You can also download the Toolkit directly from CodePlex project site.
· After the completion of installation, open Visual Studio 2005 or Visual Web Developer and add a tab in the Toolbox named AJAX Toolkit.
· Right Click in this tab and choose add items. Browse to the sample directory of where you did extract the Toolkit, then to bin directory and choose the file named AjaxControlToolkit.dll.
· This is all. You have installed AJAX Control Toolkit and you can start building your controls.
Creating Your CollapsiblePanel Sample Solution
Follow the easy steps below to create your solution.
1. Start your Visual Studio 2005 IDE.
2. Choose Create Web Site from the menu.
3. In this sample application we will use the Visual Basic language for the sample application.
4. Name the solution CollapsiblePanelSample.
5. Choose ASP.NET AJAX Control Toolkit Web Site.
6. Choose File System in the location box.
7. Click ok to create the project.
8. Visual Studio will create your project with a Default.aspx page and most likely a readme.txt. Go ahead and get rid of the latter file.
9. Open Default.aspx page in design view.
10. You noticed that there is a control on the page already called script manager. (Well, AJAX is really a script based implementation of the language JavaScript). In short, ScriptManager Control manages client script for Microsoft ASP.NET AJAX pages. By default, the Script Manager control registers the script for the Microsoft AJAX Library with the page. This enables client script to use the type system extensions and to support features such as partial-page rendering and Web-service calls.
11. Now you have to fill your page with some text. In order to do so, take Listing 1 and copy and paste it many times inside the div tag within the default.aspx page when in source mode.
12. Create a new item in the solution of type Style Sheet and leave the default name.
13. Listing 1 contains the style sheet content that should be placed inside the file. You can copy and paste directly.
Listing 1- Style Sheet Content for our example
.collapsePanel {
      width: 640px;
      height:0px;
      background-color:white;
      overflow:hidden;
}
 
.collapsePanelHeader{   
      width:640px;            
      height:20px;
      color: Yellow;
      background-color: Black;
      font-weight:bold;
      float:none;
      padding:5px; 
      cursor: pointer; 
      vertical-align: middle;
}
14. Go to the source mode, and click and drop the style sheet file into the header section of the default web form in order to be able to reference it.
15. Now, drag two panels from the standard toolbox and drop them on the page.
16. Name the first panel PnlTitle and delete the height and width specs then create a CssClass tag with value collapsePanelHeader like in listing 2.
Listing 2- Title Panel and Content Panel Format
<asp:Panel ID="PnlTitle" runat="server" CssClass="collapsePanelHeader">
<asp:Panel ID="PnlContent" runat="server" CssClass="collapsePanel">
17. Name the second panel PnlContent and delete the height and width specs then create a CssClass tag with value collapsePanel like in the above listing.
18. In the title panel add an asp image standard control (it is necessary to use the image asp control in order to be able to control it afterwards). Make the image url point to an image that you create with a down arrow (call the image collapse_blue.jpg to be able to use it later). Also, create another image with an up arrow (call the image expand_blue.jpg to be able to use it later).
19. After the image control, add a text in bold that says: Who Am I?
20. Now drag a label and make the text tag Show Details (…)
21. Please fill the content panel with some information about yourself in any html format.
22. Place the cursor after the script manager html end tag. From the Toolbox drag a Collapsible Panel control and set the properties as specified in Listing 3.
Listing 3- Collapsible Panel Extender specs
<ajaxToolkit:CollapsiblePanelExtender ID="CollapsiblePanelExtender1" 
    runat="server" TargetControlID="PnlContent" ExpandControlID="PnlTitle" 
    CollapseControlID="PnlTitle" TextLabelID="Label1" 
    CollapsedText="Show Details (...)" ExpandedText="Hide Details (...)" 
    ImageControlID="Image1" ExpandedImage="images/collapse_blue.jpg" 
    CollapsedImage="images/expand_blue.jpg"
    Collapsed="True" SuppressPostBack="true">
</ajaxToolkit:CollapsiblePanelExtender>
23. Please note that some of these properties cannot be specified using the normal properties window. The target control ID specifies the control to collapse and extend (the content panel in our case).
24. The Expand Control ID specifies the control that is going to control the expansion (the title panel in our case).
25. The Collapse Control ID specifies the control that is going to collapse the panel (the title panel in our case).
26. Please note that you can specify two different controls to collapse and expand.
27. The Text Label ID specifies that label that is going change its text caption when the user collapses or expands the panel.
28. The same description applies the Image Control ID, but the image is going to change.
29. The Collapsed Text tag specifies the text that should appear when the panel is collapsed.
30. The Expanded Text tag specifies the text that should appear when the panel is extended.
31. The Expanded Image tag specifies the image to display when the panel is expanded.
32. The Collapsed Image tag specifies the image to display when the panel is collapsed.
33. The Collapsed tag specifies the state of the content panel when the page loads.
34. The Suppress Post Back tag specifies that when expanding the panel, there should be no posting to the server or not. In our case and since our content is fixed and not changing, we did set this property to true.


ColorPickerExtender

Introduction

Color Picker is an ASP.NET AJAX extender that can be attached to any ASP.NET TextBox control. It provides client-side color-picking functionality with UI in a popup block. You can interact with the Color Picker by clicking on a colored area to set a color. It's built on top of ASP.NET AJAX and the AJAX Control Toolkit library.

Why the Color Picker Extender?

It is not that easy to find a decent color picker control for ASP.NET. There are a number of pure JavaScript color picker controls out there, but just a few of them leverage the ASP.NET server side model. If however you strict your requirements even further, and decide that you want to use ASP.NET AJAX and the AJAX Control Toolkit, then finding such a color picker would be much more challenging for you. So, the reason of this work is to overcome this challenge and provide the developers' community with an easy to use standard open source solution.

What's Special About the Color Picker Extender?

  1. Color Picker is built on top of ASP.NET AJAX and the AJAX Control Toolkit, which makes it a natural choice for those using those frameworks.
  2. Color Picker is not a standalone server control, but an AJAX extender to a standard TextBox ASP.NET server control, which makes it very easy to use.
  3. Color Picker extender is multi-browser compatible: it works with IE 6/7, Firefox, Safari, and Goggle Chrome, which makes it totally suitable for Web 2.0 solutions.
  4. Color Picker is compatible with the UpdatePanel: can be placed inside the UpdatePanel, which makes it useful for both client-side and server-side, scenarios.

Usage Example

The Color Picker extender is extremely easy to use. First of all, there is no need to manipulate the HTML or JavaScript code at all: everything is done on an ASP.NET page via regular mark-up.
First, register the Color Picker assembly either on an ASP.NET page or in a Web.config file:
Page:
Collapse
<%@ Register TagPrefix="cdt" Assembly="CDT.ColorPickerExtender" Namespace="CDT" %>
Web.config:
Collapse
<add tagprefix="cdt" namespace="CDT" assembly="CDT.ColorPickerExtender" />
Then, add a ColorPicker tag on the page and assign its properties to the corresponding values:
Collapse
   <asp:textbox id="TextBox1" runat="server" columns="7" maxlength="7" />
   <asp:imagebutton id="ImageButton1" runat="server" 
      imageurl="~/Images/icon_colorpicker.gif" />
   <cdt:colorpickerextender id="cpe" runat="server"
         targetcontrolid="TextBox1"
         samplecontrolid="ImageButton1"
         popupbuttonid="ImageButton1" />