Sponsored

Showing posts with label AJAX. Show all posts
Showing posts with label AJAX. Show all posts

Friday, May 7, 2010

How to set programmatically a value of a watermarked TextBox via JavaScript - Update

Some time ago I've published an article How to set programmatically a value of a watermarked TextBox via JavaScript about some specifics of working with a text input box decorated with a TextboxWatermark Ajax Extender control from the Ajax Control Toolkit library. The technique described in the article has proven useful for a number of developers so when the new release of the Ajax Control Toolkit has recently been announced I've decided to update the article to cover some of the braking changes in Ajax Control Toolkit components.

Ajax Control Toolkit changes

One of the most significant changes in the recent Ajax Control Toolkit release that affected everything is renaming namespaces and control names. Most of the JavaScript classes in the ACT has been moved into Sys.Extended.UI and some of them renamed.

Correspondingly the AjaxControlToolkitTextboxWrapper class that is crucial for the technique described in this article is now called Sys.Extended.UI.TextBoxWrapper and this is a breaking change. Most if its methods haven't been renamed and this is a good news however the new way of using the wrapper has been introduced.

Below are the code examples demonstrating how to write the code correctly with the new version of the ACT.

First we need to acquire an instance of the Sys.Extended.UI.TextBoxWrapper class for our textbox control and this is the newly introduced technique compared to the previous version of the ACT:

// get the instance of a textbox element
var textBox = $get(textBoxId);
// use the get_Wrapper static method of the TextBoxWrapper class to get the instance of the wrapper for the textbox
var wrapper = Sys.Extended.UI.TextBoxWrapper.get_Wrapper(textBox);

In the code above first I assume that the ACT is present so I don't have to check that Sys.Extended.UI namespace is defined. Secondly the code above is safe even if the textbox is not watermarked: the get_Wrapper static method will always return the instance of the TextBoxWrapper; the new instance will be created if the textbox is not watermarked.

Now we can set or get a value of the textbox using the instance of the TextBoxWrapper:

// get the textbox value
var oldValue = wrapper.get_Value();
// set the textbox value
wrapper.set_Value(newVlaue);

Conclusion

In a nutshell there are two major changes introduced in the new ACT release that affect the coding technique described here: the name of the textbox wrapper class has been changed; and now it's not required to check whether the textbox is watermarked to use the technique above.

Sunday, November 29, 2009

Automatically compress embedded JavaScript resources with Microsoft Ajax Minifier

Recently Microsoft has announced yet another useful addition to an ASP.NET developer tool belt: Microsoft Ajax Minifier, a tool that enables you to reduce the size of a JavaScript file by removing unnecessary content from it. Clearly this is an extremely useful tool and the ASP.NET development community has gladly embraced it (just google it up to see a lot of positive responses). The tool indeed works very well and there have even been a number of articles comparing it to other well-known JavaScript compression tools that proved its quality. So there are no doubts whether to use the Minifier or not.

The question however is how to use it. Microsoft Ajax Minifier package does include a set of documentation that explains how to use the tool and even discusses a couple of usage scenarios. Unfortunately the way I wanted to use the Minifier is not covered in the documentation and for some reason I haven't found useful information on the Internet too so I've decided to do some research and share my findings with the community.

So how would I like to use the Minifier? Here are the requirements:
  1. I want to automatically compress embedded JavaScript resources in any project of my web application solution.
  2. I want the compressed JavaScripts have the original names so I don't have to change the references in HTML mark-up.
  3. I want the compression to be done only when I switch to the Release mode in Visual Studio. When I am in the Debug mode I want all the JavaScript files to be uncompressed for easier debugging.
  4. I want compressed JavaScript files never overrides the original JavaScript files and I don't want to keep the compressed JavaScripts so whenever I modify my JavaScript code the compressed resources are always up-to-date.

I believe that the requirements above describe one of the most common web application solution configuration so if there is a way to achieve them it would be very useful.

Can I achieve the requirements above with the Microsoft Ajax Minifier? The answer is yes. The solution is kind of obvious: since the Microsoft Ajax Minifier includes an MSBuild task I just need to modify a project file where I have embedded JavaScript resources that I need to be compressed to include the Microsoft Ajax Minifier build task. It does not sound complicated and below is the solution which is simple indeed. Just include the following XML in your project file right before the closing </Project> tag (in most cases):

