Thursday, July 29, 2010

Resolving relative URL's in javascript

In ASP.Net we have Page.ResolveUrl() method to resolve any relative URLs like "~/images/logo.gif". This at runtime renders the complete hosted path of the image e.g. http://Hostname/VirtualDirectory/images/logo.gif. This makes our applications safely deployable to virtual directories within IIS applications without messing up the URL's.

However, with javascript we don't have such an straight forward solution. One scenario where you might face such an problem of incorrect URL resolution is while using a single Master page for Web Content pages in different directories(root and sub directories).
So here's a little tweak that can be used with javascript to resolve the URL's at runtime:

Put below javascript in either the site's Master page or if you are not using Master page, put it in the first js file thats included in the page or in the first script section of the page:

Url = function() { }
Url.prototype =
{
_relativeRoot: '<%= ResolveUrl("~/") %>',
resolve: function(relative) {
var resolved = relative;
if (relative[0] == '~') resolved = this._relativeRoot + relative.substring(2);
return resolved;
}
}
$Url = new Url();


Now, this function can be use on any page that has reference of above script to resolve a relative url as show below:

var logoUrl = $Url.resolve("~/images/logo.gif");

Although, this solution is ASP.Net specific, but it can be used in any scripting language like php, jsp, etc by simply replacing the part "ResolveUrl("~/")" from above script to respective language's equivalent code.





Saturday, May 1, 2010

Bar chart, Trend line, Tree view and Grouped columns in Flex AdvancedDataGrid



Download Code - 2 MB

Introduction

Altough I'm a ASP.Net developer, I recently had to use Adobe Flex Builder 3.0 in one of my projects. I think this is a really cool technology with very rich controls. And its integration with ASP.Net is so seamless which compeled me to like it instantly. I generated some really cool UI using data from .Net webservice and AdvancedDataGrid control of Flex. So I though I should publish this as an article so that newbies to Flex can explorer these cool features of Flex.



Description

Example I have taken is that of a Sales History of a categories of some products.Features of Flex used in this article are:

  • Tree mode of AdvancedDataGrid using Hierarchical datasource
  • BarChart within a column of the grid using Itemrenderer(using degrafa library)
  • LineChart withing a column of the grid to show trend of sales in previous years(using degrafa library)
  • Grouped columns for Sales History of last 5 years

Article consist of two parts. One is the .Net webservice which acts as the data access layer to fetch data. And other is the Flex application which consumes the webservice, fetches data and displays it in the AdvancedDataGrid control. In addition to just binding the data to columns of the grid, I have taken a example where I can use many features of the AdvancedDataGrid and Flex as a whole. Here the data returned by webservice is in XML format (as shown below) which is parsed by action script code and converted to a Hierarchical data object in order to display the data in a Tree struchture.


Check out demo link here.

The below action script parses the XML data returned by the webservice call and converts it into a Hierarchical data object of flex

var arrCollection:ArrayCollection = new ArrayCollection();
for each(var prop:XML in dataXML.children())
{
var o:CatInfo = new CatInfo();
if(prop.@Rank != null)
o.Rank = prop.@Rank;
if(prop.@Category != null)
o.Category = prop.@Category;
if(prop.@Amount != null)
o.Amount = prop.@Amount;
if(prop.@Percent != null)
o.Percent = prop.@Percent;
if(prop.@Year1 != null)
o.Year1 = prop.@Year1;
if(prop.@Year2 != null)
o.Year2 = prop.@Year2;
if(prop.@Year3 != null)
o.Year3 = prop.@Year3;
if(prop.@Year4 != null)
o.Year4 = prop.@Year4;
if(prop.@Year5 != null)
o.Year5 = prop.@Year5;

var objTrend:ArrayCollection = new ArrayCollection();
objTrend.addItemAt(o.Year1,0);
objTrend.addItemAt(o.Year2,1);
objTrend.addItemAt(o.Year3,2);
objTrend.addItemAt(o.Year4,3);
objTrend.addItemAt(o.Year5,4);
o.Trend = objTrend;
ParseNodes(o,prop);
arrCollection.addItem(o);
}

hdCollection = new HierarchicalData(arrCollection);
hdCollection.childrenField = "ChildNodes";
adg1.dataProvider = hdCollection;
I have used two controls from degrafa libraries for generating the runtime charts in the grid. One for the bar charts and other for the trend line chart. For references on using Degrafa libraries please check out the below links -

Degrafa + Datagrids = Visual Display of Data - InsideRIA
Degrafa + Data Part 2: The Sparkline

The Webservice is consumed using the service reference component as shown below



<mx:WebService
id="service1"
wsdl="http://localhost/FlexService/FlexService/TestService.asmx?WSDL">
<mx:operation name="GetData" resultFormat="object"
fault="mx.controls.Alert.show(event.fault.faultString)"
result="remotingCFCHandler(event)"
/>
</mx:WebService>



Future scope

Further I would be adding a search on grid soon to this application. So look out for the same. Do let me know if you would like some other features to be added to this application.

s.a.w

Friday, January 1, 2010

My First Blog

Hey Folks,

So now I have my own blog too. But don't worry guys, I'm not gonna be blogging about any of the boring topics like politics, global warming, terrorism around the world,... etc.

I plan to keep my blogs strictly technical in nature. To start with let me introduce you to my personal website http://www.sawinfotech.com/. Its not just my personal website having my personal information, pics, etc. Its a collection of web applications viz 'SAWiNFO', 'SAWManager', 'SAWWiki' and 'Waingankars' about which you can learn more on its home page.

It also lists my technical articles, social network links, photo albums and many more. In my first blog I just wanted to introduce me and my website. So moving forward you shall see some technical blogs, info, etc...

So keep watching this space...

s.a.w