The AJAX Control Toolkit : Controls in the ACT

10/10/2010 11:32:48 AM
Along with all the extenders listed in Table 1, the ACT also supplies a few traditional server controls with rich capabilities: the Accordion, Rating, ReorderList, and TabContainer controls.

The Accordion control allows you to provide multiple collapsible panes and display only one at a time. When the user clicks a new pane, the currently displayed pane is collapsed to leave room for the new one.

The Rating control provides an intuitive user interface to let users select the number of stars that represents their rating of a given subject. The control is the wrapped-up version of the user interface that several Web sites provide to let users rate published items.

A data-bound control, ReorderList, allows its child elements to be reordered on the client using drag-and-drop functionality. To move an item in the list, the user drags the item’s handle up to its new position. At the end of the operation, the control posts back so that the new status of the data source can be recorded.

Finally, the TabContainer control is a purely client-side container of tabbed forms.

You use any of these controls in the same way you would use any native ASP.NET server controls.

Improving the User Interface with Input Extenders

In a perfect world where architects design applications in strict accordance with requirements and keeping the user’s satisfaction in mind, each logical data type features its own set of input controls. In general, money, days of the week, ages, and quantities are all data represented with numbers. However, each of these logical data types might need a different user interface. The same can be said for URLs, paths, IP addresses, and dates.

Both in Windows and the Web, user interfaces are built by composing controls together. The original toolbox of controls, though, is not particularly rich in either Windows/WPF or ASP.NET. Input controls for Windows Forms are still based on the original windows in Win32. Input controls for Web pages are little more than wrappers for the HTML <input> element.

The need for effective input controls is even higher today, now that AJAX is taking root. The more work a page can do on the client, the better the overall experience is for the user. The user experience is widely improved because of saved postbacks but also because of the increased interactivity, dynamic data formatting, and validation that ad hoc input components can guarantee. As a result, input controls should be more interactive than ever. ACT extenders can help a lot.

Motivation for Input Facilities

As mentioned, in HTML there’s one primary element for accepting data—the <input> element. You use it for numbers, strings, dates, currency values, and so forth. So what if you need numeric input to be restricted to a specific range of values?

You can leave the user free of typing any values and then enforce this business rule through a server-side validation layer. Although server-side validation shouldn’t be avoided (for the safety of data), it would be even better if you could start yelling at wrong data as it’s entered into the input box.

JavaScript code is required to check values and ensure they comply with expected types and formats. In some cases, a specialized user interface also is required to make the user feel more comfortable. Here’s where some ad hoc input extenders fit in. Let’s start with the Slider and NumericUpDown extenders. Both force users to enter only numbers that fall in a given range.

The Slider Extender

The Slider extender hides its associated TextBox and replaces it with a graphical slider moving through discrete steps within a minimum and maximum interval. The underlying TextBox can always be set programmatically to any value you want. Note, though, that the assigned value must be compatible with the numeric range set via the slider; otherwise, the slider will silently fix it. Let’s consider the following example:

<act:SliderExtender runat="server" ID="SliderExtender1"
BoundControlID="lblIncomeAsText" />

The slider applies to a TextBox control named txtYourIncome and ensures it is visually assigned a value in the range 0 through 200,000. The Steps property indicates how many discrete steps should be provided. The preceding setting lets the slider jump by 5000 every time.


Why is Steps is set to a weird 41 value, when a value of 40 would have probably looked better? Correctly, 40 is what you get by dividing 200,000 by 5000. However, the property Steps counts the number of steps ranging from 0 to 200000. You have to add one more tick to be able to select 0 first and then values every 5000.

If you programmatically set the slider on the server, the value is first converted to a number and then mapped to the nearest step value. If you pass in a string (that is, not a number), the slider ignores it and defaults to the initial value of the range. If you set the value of the underlying text box on the client via JavaScript, the value is correctly recognized over the next postback, but it is not immediately reflected by the user interface. To programmatically change the value in the slider from within the client, use the following code:


Why should you opt for $find instead of $get? As mentioned, the $get function is shorthand for document.getElementById and looks only for DOM elements. The $find function stands for Sys.Application.findComponent and applies to any component of the Microsoft AJAX Library that has been programmatically created.

The BoundControlID property refers to a DOM element that dynamically displays the current slider value. In most cases, you’ll use a <span> tag or a Label control for this purpose. Internally, the slider distinguishes between <input> and any other HTML elements. It sets the value property in the former case; otherwise, it uses the innerHTML property of the matching DOM element.