<!-- Minify all JavaScript files that were embedded as resources -->
<Import Project="$(MSBuildExtensionsPath)\Microsoft\MicrosoftAjax\ajaxmin.tasks" />
<PropertyGroup>
<ResGenDependsOn>
MinifyJavaScript;
$(ResGenDependsOn)
</ResGenDependsOn>
</PropertyGroup>
<Target Name="MinifyJavaScript" Condition=" '$(ConfigurationName)'=='Release' ">
<Copy SourceFiles="@(EmbeddedResource)" DestinationFolder="$(IntermediateOutputPath)" Condition="'%(Extension)'=='.js'">
<Output TaskParameter="DestinationFiles" ItemName="EmbeddedJavaScriptResource" />
</Copy>
<AjaxMin SourceFiles="@(EmbeddedJavaScriptResource)" SourceExtensionPattern="\.js$" TargetExtension=".js" />
<ItemGroup>
<EmbeddedResource Remove="@(EmbeddedResource)" Condition="'%(Extension)'=='.js'" />
<EmbeddedResource Include="@(EmbeddedJavaScriptResource)" />
<FileWrites Include="@(EmbeddedJavaScriptResource)" />
</ItemGroup>
</Target>

What this script does is when the solution configuration is 'Release' it finds all the project embedded resource files with the extension '.js' and creates their compressed versions with the same names in the intermediate output folder where they are picked from later by the build process.

A few tips

As you may have noticed the Microsoft Ajax Minifier MSBuild task is referenced from the default folder where it was copied to by the installer. If you want to reference it from a different location, for example if you have a shared development environment and want to have similar setting for everyone, just copy two files ajaxmin.dll and ajaxmintask.dll to another location and include the <UsingTask> tag (below) instead of the <Import> tag in the script above:

<UsingTask TaskName="AjaxMin" AssemblyFile="$(MSBuildProjectDirectory)\..\Build\AjaxMinTask.dll" />

The presented script performs so called 'Normal Crunching' (see the Ajax Minifier documentation) of the JavaScript code which already does a pretty good job that is good enough in most of the cases: compression rate is over 50%. If you would like to turn on the 'Hypercrunching' mode (see the Ajax Minifier documentation) you only need to modify one line of the script to include the 'LocalRenaming' option of the Ajax Minifier:

<AjaxMin SourceFiles="@(EmbeddedJavaScriptResource)" SourceExtensionPattern="\.js$" TargetExtension=".js" LocalRenaming="CrunchAll" />

And the last note is: don't use the default Hypercrunching mode or RemoveUnneededCode option with the ASP.NET AJAX Framework as it does not work properly with it.

Thursday, November 19, 2009

Using the Microsoft Ajax Library 3.5 with the CDN

Recently Microsoft has announced its Microsoft Ajax content delivery network (CDN) which can significantly improve the performance of any ASP.NET AJAX web application. When it was first announced the CDN was almost useless for the current web applications based on ASP.NET 3.5 since it did not host the Microsoft Ajax library 3.5 and did not support content delivery via SSL. However in a very short period of time Microsoft was able to fix those problems (good job!) and now web applications built on ASP.NET 3.5 can benefit from using Microsoft Ajax CDN.

So how do you make MicrosoftAjax.js file being referenced from the CDN as opposed to the embedded file? Quite easy actually with the help of the ScriptManager control. Add the following declaration to a page (or Master page) where there is a ScriptManager control:

<asp:scriptmanager runat="server" enablepartialrendering="false">
  <scripts>
    <asp:scriptreference name="MicrosoftAjax.js" path="http://ajax.microsoft.com/ajax/3.5/MicrosoftAjax.js" />
  </scripts>
</asp:ScriptManager>

What that declaration means is that the script with a name MicrosoftAjax.js which is always automatically referenced by a ScriptManager from the System.Web.Extensions dll now should be referenced from that location: http://ajax.microsoft.com/ajax/3.5/MicrosoftAjax.js.

This is how it is referenced by default:

