Integrating Ajax into Web Appliations (Part 1)

Mar 3, 01:46 pm

Introduction

This article starts by first providing a high level description of what Ajax is and why it is becoming so popular. This is followed by some discussion of the available Ajax frameworks and several of examples of the frameworks in action. In the follow-up article I will summarize all the information into a table that can be used to make a decision on what framework works best for you. Throughout the article I will provide links where appropriate to more detailed information.

What is Ajax?

Ajax stands for Asynchronous Javascript and XML. You already of course know that it's not a new technology, but rather a combination of technologies that have been around for quite some time - I personally know that because I've used most of the possible ways of applying those technologies to my own web applications through the years.

Here are a few other points about Ajax you may or may not know:

  • It mainly uses XHTML and CSS - but other forms of data-interchange between the web server and client can also be used easily, like HTML, plain text, and formats like JSON.
  • It uses the Document Object Model (DOM), DHTML, and Javascript to manipulate it.
  • It makes use of the XMLHttpRequest object, now widely supported in various browsers including IE, FF, Safari, and Opera.
  • It uses JavaScript to interconnect the various components and technologies mentioned above.

Ajax's Popularity

How did Ajax become so popular? It is evident that the technologies used were available long before even the term Ajax was thrown into the IT arena early in 2005. I think there are a few key factors that count for today's hype around Ajax:

  • Many websites that exist today expose a slow and unresponsive user interface, and users are getting more demanding in their desire for sophisticated web applications that are also faster and more responsive.
  • The wish of many web developers to make the user interface better (more like typical client-server applications) where each control can be updated without others being affected, no screen flickering and fewer delays, and no screen freezing or refreshing.
  • The fact that JavaScript and the object XMLHttpRequest are now widely supported in many browsers has made Ajax possible.

Ond of the first attempts to fulfill those wishes and demands started with Microsoft's Remote Scripting, released when IE3 came out. It made use of a Java Applet, which was very popular at the time. Personally, I have used it a couple of times in my intranets because I thought it was a cool thing, but didn't apply it online since it was only supported on IE3 and later versions - way too restricted at that time for Internet web applications.