The slider script hides the underlying TextBox. For this reason, it is recommended that you hide the text box declaratively using CSS styles to avoid any flashing when the page loads up. Finally, be aware that regular text boxes are displayed inline, whereas slider boxes are positioned through blocks.

Figure 1 shows a few input extenders in action in a sample page.

Figure 1. Input extenders in action

The NumericUpDown Extender

The NumericUpDown extender selects the next/previous value in a bound list of possible values. Despite what the name implies, NumericUpDown is not just a tool for specifying numeric quantities. The RefValues property allows you to list values to move through:

<act:NumericUpDownExtender ID="UpDown1" runat="server"
RefValues="None;1;2;3;4;5;More than 5;"
TargetControlID="Children" />

NumericUpDown has the ability to retrieve reference values from a remote service. The service is invoked asynchronously each time the user clicks the up or down buttons. The service must be script-callable and include methods with the following signature:

public int YourMethod(int current, string tag)

You configure the extender to use the remote service through the ServiceDownPath, ServiceDownMethod, ServiceUpPath, and ServiceUpMethod properties. Finally, the up and down buttons don’t have to be auto-generated via script. They can be buttons already defined in the page and referenced through the TargetButtonDownID and TargetButtonUpID properties.

The FilteredTextBox Extender

Preventing user mistakes involves controlling the input by filtering out undesired characters, invalid expressions, or data of the wrong type. Using the standard TextBox control, you enforce proper input by validating it on the server, where you can check whether the input string can be converted to a given data type. Extenders simply save you from writing the JavaScript code required to make checks on the client.

The FilteredTextBox extender prevents a user from entering invalid characters into a text box. It basically adds JavaScript that hooks up the keyboard activity and filters out undesired keystrokes. You can configure the extender to refuse certain characters or to ensure that only specified characters are accepted. You use the FilterMode property for this setting: it accepts only ValidChars and InvalidChars as its value:

<act:FilteredTextBoxExtender ID="Filtered1" runat="server"
FilterType="Numbers" />

The FilterType property determines the type of filter to apply—only numbers, only lowercase or uppercase, and a custom set of characters. It should be noted that a TextBox with a watermark can’t be filtered to accept numeric values only. The filter layer, in fact, automatically clears any watermark text you set.

The Calendar Extender

Using the calendar extender, you make it virtually impossible for users to type anything other than a date. ASP.NET comes with a server Calendar control, but a calendar extender is really different, as it builds its user interface entirely on the client, works entirely on the client, and generates no postbacks at all as the user navigates to find the month and day. Furthermore, if a given browser doesn’t support JavaScript, the old text box is displayed.

<act:CalendarExtender ID="CalendarExtender1" runat="server"
Format="dd/MM/yyyy" />

The preceding code snippet is sufficient to display a popup calendar as the associated text box receives the focus. As an alternative, you can display the popup when the user clicks a page button. The ID of the button is set through the PopupButtonID property. The Format property indicates the format of the date as it will be written to the text box when the user dismisses the calendar popup. (See Figure 2.)

Figure 2. The Calendar extender in action

The Calendar extender is good for date-picking functionality; it is not as good for real calendaring functionality.

The MaskedEdit Extender

Would you really use the Calendar extender to pick a date that represents a birth date? It is an option and, all in all, it is one of the best options you have. But it is not the perfect choice. Why is that so? A date that represents a birth date would reasonably require you to navigate a few years back to find the right day. A popup calendar is great to pick close dates; it loses part of its appeal as it is employed to pick up just any date. To some extent, we’re back to square one—using a text box to have users enter a date. This raises a number of new issues—involving formatting, locales, and separators.

When we start reasoning about data formatting and locales, Date is not the only critical data type. Currency, numbers, special strings such as URLs, disk paths, phone numbers, and e-mail addresses are all great examples of data types for which a specialized and masked input field is desirable. In ASP.NET, the MaskedEditTextBox control allows you to control input in a number of common scenarios. extender is a component that when attached to a

You can use the MaskedEdit extender to enter numbers, dates, times, and date/times. The extender decides its output based on given culture settings. The following code snippet shows the typical way to use the extender with a text box that accepts a date:

<asp:TextBox runat="server" ID="TextBox1" />
<act:MaskedEditExtender ID="MaskedEditExtender1" runat="server"
MaskType="Date" />