<script src="/ScriptResource.axd?d=eYUqBJhfSVL41hIDYkBL0tfaps9hoQId_48PydfbcyWH41vNvL68sk-l7P9FLAPz7b4vtI8WkZ-ezAF0b_ZkyG52wt9oUtaQ5ezFfGBr7LY1&t=ffffffffef976216" type="text/javascript"></script>

and after we include the new ScriptReference declaration:

<script src="http://ajax.microsoft.com/ajax/3.5/MicrosoftAjax.js" type="text/javascript"></script>

ScriptManager is even smart enough to automatically reference the debug version MicrosoftAjax.debug.js from the CDN when debugging is enabled in the web.config file:

Web.config:
<compilation debug="true">

HTML:
<script src="http://ajax.microsoft.com/ajax/3.5/MicrosoftAjax.debug.js" type="text/javascript"></script>

So this is clear: we have our MicrosoftAjax.js referenced from the CDN and that improves our web application performance and saves us and the visitors some bandwidth since an internet browser will reuse the same cached copy of the MicrosoftAjax.js from the CDN for different web applications that reference it.

Using the CDN conditionally

What if we only wanted to reference MicrosoftAjax.js from the CDN when the web application is deployed to a production environment and use an embedded version in a development environment? That would make sense in order for the developers to work without having to be connected to the Internet. Once again it can be done but this time we'll need to write some code. We are going to add the MicrosoftAjax.js script reference dynamically depending on the debug value in the web.config file; we only add the script reference when debug="false":

protected void Page_Load(object sender, EventArgs e)
{
  if (!Context.IsDebuggingEnabled)
  {
    ScriptManager sm = ScriptManager.GetCurrent(this);
    sm.Scripts.Add(new ScriptReference 
      {Name = "MicrosoftAjax.js", Path = "http://ajax.microsoft.com/ajax/3.5/MicrosoftAjax.js"});
  }
}

Using the CDN via SSL

Another major case is when our web application has pages that are served via SSL. In this case we want to automatically select the correct CDN URL for the MicrosoftAjax.js. In order to do that we just modify the previous code:

protected void Page_Load(object sender, EventArgs e)
{
  if (!Context.IsDebuggingEnabled)
  {
    ScriptManager sm = ScriptManager.GetCurrent(this);
    sm.Scripts.Add(new ScriptReference 
       {Name = "MicrosoftAjax.js", Path = Request.Url.Scheme + "://ajax.microsoft.com/ajax/3.5/MicrosoftAjax.js"});
  }
}

So that's it for now. Enjoy using the Microsoft Ajax CDN.

Wednesday, June 24, 2009

ASP.NET user name availability check using WCSF Validation Bundle

An average web site offering membership and protected content for its members requires users to sign up by visiting a sign-up or register page that allows a user to enter some information and create an account. A couple of pieces if information that users are commonly asked to enter are a User name or Login name and user's email. One potential problem with such user input is checking that entered login name and/or email address are available for registration and haven't been used by other users. When it's the case multiple attempts of entering available values can be very annoying and frustrating for users even making them to refuse registration on a web site. So improving user experience when validating login name and email is quite an important task.

Monday, June 22, 2009

How to set programmatically a value of a watermarked TextBox via JavaScript

There is an updated version of the article for the latest Ajax Control Toolkit release: http://blog.turlov.com/2010/05/how-to-set-programmatically-value-of.html
If you use ASP.NET AJAX and AJAX Control Toolkit you may find it useful to decorate some of your TextBox controls on a page with a TextBoxWatermark AJAX extender control from the AJAX Control Toolkit. It's fairly easy to use and a nice tool for improving both the page look and user experience. However if you need to set a value of a TextBox decorated with the TextBoxWatermark extender programmatically via JavaScript on the client-side you may notice that the behavior of the watermarked TextBox is different. If you use the regular way to set a value like this:
$get(textBoxId).value = someText;
then the value displayed in the TextBox on the page will change to the set value but the watermarked look will still be present and other AJAX Control Toolkit TextBox extenders (like a Calendar extender, for instance) will not recognize the new value. This happens because the TextBoxWatermark extender can not recognize and intercept your JavaScript operation since it's designed to serve user interactions. However there is a correct way of programmatic access to the TextBox's value. We modify the code above like that:
var textBox = $get(textBoxId);
if (textBox.AjaxControlToolkitTextBoxWrapper) {
    textBox.AjaxControlToolkitTextBoxWrapper.set_Value(someText);
}
else {
    textBox.value = someText;
}
The explanation is that most of the TextBox extenders from the AJAX Control Toolkit including a TextBoxWatermark extender use a special proxy class AjaxControlToolkitTextBoxWrapper to manipulate with the input elements. The proxy adds a special property AjaxControlToolkitTextBoxWrapper to the input element that contains a reference to itself allowing to access the value of the input element correctly. Similarly, if you need to get a value of a watermarked TextBox you do it like this:
var textBox = $get(textBoxId), text;
if (textBox.AjaxControlToolkitTextBoxWrapper) {
    text = textBox.AjaxControlToolkitTextBoxWrapper.get_Value();
}
else {
    text = textBox.value;
}