Then Microsoft came out with ActiveX controls, which became very popular although they were again restricted to only IE. Around the release of IE5, MS included a new component in their MSXML class library called XMLHttpRequest, which contained - among others - an object named XMLHTTP (also an ActiveX object), which could make synchronous or asynchronous HTTP Requests to a back-end web page that ran on a web server (using it's methods open(), send(), and a property called responseText), which executed and returned the result. The result type could be a string, for example containing HTML, or XML.

Although its use was restricted to IE5 and up (because it depended on other specific IE5 components) I have used this component and its various objects from the beginning in various intranet applications because it made it possible for me to use only JavaScript for scripting in my web page, and to divide the page in logical areas. I did this by writing a couple of function libraries including one that generated the final HTML output.

You guessed it - no more spaghetti code (to be clear, by spaghetti I mean having HTML, ASP script, and JavaScript all within a single page). Even better, I could also update specific controls on my page, on the fly. It had all the benefits I wanted: no full-page refreshing, no frozen browser screens and less web server and network load. My intranet applications (which were mainly IE targeted at the time) became much more responsive - and yes you guessed it, most important, my user base was thrilled with the new functionality!

XMLHttpRequest became very popular, so most of the others producers of browsers, Opera, FF, and Safari, started to incorporate the object with about the same name (XMLHTTP) and same functionality, but implemented using different technologies. That really made interoperability and easiness of using this object in a web application very attractive of course, and that's the point where developers started to incorporate the object in their corporate Internet strategies more and more. It also became common to use cross-browser JavaScript, CSS, DHTML, and the DOM to be able to make real use of XMLHTTP. So the Ajax-community as we could call it today really existed from then (late nineties) on.

Microsoft more recently came up with the so-called out-of-band-calls or later on script callbacks, which are supported both in ASP.NET 1.1 and 2.0. Script callbacks are simply HTTP Requests being made using the XmlHTTPRequest object to avoid refreshing the entire page. This is however a limited implementation because only one return type could be used, a string, and also because doing multiple callbacks on one web page was not trivial to do. It however can be seen as a first attempt by Microsoft to hook onto the Ajax boat. Whilst Microsoft had invented the XMLHTTPRequest object, they hadn't built any framework around it (until now with Atlas), so before all these new frameworks started popping up, developers had to build their own framework from the ground up.

Ajax Frameworks

Nowadays, Microsoft has given their Ajax development another name, the MS Atlas Project, which is one of the frameworks we'll see more closely later on. It makes Ajax-ifying your web applications a real breeze and offers some interesting feature extensions. It's a rather advanced project, integrating well into the ASP.NET page lifecycle, and currently there's a March 2006 release available for download. The March release provides the functionality on Safari 1.2 and up which was missing in previous versions.

Another great implementation at which we'll also take a good look further on was originally called My Ajax.NET from Jason Diamond, but was later renamed to Anthem.NET and is now situated on Source Forge. It's an open source project and is currently maintained by Jason Diamond and another developer. In this article I'll use version 1.1.0. It features a special control collection for Ajax development and integrates fully into the ASP.NET page lifecycle.

A third library at which we'll take a closer look is Michael Schwarz's Ajax.NET Pro. Originally being an open source project and according to Michael being the first Ajax-like library on the Internet, he's now working on two versions, one for .NET v1.1 and another for v2.0, but they're no longer open source. I'll be using the .NET v2.0 implementation here, called Ajax.NET Professional, version 5.11.4.2. The framework does not integrate into the ASP.NET page lifecycle but uses a separate HttpHandler.

There are more implementations of Ajax of course (see the Related Links section) but the three I will be covering are the most advanced .NET targeted frameworks I've seen so far and are ones you might well encounter in your ASP.NET development.

System Requirements

To run the sample code provided by the frameworks as well as included in the download material you will need to have the following:

  • A web server running on Windows XP or Windows Server 2003 or later
  • The .NET Framework version 1.x / 2.0
  • VS.NET2003 / 2005 (see note) or Visual Web Developer
  • A web browser - it can be IE6, IE7, FF 1.5 for Windows but also Safari 1.2+ on Mac OSX - all samples should work

Note: Although not discussed here, the Anthem.NET and Ajax.NET Professional samples provided for VS.NET 2003 will require you to install IIS first if you have XP Professional. For VS.NET 2005 it is not really necessary - it has its own lightweight web server (previously called Cassini) and therefore doesn't need IIS to run web applications. It can however be convenient to have IIS installed since there can be issues with dynamic relative URLs, for example images might not be resolved correctly because of the format in which the built-in web server does HTTP Requests (it uses a different port than 80 and is generally a dynamic generated port number).

Installing and Compiling the Sample Code

All the samples are written using C# with VS 2005 and were generated from a Web Site project. There are implementation specific samples you can obtain by downloading them from their respective websites. For more information, check the Related Links section.

For each of the frameworks discussed in this article and where possible there are specific samples available in the download material. Each sample has an install.txt file which describes what you should do in order to get the sample up and running quickly.

The directory structure of the download for this article is as follows: it contains three directories named AtlasSample, AnthemNETSample, and AjaxNETSample. Each one contains project files that you can open in VS.NET 2005 using Open | Web Site. But before doing so, you'll need to add the corresponding libraries first.

Ajax - A More Technical View

The main purpose of Ajax is to permit developers to update specific controls on their web pages with minimal effort, therefore enabling real client-server functionality, no full-page refreshes and less web server and network load. But how is it achieved?

In its simplest form, Ajax uses a JavaScript function on the client, where the XMLHttpRequest object is used to make a script callback to the web server and passes parameters to a server method to execute and fetch the required data. Another JavaScript function on the client then receives the data returned by the server method and finally it again uses JavaScript to update the client browser using the DOM and DHTML support to update the corresponding controls or variables. A more in-depth discussion and a nice visual representation of the Ajax model can be found at http://www.adaptivepath.com/publications/essays/archives/000385.php.

The XMLHttpRequest component can be seen as a black box with its properties and methods defined. See the Related Links section for more details on the XMLHttpRequest object.

Instantiating the XMLHttpRequest in your code is the start of each new adventure with Ajax:

var xmlhttp;
// on IE
xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
//Other browsers like Mozilla FireFox and Safari:
xmlhttp = new XMLHttpRequest();

Note that IE7 now has the object as part of JavaScript (as well as the ActiveX object used in previous versions) so basically the actual code that any frameworks use will keep working.

As you'll see, the frameworks you're about to look at all have script libraries that do not require you to write all those tedious script blocks - it's all integrated "in the box".

Ajax - Its Disadvantages

Of course, as with most things there are some negative aspects that you need to be aware of. Ajax has some disadvantages as well. As you know now, Ajax makes use of JavaScript, which serves as the glue to bind everything together. So for Ajax to work, JavaScript must be enabled on the client. Since users can easily disable JavaScript you may be still required to have the functionality to process the whole page on the web server.

That is all right, but we as developers should be aware of it and include server processing support in the case the browser doesn't support JavaScript. And that's easy to do, as you all know - simply detect the browser type and check whether it has JavaScript enabled. For more information on how to do this see the Related Links section.

Another downside is that the browser must include the XMLHttpRequest component and fully support its functionality. The browser support can easily be verified by the use of try and catch blocks. Simply try to instantiate the object as shown below:

var xmlhttp;
var error;
...
 try {
  xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
 } catch (error) {
  try {
   xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
  } catch (error) {
   xmlhttp = false;
  }
 }
 // Mozilla and Safari but also IE7 will enter here
 if (!xmlhttp && typeof XMLHttpRequest != 'undefined') {
  xmlhttp = new XMLHttpRequest();
...

Similar to the code above, the frameworks described in this article verify the capabilities of the client browser. They simply inject JavaScript code into the page where Ajax is requested. Most of the libraries have reached some level of transparency already, actually in some of them that level is quite high! We'll also see that MS Atlas takes it to the next step by creating a strong-typed API above the JavaScript functionality, with all its obvious advantages. Others like Anthem.NET provide a collection of special controls that derive from already existing controls (like a button, for example) but do expose extra or modified functionality.

Now that we have a basic understanding of Ajax, lets move onto the frameworks I will be discussing and what functionality they support; if they are easy to use, and most important on which browsers / platforms they are supported, and of course finally if tested, do they really work as expected?

Ajax - Frameworks

Let's get in and look in detail at the three frameworks I'm going to review in this article.

The MS Atlas Project

In short, the Atlas library consists of a collection of server controls that help Ajax-ifying your web pages, even if those pages have already been developed. Apart from that it contains a JavaScript client script library API that allows for object-oriented development.

Atlas is tightly integrated into VS 2005 and doesn't work on older versions of Visual Studio. The installer (found here) installs a new project type in VS 2005 called ASP.NET Atlas Web Site. So, go ahead and install it, and then fire up VS 2005. Clicking on Create Web Site in the Recent Projects area will bring up the dialog box found in Figure 1.

Figure 1. The new Atlas Project Template

The new project type should appear under the section My Templates. Name the project AtlasSample.

It is clear that when you create a new Web Application using this new project type, it will include Atlas functionality... and it does. First of all, in the bin directory you will see a new assembly called Microsoft.Web.Atlas.dll as shown in Figure 2.

Figure 2. Solution Explorer in VS 2005 with an Atlas project

So, this really was plain easy to install, wasn't it? Using the new template is very easy, so let's add the sample files from the download material that accompanies this article, AtlasSample. Follow the instructions in the install.txt.

Once you've added the project files, your Solution Explorer should look like Figure 3.

Figure 3. Atlas sample web application

Make sure you also update the web.config by copying the contents that refer to Atlas from the supplied web.config in the download material. The sections that refer to Atlas are clearly marked.

You'll immediately notice that in Figure 3 there are three web service files in the Solution Explorer. They serve as the web server methods where callbacks will call into. Now open up Default.aspx by pressing F5 (or Ctrl-F5 without Debug). It should look like Figure 4 (only AtlasSample is shown here because the other two framework samples look the same).

NOT VALID: ImageTooWide: AtlasSample in IE before clicking any buttons
This figure has been reduced in size to fit in the text. To view the full image Click here

After clicking each of the five buttons the screen should look like Figure 5

NOT VALID: ImageTooWide: AtlasSample running in IE6 after clicking the buttons
This figure has been reduced in size to fit in the text. To view the full image Click here

As you can see there are five small examples shown, the first two return the web server's date/time, and the other three are different versions of a progressbar I developed in my free time. Of those, the most interesting are the second example (the real-time clock) and the last progressbar (5th example) that reflects real-time web server data processing. The others are merely work towards them but serve to show simple Ajax development integrated with ASP.NET.

You'll see how they work when we get to the section where I'll explain the code used. But first let's see where the other two frameworks are downloaded and how they are installed. Note that all the examples have the same samples for each framework and therefore won't be shown repeatedly throughout the article.

Anthem.NET

Anthem.NET is an Open Source project and as such comes with the source code (C#) included as well as two example projects, one for VS.NET 2003 and another for VS 2005. Using the samples with Visual Studio is well described in the accompanying Install.txt. Anthem .NET uses the public domain license and the version status was alpha at the time of writing. See the Related Links section for information on where to download the latest version.

The installation is pretty basic, you simply unzip the files and copy the directory called anthem to your project directory space where you normally create your VS.NET 2005 projects.

After that, simply copy the directory called AnthemNETSample to the same directory level, and open it up in VS.NET 2005 (using Open Web Site).

The last thing you need to do is add the Anthem-2005 dll reference. Right-click the AnthemNETSample web workspace in Solution Explorer and choose Add Reference. Click the tab Browse in the dialog window that appears. Locate the dll that is located in the Anthem-2005 subdirectory of anthem that you just copied, and click OK. The dll will be added to your bin directory.

Even better, you can also add the Anthem-2005 as a project reference to your solution. If you do this, you will be able to browse the source and see how Anthem.NET is built. If you do this and add the project reference to the project AnthemNETSample, then the Solution Explorer should now look like Figure 6.

Figure 6. The Anthem.NET framework and sample web application

As you can see from Figure 6 there are already quite a few anthem controls supported, and the list is growing steadily as I'm writing. The main advantage of using these special controls is that they make it easier to create Ajax-like web applications.

The next step is to open Default.aspx, set it as the start up page, and hit F5 (or Ctrl-F5). You should see a page like the one we've seen for the Atlas sample web application previously.

The next and final framework to look at is Ajax.NET Professional.

Ajax.NET Professional

The last framework I'll include here is Michael Schwarz's Ajax.NET Professional. First, you'll need to download the framework for whichever version of .NET you are.

Note: If you lean more towards open source, there's now also BorgWorX that took the latest Ajax.NET source code and is continuing the development where Michael Schwarz left off. I'd like to include this one here but that would make the already long article even longer. I haven't looked at it closer yet, but it looks like it would be another good candidate to use.

After having downloaded it, unzip it and notice that it contains, among other things, a library called AjaxPro.2.dll for working with .NET 2.0, and a few sample web applications. The next step is to copy the sample called AjaxNETSample to your project space from the code download, add the dll to its bin directory, and open the directory in VS 2005. If all is well, then your Solution Explorer should resemble Figure 7.

Figure 7. Ajax.NET Professional sample application

Like the other frameworks, this sample web application consists of the same examples that have been used in the other two. It enables us to compare them and draw conclusions on how they behave, how flexible they are and where they apply best.

At this point, you should be able to run all three samples, and if you click the five example buttons all three should expose the same Ajax functionality. The sample applications are also - with a few tweaks - compatible with FireFox 1.5 for Windows and Safari 1.2+ for Mac OSX. The work I had to do to accomplish this was mainly small tweaks in my JavaScript code due to differences in the way each browser supports JavaScript.

I think that we are ready now to move on to the next section where we'll dive into the details of the samples.

The Sample Applications

For each Ajax framework I have created five examples: one that gets the current web server's date/time, one that emulates a real-time clock, and three different progressbars, where each one indicates work that's done on the web server when the button is clicked. The three progress bars differ in how they interact with the web server: the first two wait until the web server has completed its work and the third retrieves the status in real time using small intervals. All the samples will be discussed for each framework except example 4, the second progress bar, because it doesn't add any significant understanding as to how Ajax-like web applications work but is included in the download.

So let's see what Ajax functionality each example brings and how it is implemented in each library.

Example 1: Get Server Date/Time

The first example simply returns the date/time from the web server.

Atlas

Figure 8. Example 1 in Atlas before starting

In Atlas, the callback starts with clicking an HTML button:

<input onclick="return getServerTime();"...


This in turn executes the JavaScript function getServerTime():

function getServerTime() {
    document.getElementById("btnShowDate").disabled = true;
    window.status = "Getting data from web server... ";
    AtlasSample.GetServerDateTimeService.ServerDateTime
        (getServerTime_callback);
}

Which calls into the web service method ServerDateTime() using the object XmlHttpRequest:

[WebMethod]
public DateTime ServerDateTime()
{
   return DateTime.Now;
}

In the March release, it is now possible to use a $ instead of document.getElementById(). It will save you some typing. So the following now works:

$("btnShowDate").disabled = true;

In Atlas, it is possible to use page methods (I've added a sample page named PageMethod.aspx for you to see how it's done), but another interesting way to do it is by creating web services with web methods, like the one above.

When a callback is made using Atlas (using JSON) to a web service with an .asmx extension, it is passed on to a special HttpHandler (defined in the web.config) whereas with a normal call into a web service (using SOAP) then it is passed onto the normal handler. So you're able to use normal web services in a web application when Atlas is being used.

The web server method returns its data and on the client it is passed into the JavaScript function getServerTime_callback():

function getServerTime_callback(res) {
    document.getElementById("divDate").innerHTML = res;
    document.getElementById("btnShowDate").disabled = false;
    window.status = "Getting data from web server... done.";
}

Note that res is used and not res.value. This means that in Atlas, the return value res is not an object but a direct value, in this case a string. Both of the other frameworks will return an object, which is more common use in JavaScript functions.

When it has completed the controls on the page are updated, quickly and without a full-page refresh as shown in Figure 9.

Figure 9. The results of Example 1 in Atlas

Anthem.NET

The differences in code for using Anthem.NET are as follows: first, the HTML button is the same, but the way to call the server method is different:

function getServerTime() {
    document.getElementById("btnShowDate").disabled = true;
    window.status = "Getting data from web server... ";
    Anthem_InvokePageMethod('GetServerTime',[],
        getServerTime_callback);
}

In this case, the method that is used to call into the JavaScript library is Anthem_InvokePageMethod(), which takes a few parameters. Among them are the web server method (in this case a page method), then the parameter value pair collection (here nothing is passed on, which is denoted by an empty pair of brackets), and finally I pass in the JavaScript function name that will be executed when the callback returns. This can also be an inline function or anonymous function as a later example will show.

The server method is also different - it's a page method now instead of a web service call:

[Anthem.Method]
public DateTime GetServerTime()
{
    return DateTime.Now;
}

Methods used by Anthem.NET are marked with the attribute [Anthem.Method]. This is the way to make them available to the Anthem callback process. The JavaScript function getServerTime_callback() that is executed is exactly the same as with Atlas, with the only difference that res.value is used instead of only res (here, an object is returned instead of a direct value, as is done in Atlas).

Ajax.NET Professional

Keep in mind that Ajax.NET doesn't integrate within the web page lifecycle since it uses its own HttpHandler. Consequently, you can't access page values on the server side, but there may not be a need for you to do that - actually, the concept of Ajax was originally meant to update specific controls on the page. However, the fact that Atlas and Anthem do integrate well into the page life cycle may make them more advantageous when planning for a new web development.

Another issue which may arise when using Ajax.NET Pro is the way you define user access in IIS, if you only allow Windows Integrated Security, IE will work fine but the other browsers that do not implement automatic user authentication using NTLM will keep asking for user credentials each time a new HTTP request is made. Other implementations will only ask you for them once, the first time you load the page. While most Internet web sites work with anonymous access - for which the problem does not exist - for intranet use and when targeting browsers other than IE, using Windows Integrated Security can cause this problem of repeatedly asking for credentials.

In Ajax.NET Professional, the button stays the same, but as expected you need to modify the call into the server method:

function getServerTime() {
    document.getElementById("btnShowDate").disabled = true;
    window.status = "Getting data from web server... ";
    AjaxNETSample._Default.GetServerTime(getServerTime_callback);
}

The method executed is a page method, and like with Anthem.NET, we need to mark the method with a special attribute, but the rest stays the same:

[AjaxPro.AjaxMethod]
public DateTime GetServerTime()
{
    return DateTime.Now;
}

Like you would expect, the JavaScript function getServerTime_callback() that is executed when the callback returns is exactly the same as with Anthem.NET.

Example 2: Real-time Clock

The next example we'll have a look at is an extension to the first example, a simple real-time clock.

Atlas

Figure 10. Example 2 before starting the clock

Clicking the button will start the callback that causes the clock to run as shown in Figure 10.

<input onclick="return getServerRealTime();"...

This will executes the JavaScript function getServerRealTime():

var ftRT;
var blnClockRunning = false;
function getServerRealTime()
{
    AtlasSample.GetServerDateTimeService.ServerDateTime(_
      getServerRealTime_callback);
    // continiously execute method....
    ftRT = window.setTimeout("getServerRealTime()", 500);
    if (ftRT != null)
    {
        document.getElementById("btnShowDateRealTime").disabled = true;
        document.getElementById("btnStopRealTime").disabled = false;
        blnClockRunning = true;
    }
}

As with the first example, the server method ServerDateTime() is called, but after that, the callback method is re-run every half a second using the JavaScript's function setTimeout(). This leaves the user with a constantly updated display without the need to refresh the whole page. Just put this in contrast with the refresh meta tag which causes a full page refresh, and you'll notice the immedeate improvement in user experience.

Like the previous example, after each time the callback returns, the JavaScript function getServerRealTime_callback() is called:

function getServerRealTime_callback(res) {
    document.getElementById("divDateRealTime").innerHTML = res;
}

Each time after the callback returns, the controls on the page are refreshed as shown in Figure 11:

Figure 11. Example 2 updating the date and time

When you click the Stop button, the callback process is stopped:

function getStopRealTime()
{
    window.clearTimeout(ftRT);
    document.getElementById("btnStopRealTime").disabled = true;
    document.getElementById("btnShowDateRealTime").disabled = false;
    blnClockRunning = false;
}

The JavaScript function clearTimeout() stops the continuous call into the function getServerRealTime(), which halts the process of updating the page controls.

Anthem.NET

OK, let's review the changes needed for Anthem.NET to work properly. As expected, the HTML button can stay the same, but in the JavaScript function you'll need to modify the call into the server page method:

function getServerRealTime() {
    document.getElementById("btnShowDateRealTime").disabled = true;
    Anthem_InvokePageMethod('GetServerTime',[], getServerRealTime_callback);
    ftRT = window.setTimeout("getServerRealTime()", 500);
    document.getElementById("btnStopRealTime").disabled = false;
}

The method called is a page method, actually the same as in the first example, marked with the attribute [Anthem.Method].

The JavaScript function getServerRealTime_callback() that is executed when the callback occurs is exactly the same as shown with the Atlas code explanation. Likewise, the function to stop the callbacks, getStopRealTime(), is also the same.

Ajax.NET Professional

Here, the button is the same, and you only need to modify the page method call:

function getServerRealTime() {
    document.getElementById("btnShowDateRealTime").disabled = true;
    AjaxNETSample._Default.GetServerTime(getServerRealTime_callback);
    ftRT = window.setTimeout("getServerRealTime()", 500);
    document.getElementById("btnStopRealTime").disabled = false;
}

The page method GetServerTime() is exactly the same as with the preceeding example, this time marked with the attribute [AjaxPro.AjaxMethod]. Likewise, the function that is executed when the callback returns, getServerRealTime_callback(), is also identical. To stop the callbacks the same function getStopRealTime() is used.

From these two examples you have seen that using them with each framework is basically the same. All three frameworks handle the creation of and the call into the XmlHTTPRequest object behind the scenes. The differences are mainly in the way the web server methods are called, their data types and which types of controls are being used to initiate the callbacks.

Conclusion

In this article I've introduced you to the concept of Ajax and to three different frameworks that can be used to develop more interactive and more responsive web applications compared with traditional ASP.NET web development. By using one of these frameworks you can avoid having the annoying full page refresh that happen with postbacks. I've also demonstrated how to obtain and install the frameworks and showed a couple of basic examples of how you can use them.

In the part 2 of this article I'll show you some more examples and then we'll compare all three frameworks looking at some specific topics from a developer's point of view and finally include a simple feature comparing table.

Founders at Work



Add your comments

Please keep your comments relevant to this blog entry: inappropriate or purely promotional comments may be removed. To add hyperlink, please follow this example: "your link text":http://your.link.url