You define an input mainly through two properties: Mask and MaskType. The full list of properties is shown in Table 2.

Table 2. Properties of the MaskedEdit Extender
AcceptAMPMFalseBoolean property, indicates whether an AM/PM symbol should be used when representing a time.
AcceptNegativeNoneIndicates whether a negative sign (-) is required for negative values. Feasible values come from the MaskedEditShowSymbol enumeration: None, Left, Right.
AutoCompleteTrueBoolean property, indicates whether empty mask characters not specified by the user must be automatically filled in.
AutoCompleteValue“”Indicates the default character to use when AutoComplete is enabled.
Century1900Indicates the century to use when a date mask has only two digits for the year.
ClearMaskOnLostFocusTrueBoolean property, indicates whether to remove the mask when the TextBox loses the input focus.
ClearTextOnInvalidFalseBoolean property, indicates whether to clear the TextBox when the user has entered invalid text.
ClipboardEnabledTrueBoolean property, indicates whether to allow copy/paste with the clipboard.
ClipboardText“”Indicates the prompt text to use when a clipboard paste is performed.
CultureName“”Gets and sets the name of the culture to use.
DisplayMoneyNoneIndicates whether the currency symbol is displayed. Feasible values come from the MaskedEditShowSymbol enumeration: None, Left, Right.
ErrorTooltipCssClass“”Gets and sets the CSS class for the ToolTip message.
ErrorTooltipEnabledFalseBoolean property, indicates whether to show a ToolTip message when the mouse hovers over a TextBox with invalid content.
Filtered“”Gets and sets the list of valid characters for the mask type when the “C” placeholder is specified
InputDirectionLeftToRightIndicates the text input direction. Feasible values come from the MaskedEditInputDirectionLeftToRight, RightToLeft. enumeration:
Mask“”Specifies the mask of characters that is acceptable to the extender.
MaskType“”Indicates the mask type using any of the values defined by the MaskedEditType enumeration.
MessageValidatorTipTrueBoolean property, indicates whether a help message is displayed as the user types in the TextBox.
OnBlurCssNegative“”Gets and sets the CSS class used when the TextBox loses the input focus and contains a negative value.
OnFocusCssClass“”Gets and sets the CSS class used when the TextBox receives the input focus.
OnFocusCssNegative“”Gets and sets the CSS class used when the TextBox gets the input focus and contains a negative value.
OnInvalidCssClass“”Gets and sets the CSS class used when the text is not valid.
PromptCharacter_Gets and sets the prompt character being used for unspecified mask characters
UserDateFormatNoneIndicates a particular date format. Feasible values are defined by the MaskedEditUserDateFormat enumeration.
UserTimeFormatNoneIndicates a particular time format. Feasible values are defined by the MaskedEditUserTimeFormat enumeration.

The MaskType property selects a general pattern from a predefined list—the MaskedEditType enumeration:

public enum MaskedEditType

By selecting a mask type, you inform the extender that the target control is going to accept a number, a date, a time, or both. The Mask property (of string type) indicates the physical sequence of characters that form a valid input for the text box. For example, “5/4/08” and “04-05-2008” are both valid dates, but they use different input masks.

To build a mask, you use a few predefined symbols as placeholders. The list of supported symbols is in Table 3. For example, the “999,999.99” mask makes your code accept a number with a decimal separator and, at most, a one thousand separator.

Table 3. Symbols Supported by the MaskedEdit Extender
9Indicates a numeric character
LIndicates a letter
$Indicates a letter or a blank
CIndicates a custom case-sensitive character as defined by the Filtered property
AIndicates a letter or a custom character as defined by the Filtered property
NIndicates a numeric or custom character as defined by the Filtered property
?Indicates any character
/Indicates a date separator according to the current culture
:Indicates a time separator according to the current culture
.Indicates a decimal separator according to the current culture
,Indicates a thousand separator according to the current culture
\Indicates an escape character
{Indicates the initial delimiter for repetition of masks
}Indicates the final delimiter for repetition of masks

The appearance of the currency symbol is controlled by the DisplayMoney property, and each character to type is represented by a prompt. The default prompt is the underscore, but you can change it via the PromptCharacter property.

For dates, you can also use extra properties such as AcceptAMPM, Century, and even a custom user format in addition to the predefined formats defined by the MaskedEditUserDateFormat enumeration:

public enum MaskedEditUserDateFormat