Tuesday, June 2, 2009

New version of ASP.NET AJAX Control Toolkit released

The new release of ASP.NET AJAX Control Toolkit is available for download. Bertrand Le Roy has written a very informative post about it.

What I particularly like in this new release is that the Color Picker extender is now included in the Ajax Control Toolkit. Hooray!

Along with the new Toolkit release there come a whole bunch of new tutorials and videos. Among them there are this particularly nice tutorial about the Color Picker extender and another excellent video tutorial by Joe Stagner. Thank you folks for such a great job!

What that means for the Color Picker Extender users is that they don't have to download it separately from Codeplex anymore because it is included in the Ajax Control Toolkit. For those who cannot yet switch to the new version of ACT the original Color Picker Extender control will continue to be available on Codeplex. During the next few days I will prepare and upload a new release synced up with the Ajax Control Toolkit.

It is very educating to read people's opinions about the new release of ACT in response to blog posts and on Codeplex. In general, the responses are positive, but occasionally there are some complaints, mostly about little things.

I would like to remind everybody that Ajax Control Toolkit is a completely community-based initiative (with, of course, the initial kick-off help from Microsoft) and people who work on it take time out of their personal calendars so let's be more tolerant and if you've come across something really bad please use the Issue Tracker.

As I mentioned before, I specifically was interested in reading responses about the ColorPicker.  Interestingly, all the complaints were about its look and feel, not about functionality. I admit that the UI it provides is rather simplistic but here is my question back: why don't you all take some time and come up with feedbacks and suggestions on what can be improved?

Since the ColorPicker was publicly available on CodePlex it's been downloaded more then 2000 times (and I don't count downloads of ACT source code) and only a few people suggested something about improving it. I take it as everybody has been satisfied.

Now that the CPE is a part of the ACT and has a bit more visibility I suggest that people who have suggestions or concerns please don't hesitate to speak up.

Wednesday, May 27, 2009

Survey: Ajax usage among .NET developers

If you haven’t already and you are a .NET developer, please take a couple minutes and answer this survey, whether you use Ajax or not. There are a number of Ajax surveys around, but this is the only one that focuses on .NET developers.

The survey:
http://www.zoomerang.com/Survey/?p=WEB22973CYKW2H

Monday, April 27, 2009

How to Improve ASP.NET UpdatePanel Performance

Since ASP.NET AJAX UpdatePanel was first introduced it has earned a strange mix of reputation. From one hand it has become a tool of first choice for many ASP.NET developers who wanted an easy way of introducing an AJAX-like behavior for their ASP.NET web apps. From another hand it has earned a lot of criticism from seasoned web developers because of certain performance consequences associated with complex usage scenarios.

Well, everything may be good and may be evil based on how we use it. From my experience consious and judicious use of UpdatePanel is the key to saving its benefits and avoiding potential problems.