Many of the settings that influence the formatting applied by the MaskedEdit extender descend from the current culture. The CultureName property indicates the culture to apply. Note that this setting overrides the culture setting defined for the page through the UICulture attribute in the @Page directive.

While the masked extender provides dynamic formatting capabilities, an additional component—the masked validator—ensures that any text typed can be successfully parsed back to the expected type:

<act:MaskedEditValidator ID="MaskedEditValidator1" runat="server"
EmptyValueMessage="Number is required "
InvalidValueMessage="Number is invalid" />

The MaskedEditValidator control is a custom validator that you optionally attach to the MaskedEdit extender so that the content of the edited TextBox is carefully verified. The validator ensures that the text matches the mask. The validator performs server and client validation, and it can be associated with a validation group, just like any other ASP.NET validator control.

The Text property of a masked TextBox returns formatted text. For a date, the property returns something like “05/04/2008”; for a number input field, the property returns text like “3,500.00”. The currency symbol is not included in the Text property, even though it is shown to the user in the page.

How can you parse the value returned by Text into the logical data type—be it a date or a decimal? You can use the static Parse method on the DateTime and Decimal types, but you must pay due attention to the culture you use. For example, “05/04/2008” can be either the 4th of May (US culture) or the 5th of April (European culture).

The issue is that there’s no guaranteed matching between the culture used by the input page and the server page. The risk is that users type the date according to the European culture and have it processed on the server as a US culture data. Worse yet, the 3500 value entered using, say, Italian decimal and thousand separators in a numeric text box (“3.500,00”) might throw an exception because the parser of the Decimal type defaults to the US culture where commas and the dot are reversed. You have to work around these issues programmatically.

The key fact to remember is that extenders default to the en-us culture unless the CultureName property is explicitly set. On the server, instead, the system defaults to the value of the UICulture property on the Page class. In your code-behind class, you first obtain a CultureInfo object that reflects the culture used for the user interface of the MaskedEdit extender. You can proceed as shown here:

string culture = "en-us";
if (!String.IsNullOrEmpty(MaskedEditExtender1.CultureName))
culture = MaskedEditExtender1.CultureName;
CultureInfo info = new CultureInfo(culture);

Next, you call the Parse method, specifying a format provider based on the selected culture:

NumberFormatInfo numberInfo = info.NumberFormat;
DateTimeFormatInfo dateInfo = info.DateTimeFormat;
DateTime when = DateTime.Parse(txtBirthDate.Text, dateInfo);
decimal amount = Decimal.Parse(txtAmount.Text, numberInfo);

Figure 3 shows the behavior of a page that uses the it-IT culture in the masked editor but an en-US culture on the server. The preceding code snippet performs the trick of transforming dates correctly.

Figure 3. The MaskedEdit extender in action

The AutoComplete Extender

Auto-completion consists of the program’s ability to predict the word the user is typing from the first few characters he or she has just entered. In Internet Explorer, for example, auto-completion keeps track of any text you type in the address bar and form fields and offers suggestions whenever you’re typing again in a similar control. This feature is entirely browser-led and can just be turned on and off for <input> and <form> tags by setting the autocomplete attribute to off. Note, though, that the autocomplete attribute is not a standard HTML attribute, although today nearly all browsers do recognize and support it.

The AutoComplete extender in the ACT provides a similar behavior for TextBox controls, but it makes the developer responsible for all the logic that provides possible words to the user. The extender creates a drop-down panel, much like a drop-down list, and positions it right at the bottom of the text box. Here’s how to associate an auto-complete extender with a text box:

<act:AutoCompleteExtender runat="server" ID="AutoComplete1"
ServiceMethod="GetSuggestions" />

The extender is bound to a Web service or WCF service that actually provides the words to populate the drop-down list. The MinimumPrefixLength property instructs the control when to place a call to the Web service—for example, only when the user has typed at least the specified number of characters. The text already typed in will be used as input for the specified Web service method. The response is used to populate the drop-down list.

The EnableCaching Boolean property can also be turned on. If you do so, typing the same prefix more than once results in a single call to the Web service. Furthermore, depending on the way the Web service retrieves its data, you also can enable caching on the server to save some extra roundtrips to a database or another remote data store. Table 4 shows the full list of properties supported by the extender.