Below I suggest a number of rules that help achieving better results when using UpdatePanel.

  • Avoid automatic refreshing of UpdatePanel; always stay in control of which UpdatePanel and when refreshes: set UpdateMode property to Conditional (the default value is Always).

  • Minimize the content of the UpdatePanel: the <ContentTemplate> should only include controls that are neccessary to refresh. For instance if user input requires server-side validation include only an error message mark-up in the UpdatePanel and leave the rest of the form outside.

  • Try to keep the partial postback trigger controls outside of their respective UpdatePanels unless its neccessary to change their markup.

  • Try to stick to a simple rule: one trigger for one UpdatePanel. If you need to refresh multiple UpdatePanels during one request add a trigger control to only one of those UpdatePanels and refresh the others programmatically in an event handler on the server. The idea is to avoid uncontrollable refreshing of unnecessary UpdatePanels.

  • Since ViewState is updated with every partial postback request turn the ViewState off on a page that contains the UpdatePanel wherever possible or store the ViewState on the server to avoid transferring it forth and back with every async request.

  • Since Page runs through its lifecycle during every partial postback and executes methods like Page_Load or Page_PreRender make sure that logic that is unneccessary for refreshing UpdatePanel is not executed by wrapping it in if(!ScriptManager.IsInAsyncPostBack).

  • If you use UpdatePanel event handlers like Init, Load, PreRender and Unload make sure that code inside these event handlers does not execute unless neccessary by checking Page.IsPostBack and ScriptManager.IsInAsyncPostBack properties.

  • If you trigger an UpdatePanel programmatically from the client-side (via JavaScript) make sure that its event handler check for the event trigger value using Request.Params["__EVENTTARGET"] ot avoid unnecessary execution path.

  • If you programmatically update Page's Header (Title, etc.) or other Page's content that is outside UpdatePanel make sure that this code never gets executed during partial postbacks. First of all its not neccessary since page does not refresh but also it may be dangerous because the content may not be handled properly by a browser.

Conclusion

There may probably be more tricks and tips regarding usage of UpdatePanel but those mentioned above have been proven by real exeprience. I would also recommend understanding how UpdatePanel works behind the scene and never hesitate using Fiddler to investigate what your web app's doing.

Wednesday, March 11, 2009

Using ColorPickerExtender Client-side Events

There have been question about how to utilize the client-side functionality of the ColorPickerExtender in order to improve customer experience. Here is an example of how to use a colorSelectionChanged client event.

Subscribing to the colorSelectionChanged event

You can subscribe to the event either via JavaScript code or ASP.NET mark-up:

    var cpe = $find("ColorPickerExtender1");
    cpe.add_colorSelectionChanged(changeColor);

Here $find is a standard function of the ASP.NET AJAX Framework that returns an instance of the AJAX component by BehaviourID; ColorPickerExtender1 is a BehaviourID of the ColorPickerExtender component and changeColor is your JavaScript function that will be called when the event occurs.

<ajaxToolkit:ColorPickerExtender ID="defaultCPE" runat="server"
TargetControlID="Color1"
    BehaviorID="ColorPicker1"
    OnClientColorSelectionChanged="changeColor"
/>

Make sure that the changeColor JavaScript function exists on the page otherwise you'll see a JavaScript error "changeColor is undefined". You may define a changeColor function like this:

function changeColor(sender) {
    sender.get_element().style.color = "#" + sender.get_selectedColor();
}

When your function is called after a user picked a color (i.e. clicked a mouse on the color palette) a sender argument will point to the instance of the ColorPickerExtender component that you can use inside your function. For instance, call a method get_element() to retrieve a reference to an input DOM element which the extender is attached to or use a get_selectedColor() method to retrieve a hexadecimal color code that the user selected. When assigning the color value to a DOM element style don't forget to prepend it with a '#' character.

Thursday, January 29, 2009

ASP.NET AJAX Compatibility Patch for Safari 3.x and Google Chrome

The problem I am going to talk about is not new but it somehow managed to concern not so many developers so far. However, it is a growing concern and more people would need a solution at some point.

The heart of the problem is there are two browsers with a growing number of users - Safari 3.x and Google Chrome, that ASP.NET AJAX framework is not compatible with.

One part of the problem is induced by a fact that both browsers report themselves as "Webkit" which is not supported by ASP.NET AJAX. This part of the problem affects both Safari and Chrome users.

The second part of the problem mostly affects Safari users because ASP.NET AJAX framework does "support" Safari (version 2.x) but in such a manner that makes your web application look like a total disaster in Safari version 3.x.

The suggested fix will help both cases. At least my tests showed quite a success. Ideally we would need an official patch from Microsoft but since they have their own plans and busy with the next .NET/ASP.NET 4.0 and VS 2010 I would assume that there will be no fix till those versions are out.

So let's stick to this solution for now. The solutions for the problem were suggested by a couple of people: http://forums.asp.net/p/1252014/2898429.aspx and http://blog.lavablast.com/post/2008/10/Gotcha-WebKit-(Safari-3-and-Google-Chrome)-Bug-with-ASPNET-AJAX.aspx. Since both solutions are absolutely the same I want to give both of them a credit.  
Now to the point, ASP.NET AJAX framework has a class Sys.Browser that represents a current browser and supports cross-browser compatibility for everything else. The solution simply extends the Sys.Browser class to support a Webkitbrowser:

Sys.Browser.WebKit = {};
if( navigator.userAgent.indexOf('WebKit/') > -1 )  {
    Sys.Browser.agent = Sys.Browser.WebKit;
    Sys.Browser.version = parseFloat(navigator.userAgent.match(/WebKit\/(\d+(\.\d+)?)/)[1]);
    Sys.Browser.name = 'WebKit';
}
That is all the code you need. To apply this code to your web application you will need to create a JavaScript file, let's say webkit.js and reference it in your application using standard ScriptManager server control. You can reference the fix as a file using this syntax:

<asp:ScriptManager ID="sm" runat="server">
    <Scripts>
        <asp:ScriptReference Path="~/Scripts/webkit.js" />
    </Scripts>
</asp:ScriptManager>
or embed it into an assembly (my preferred way) and reference it from the assembly as an embedded resource:

<asp:ScriptManager ID="sm" runat="server">
    <Scripts>
        <asp:ScriptReference Assembly="Scripts" Name="Scripts.webkit.js" />
    </Scripts>
</asp:ScriptManager>
Note that when you reference the fix from an assembly don't forget to add an assembly default namespace to the file name in the Nameattribute. In conclusion, according to my tests the fix eliminated problems with UpdatePanel, AjaxControlToolkitand Virtual Earth map control.

Wednesday, October 1, 2008

More About Color Picker ASP.NET AJAX Extender

I have published an article on Code Project about the Color Picker ASP.NET AJAX Extender. Please read it there.

Friday, September 26, 2008

Color Picker ASP.NET AJAX extender control

I was looking for a client-side color picker control and found it extremely difficult to find something that would satisfy to my requirements. I have found plenty of pure JavaScript controls written with various levels of proficiency and there was even one ASP.NET color-picker control that I almost liked but still my major requirement was not satisfied: I was looking for AJAX .NET Extender control - easy to use and based on a solid and proven platform.

So, I have researched what other color picker controls do and decided to write the one myself that I would base on Microsoft AJAX .NET platform. After some considerations I've decided to go even further and build an AJAX Control Toolkit Extender control.

As an example I took an AJAX Control Toolkit Calendar extender and in my Color Picker extender control I also internally used another AJAX Control Toolkit control: Popup extender.

Now, what are the advantages of implementing a client control as an ASP.NET AJAX extender?

  1. You use ASP.NET page mark-up to render the control content to the browser.
  2. No need to manually inject JavaScript, HTML and other resources.
  3. You develop JavaScript code in a standalone file leveraging ASP.NET AJAX framework and Visual Studio intellisense abilities.
  4. JavaScript per se is very well structured, easy to read and debug.
  5. Many of the hassles of JavaScript client coding such as cross-browser compatibility, event handling, asynchronous calls are taken care of by ASP.NET AJAX framework.

So, I have spent a few days coding the control and finally it's out there. I have created a Codeplex project for it so if you are interested just go there and download the control and a Demo Web site.

Now, just a few more words about the extender. First, this is how it looks:

Second, it's extremely easy to use. The extender attaches to an ASP.NET TextBox server control and to an optional button that can open a popup window and an element that samples a selected color in the background. User selects a color by clicking on a colored area. Below is a code example of using an extender on an ASP.NET page.

<asp:TextBox ID="TextBox1" runat="server" 
       Columns="7" MaxLength="7"></asp:TextBox>
  <asp:ImageButton ID="ImageButton1" runat="server" 
       ImageUrl="~/Images/icon_colorpicker.gif" />
  <cdt:ColorPickerExtender ID="cpe" runat="server" 
       TargetControlID="TextBox1"
       SampleControlID="ImageButton1"
       PopupButtonID="ImageButton1" />