Table 4. Properties of the AutoComplete Extender
AnimationsSets animations to be played when the flyout is shown and hidden.
CompletionIntervalGets and sets the number of milliseconds after which the extender gets suggestions using the bound Web service.
CompletionListCssClassIndicates the CSS class used to style the completion list flyout.
CompletionListHighlightedItemCssClassIndicates the CSS class used to style the highlighted item in the completion list flyout.
CompletionListItemCssClassIndicates the CSS class used to style the item in the completion list flyout.
CompletionSetCountGets and sets the number of suggestions to get from the bound Web service. Default is 10.
ContextKeyString property, indicates any page or user-specific information to pass to the bound Web service.
DelimiterCharactersIndicates one or more characters that the extender will use to tokenize the text-box content. The Web service will then use the last of these token to provide suggestions. Not set by default.
EnableCachingBoolean property, indicates whether client-side caching is enabled. True by default.
FirstRowSelectedBoolean property, indicates whether the first option in the list will be automatically selected. False by default.
MinimumPrefixLengthGets and sets the minimum number of characters in the text-box buffer that trigger the bound Web service. Default is 3.
ServiceMethodGets and sets the name of the method to invoke on the bound Web service.
ServicePathGets and sets the URL of the bound Web service.
UseContextKeyBoolean property, indicates whether the value of the ContextKeyFalse by default. property should be used, if specified.

A Web service that works with the AutoComplete extender is an ASP.NET AJAX script service. It looks nearly the same as a regular ASP.NET Web service, except that its class must be decorated with the ScriptService attribute. If you employ a Web service that lacks the attribute, each request to the associated ASMX endpoint originates an HTTP 500 error.

public class SuggestionService : WebService

The name of any public method on the class that is flagged with the WebMethod attribute can be successfully assigned to the ServiceMethod property of the extender. A method that provides suggestions must have the following signature:

public string[] GetCustomerIDs(string prefixText, int count)

The first argument is the prefix text to generate suggestions. It matches the current content of the text box and its length is not smaller than the value of the MinimumPrefixLength property. The count parameter indicates how many suggestions are to be provided. The value of the count parameter comes from the value of the CompletionSetCount property. The return value is always packed as an array of strings. Because of the ScriptService attribute, any communication between the server and client occurs through JSON strings.

You can leverage any supported attributes on Web service methods that will make the call go faster. For example, the CacheDuration attribute on the WebMethod attribute forces the service to cache internally for the specified duration the response of the method call. Likewise, you can enable session state if it’s strictly required by the logic the method implements. See Figure 4.

Figure 4. The AutoComplete extender in action

Most View
HP Photosmart 7520 e-All-In-On Printer – So Much Potential *Sniffle*
The Assemblage Of GeForce GTX 650 Ti Graphics Cards (Part 7)
Sharepoint 2013 : Creating team sites (part 1) - Customizing team sites, Working with document libraries
101 Recommended Apps (Part 13)
Xara Photo And Graphic Designer MX 2013
Innovate & Inspire - Delight, Surprise, Love, Connection (Part 3)
PowerShell for SharePoint 2013 : Word Automation Services - Configure the Conversion Processes, Configure Conversion Throughput
Parallel Programming with Microsoft Visual Studio 2010 : Introduction to LINQ (part 2) - PLINQ
WD Black 4TB - 4TB Storage Goes Mainstream
Lenovo Ideatab S2110 - A Transformer’s Strong Competitor Running Android 4.0 (Part 2)
Top 10
Sharepoint 2013 : Farm Management - Disable a Timer Job,Start a Timer Job, Set the Schedule for a Timer Job
Sharepoint 2013 : Farm Management - Display Available Timer Jobs on the Farm, Get a Specific Timer Job, Enable a Timer Job
Sharepoint 2013 : Farm Management - Review Workflow Configuration Settings,Modify Workflow Configuration Settings
Sharepoint 2013 : Farm Management - Review SharePoint Designer Settings, Configure SharePoint Designer Settings
Sharepoint 2013 : Farm Management - Remove a Managed Path, Merge Log Files, End the Current Log File
SQL Server 2012 : Policy Based Management - Evaluating Policies
SQL Server 2012 : Defining Policies (part 3) - Creating Policies
SQL Server 2012 : Defining Policies (part 2) - Conditions
SQL Server 2012 : Defining Policies (part 1) - Management Facets
Microsoft Exchange Server 2010 : Configuring Anti-Spam and Message Filtering Options (part 4) - Preventing Internal Servers from Being Filtered