Feel free to download the extender from the Codeplex, try it and post any comments or suggestions on the Codeplex project page.

Update 2020

Recently, I've visited the old and now archived CodePlex page for the ColorPickerExtender (https://archive.codeplex.com/?p=cpe) and found out that back in the day Microsoft had included that control on the official ASP.NET site (https://docs.microsoft.com/en-us/aspnet/web-forms/overview/ajax-control-toolkit/colorpicker/using-the-colorpicker-control-extender-cs). What a nice thing! Encouraged by this finding I've decided to resurrect the CPE and port it over to Angular, which is currently my favourite client-side framework. I will be introducing a new project on Git some time at the end of 2020, so stay sharp!

Monday, September 15, 2008

Working with VEColor class of VirtualEarth SDK

If you ever wanted to set a color for a custom VEShape object of type polyline or polygon than you must be familiar with the VEColor class that is used to represent a color in VirtualEarth SDK.

I am sure there are reasons behind of the design of the VEColor class, but for those who are used to a standard Web color representation in a form of 6-digit hexadecimal number it's kind of weird to provide 3 integer number in order to construct a color.

So I was in a search for some convenient ways of converting between VEColor and standard Web color and first place I looked through was of course the VirtualEarth Map control because I thought that the VE developers themselves would need a way to perform the same exercise. No surprise there is a couple of non-documented VE objects to support such conversion technique.

Here is a code example of using those objects:

// Create a convertor class
var converter = new VEHexStringToColor();
// Converter returns an instance of a VEColor class
// Transparency value is always set to 1.0
var veColor = converter.Convert("aabbcc");
// Adjust transparency value
veColor.A = 0.7;
// Convert VEColor to a string with a leading '#'
var webColor = VEColorToHexString(veColor);alert(webColor);

Both objects are available on the page after you reference a VE Map control v6.1. Of course there is no guarantee of any support of those objects in any future versions of the VE Map control so use it at your own risk and have fun.

Tuesday, June 17, 2008

Scalable CSS for Ajax Control Toolkit Tabs

If you use Tabs control from AJAX Control Toolkit library you may have noticed that the default CSS definition provided with the control does not display properly when you increase font size on a page, that is the default CSS is not scalable.

Since Tabs allows you to override CSS it's quite easy to fix a problem. Just grab a correct CSS file with the set of images and assign a CssClass property a new class name:

<ajaxToolkit:TabContainer runat="server" CssClass="myTabs" ...>

Now it looks more appropriate:

Friday, May 23, 2008

ScriptManager vs. ToolkitScriptManager

Introduction

ScriptManager is a special ASP.NET server control that should be placed on a page before you can use any of AJAX.NET enabled controls. The same rule is true for the AJAX Control Toolkit controls: they all require a ScriptManager on the page. While AJAX Control Toolkit controls work perfectly fine with the standard ASP.NET ScritpManager the Toolkit includes its own version of the ScriptManager called ToolkitScriptManager that inherits from ScriptManager and is meant to improve some of the ScriptManager's behaviors in particular how it renders out behavior JS scripts. Let's examine how using a ToolkitScriptManager changes a web page's appearance.

Experiment

As a testing example I have created a very simple page consisting of a single Accordion control from the AJAX Control Toolkit library.

<head runat="server">
    <title>Untitled Page</title>
    <style type="text/css">
        .accHead { border:1px solid #445566;font-size:larger;background-color:#aaa;}
        .accHeadSel { border:1px solid #445566;font-size:larger;background-color:#444;color:#fff;}
        .accCont { border:1px solid #ccc;padding:5px;}
    </style>
</head>
<body>
    <form id="form1" runat="server">
    <ajax:ToolkitScriptManager ID="tsm" runat="server"></ajax:ToolkitScriptManager>
    <%-- <asp:ScriptManager ID="sm" runat="server"></asp:ScriptManager>--%>
    <div>
<ajax:Accordion
    ID="MyAccordion"
    runat="Server"
    SelectedIndex="0"
    HeaderCssClass="accHead"
    HeaderSelectedCssClass="accHeadSel"
    ContentCssClass="accCont"
    AutoSize="None"
    FadeTransitions="true"
    TransitionDuration="250"
    FramesPerSecond="40"
    RequireOpenedPane="false"
    SuppressHeaderPostbacks="true">
    <Panes>
        <ajax:AccordionPane ID="AccordionPane1" runat="server"
            HeaderCssClass="accHead"
            ContentCssClass="accCont">
            <Header>Pane Header 1</Header>
            <Content>Content 1</Content>
        </ajax:AccordionPane>        
        <ajax:AccordionPane ID="AccordionPane2" runat="server"
            HeaderCssClass="accHead"
            ContentCssClass="accCont">
            <Header>Pane Header 2</Header>
            <Content>Content 2</Content>
        </ajax:AccordionPane>        
        <ajax:AccordionPane ID="AccordionPane3" runat="server"
            HeaderCssClass="accHead"
            ContentCssClass="accCont">
            <Header>Pane Header 3</Header>
            <Content>Content 3</Content>
        </ajax:AccordionPane>        
    </Panes>            
    <HeaderTemplate>List of Panes</HeaderTemplate>
    <ContentTemplate></ContentTemplate>
</ajax:Accordion>
    </div>
    </form>
</body>

You may have noticed that right after the form tag there are ScriptManager (SM) control and ToolkitScriptManager (TSM) control on the page but one of them is commented out. Next I run a page from VS 2008 two times: first using the SM and second using TSM, and compare the results.

HTML output and traffic

Let's compare the HTML output of two page versions. See a WinMerge screen shot below that shows the SM version in the left pane and the TSM version in the right pane.

First difference you see is that TSM adds its own hidden field on the page (top right pane) and the next and more important difference is that TSM renders one script reference on the page instead of the five ones that SM does.

Now if we examine the page's traffic with the FireBug we'll see how that changes the traffic: first graph refers to the page using the SM control and the second one when the TSM's at work.

Analyzing the graphs it's easy to see that the TSM does reduce a number of browser's round-trips by combining multiple script references into a single one. This advantage will become more attractive as more AJAX-enabled server controls will be placed on a web page that support script combining. However it is not necessarily true that it will always reduce the page loading time. As you can see when TSM returns a combined script to the page it takes some time to perform a work on the server. Correspondingly the amount of work and consequentially the response time directly depend on the number of scripts to combine (that is a number of AJAX server controls) and the size of the scripts to process (white spaces removal and compressing).

So there is no single recommendation that it's always preferable to use TSM instead of SM. In many cases SM version of a page may work faster then a TSM version of the page. Since it's not that difficult to alter a page for both cases I'd advise to test and compare both versions in your particular scenario before making a decision which one to choose.

Thursday, May 22, 2008

ToolkitScriptManager and Web Deployment Project

Problem description
If you use AJAX Control Toolkit in your project you probably use ToolkitScriptManager from the Toolkit instead of standard ASP.NET ScriptManager class. Now if you want to deploy your web application using Web Deployment Project (WDP) for VS2008 then you will find out very quickly that your AJAX enabled application features don't work. The reason for that is there is a JavaScript error on a page saying that the root JavaScript object for AJAX Control Toolkit is not defined on the page and all the subsequent scripts relying on that object have failed. I am not reproducing the exact message here because it may vary in different situations.

Background
You have tested your web application many times in your Dev environments and everything worked just fine. So what you've changed is you used a Web Deployment Project to build and deploy your web application and you presumably wanted to take advantage of a famous precompile and merge feature of the WDP.

Explanation
Now the problem is that the missing JavaScript on the page is rendered by a ToolkitScriptManager object that generate a link to a JavaScript code using a ScriptResource handler which is in its turn supposed to retrieve the code embedded into assembly. Because WDP changes the names and locations of the assemblies ToolitScriptManager was unable to resolve the assembly name and could not generate the link so your page does not have that JavaScript reference any more.

Workaround
Use standard ASP.NET ScriptManager instead of ToolkitScriptManager and everything will work again.

What's next?
I am in a process of investigating whether a ToolkitScriptManager brings any advantages comparing to a new ScriptManager 3.5 in terms of more efficient HTML rendering and will post here my findings as soon as possible.

Also if you are interested in employing a ToolkitScriptManager together with the Web Deployment Project I invite you to vote for this bug on Codeplex.