December 20, 2010

Creating a simple Border Layout

At times, building a simple thing can become tedious. Especially when you miss simple configurations that make huge impact! This is a back to basics article on how to code a simple border layout in an ExtJS panel.

Let’s make a simple panel with a border layout:
var panel = new Ext.Panel({
 renderTo: document.body,
            title: 'Border Layout',
            layout: 'border',
            width:700,
            height:400,
            items: [{
                region: 'north',
                layout: 'fit',
                frame: true,
                html: 'This is North!',
                height: 150
                
             },{
                region: 'west',
                layout: 'fit',
                frame: true,
                border: false,
                html: 'This is West!',
                width: 200,                
            }, {
                region: 'center',
                layout: 'fit',
                frame: true,
                width: 400,
                html: 'This is Center!',
                border: false
             }, {
                region: 'east',
                layout: 'fit',
                frame: true,
                border: false,
                html: 'This is East!',
                width: 200                
            },{
                region: 'south',
                layout: 'fit',
                frame: true,
                html: 'This is South!',
                height: 150
                
             }]
    });
There are few points to remember when working with border layout. I have listed few important points:
  • When you use border layout, you should always have width and height of the panel defined. If these are not defined, the panel is not displayed properly.
  • North & South region must have height information for proper display.
  • East & West region must have width information for proper display.
  • Center region is a must for the border layout.

Here is the screen shot of our simple panel:

Share your tips with me and keep coding :)

Read other ExtJS related articles!

June 21, 2010

Hiding Series in ExtJS Charts

In the last few posts we saw how to create and handle events in Ext JS charts. We will have a look at some advanced tasks using Ext JS charts. In this post, we will learn how to hide and display a series in a chart.

As usual, I will go with the sales and revenue chart. In our chart we will have two series - Sales and Revenue. We will provide two check boxes to toggle the series' visibility.
Lets begin with the data store (The data store is same as the one used in previous tutorials):
var store = new Ext.data.JsonStore({
fields:['month', 'sales','rev'],
data: [
    {month:'Jan', sales: 2000, rev: 3000},
    {month:'Feb', sales: 1800, rev: 2900},
    {month:'Mar', sales: 1500, rev: 3100},
    .
    .
    .
    {month:'Nov', sales: 2100, rev: 3000},
    {month:'Dec', sales: 2650, rev: 3300}
]
});
The framework does not provide us with APIs for what we are trying to achieve. But before that lets display the chart and the controls without the proposed functionality:
new Ext.Panel({
    title: 'Hiding series in ExtJS Charts',
    renderTo: 'container',
    width:600,
    height:300,
    tbar:[{
         xtype:'checkbox',
         boxLabel:'Toggle Sales',
         handler: function() {
                  alert('Hide / Show Sales');
           }
         },{
         xtype:'checkbox',
         boxLabel:'Toggle Revenue',
         handler: function() {
                  alert('Hide / Show Revenue');
           }
         }],
    items: [{
        xtype: 'columnchart',
        id:'myChart',
        store: store,
        xField: 'month',
        extraStyle: {
                  legend: {
                        display: 'right'
                  }
    },
    series: [{
        yField: 'sales',
        displayName: 'Sales'
        },{
        yField: 'rev',
        displayName: 'Revenue'
    }]
  }]
});
Now we have the chart and the necessary handler methods on the checkbox, let's split the problem into two parts. First is hiding the series in the chart and second is to hide the series name in the legend.

To hide the series, you will have to access the APIs exposed by flash component. The SWF component exposes a method named setSeriesStylesByIndex for setting styles for a series. The method has two parameters - index of the series you are about to modify and the config object that will hold the new style.You can pass the following parameters and its values to the config object:
  • color
  • colors
  • size
  • alpha
  • borderColor
  • borderAlpha
  • fillColor
  • fillAlpha
  • lineSize
  • lineColor
  • lineAlpha
  • image
  • images
  • mode
  • connectPoints
  • connectDiscontinuousPoints
  • discontinuousDashLength
  • skin
  • visibility
For more details on these attributes, have a look at YUI documentation. Back to our method, it will now look something like this:
function setSeriesStylesByIndex(index, styles){
    // Assuming swfObject is an instance of swf available in chart
    swfObject.setSeriesStylesByIndex(index, Ext.encode(styles));
}
Our next hurdle is how to call this method when clicking on our checkbox. To accomplish our task we will use the override method (static method) available in Ext class.
Here is the final code of our function being injected into chart:
Ext.override(Ext.chart.Chart, {
    setSeriesStylesByIndex: function(index, styles){
        this.swf.setSeriesStylesByIndex(index, Ext.encode(styles));
    }
});
If you execute our project and have a look at the chart rendered you will notice that the series display can be toggled but the legend of the chart is not updated properly. To update the chart's legend, we will update the showInLegend property of the series. Each series can be accessed in a chart using the series array. So, to modify the first first series, we just need to use the array notation to access the series and the showInLegend property. For example:
chart.series[0].showInLegend = false;
By just setting the property will not have any effect on the chart. We will have to update the display by calling the refresh method available with the chart object. Here is how our checkbox event handler look finally:
function() { 
var chart = Ext.ComponentMgr.get('myChart');
    if(this.checked) {
         // hide the columns (series in chart)
         chart.setSeriesStylesByIndex(0,
                  {connectPoints: false,alpha:0.0});
         // hide the series label in legend
         chart.series[0].showInLegend = false;
    } else {
         chart.setSeriesStylesByIndex(0,
                  {connectPoints: true,alpha:1.0});
         chart.series[0].showInLegend = true;
    }
    // Refresh the chart
    chart.refresh();
}
You will have to hard-code the appropriate series index so that the correct series properties is modified.The complete code is given below:
new Ext.Panel({
    title: 'Hiding series in ExtJS Charts',
    renderTo: 'container',
    width:600,
    height:300,
    tbar:[{
         xtype:'checkbox',
         boxLabel:'Toggle Sales',
         handler: function() {
             var chart = Ext.ComponentMgr.get('myChart');
             if(this.checked) {
                 chart.setSeriesStylesByIndex(0,
                          {connectPoints: false,alpha:0.0});
                 chart.series[0].showInLegend = false;
             } else {
                 chart.setSeriesStylesByIndex(0,
                          {connectPoints: true,alpha:1.0});
                 chart.series[0].showInLegend = true;
             }
             chart.refresh();
         }
    },{
         xtype:'checkbox',
         boxLabel:'Toggle Revenue',
         handler: function() {
             var chart = Ext.ComponentMgr.get('myChart');
             if(this.checked) {
                 chart.setSeriesStylesByIndex(1,
                          {connectPoints: false,alpha:0.0});
                 chart.series[1].showInLegend = false;
             } else {
                 chart.setSeriesStylesByIndex(1,
                          {connectPoints: true,alpha:1.0});
                 chart.series[1].showInLegend = true;
             }
             chart.refresh();
         }
    }],
    items: [{
        xtype: 'columnchart',
        id:'myChart',
        store: store,
        xField: 'month',
        extraStyle: {
             legend: {
                display: 'right'
             }
        },
    series: [{
        yField: 'sales',
        displayName: 'Sales'
    },{
        yField: 'rev',
        displayName: 'Revenue'
    }]
  }]
});
ExtJS Line Chart showing Sales & Revenue

Well, that's all for now. In the coming weeks we will have some more tutorials on chart and finally build a dashboard. We will also have a look at the new touch UI framework introduced recently.

Read other ExtJS related articles!

June 15, 2010

ExtJS is now Sencha!

The post's heading speaks it all. Yes, Ext JS a javascript UI library has combined forces with jQTouch and Raphael projects. The company's name is being changed to Sencha which is a popular Japanese green tea. It is interesting to see jQtouch and Raphael which are two leading open source projects getting combined.

As a developer using Ext JS, I am very excited to see this merging. I would like to see Ext JS making use of Raphael's graphics capabilities. At the same this, it will be very interesting to see how a jQuery backed mobile web development library is going to fit it. Will they rewrite the library using Ext JS core? Another interesting point is that both Raphael and jQtouch uses MIT license. The company also managed to get hold of Jonathan Stark to maintain jQtouch.

What I would like to see is a better visualization API (charting tools) based on Raphael rather than the YUI charts. It will be also interesting to see how these projects collaborate and how their outcome affects the developer community.

Read other articles and tutorials on ExtJS.

June 03, 2010

Handling Events in ExtJS Charts

After publishing "Getting started with ExtJS Charts" article last week, I got a question on handling event in ExtJS charts. So, in this article we will discuss about the event handling. Before we present the reader’s issue, let’s have a look at how to handle events.


The documentation of chart package is really bad! I wonder why ExtJS team is not updating it. I would actually love to see a java script based chart library (built by ExtJs team) rather than YUI charts being used. Another option for developers would be to use other charting tools available. But for now, let's get back to event handling.

You can attach custom event handlers just like how you do for any other ExtJS component. You can use the listeners property or use methods like on and addListener.

Now if you have a look at the Cart's source code you will find few hidden events:
  • itemmouseover
  • itemmouseout
  • itemclick
  • itemdoubleclick
  • itemdragstart
  • itemdrag
  • itemdragend
Unfortunately, I found some of these not working as it should be. Even forums seem to have less detail about these events.

Item Click Event (itemclick):
Item click event is invoked when a chart item is clicked. With this event you can do drill down, update another chart or do other dynamic effects on the chart. Let’s dive into the code to get a better understanding.

First let’s set up our data store:
var store = new Ext.data.JsonStore({
    fields:['month', 'sales','rev'],
    data: [
            {month:'Jan', sales: 2000, rev: 3000},
            {month:'Feb', sales: 1800, rev: 2900},
            .
            .
            .
     {month:'Dec', sales: 2650, rev: 3300}
 ]
});
We will create a simple column chart using this store:
new Ext.Panel({
    title: 'A Demo Application',
    renderTo: 'container',
    width:600,
    height:350,
    items: [{
 xtype: 'columnchart',     
 id:'myChart',
        store: store,
        xField: 'month',
 yField: 'sales',
 listeners: {
            itemclick: function(o) {
         var record = store.getAt(o.index);
  Ext.Msg.alert('Item Selected',
                    "You Clicked on Sales: " +rec.get('sales') + 
                    " for " + rec.get('month'));
     }
 }      
    }]
});
In the above code, I have used listeners property to specify my itemclick events handler. Using the parameter passed to the event’s method, we will be able to access all the necessary information. Here I am just displaying the value of sales.

Item Mouse Over Event (itemmouseover):
itemmouseover event is fired when user mouse over an item. This can be used for display some dynamic selection. For example, let’s assume we had a data grid with the same values ie sales and revenue and we would like to automatically select the row when use mouse over on an item in the chart.

We will introduce a data grid that will render the same data store. This time, I will make use of the line chart and display both sales and revenue details.
new Ext.Panel({
        title: 'A Demo Application',
        renderTo: 'container',
 layout:'column',
        height: 350,        
        items: [{
     xtype: 'linechart',
     width:600,
          height:350,
     id:'myChart',
            store: store,
     xField: 'month',
     xAxis: new Ext.chart.CategoryAxis({
                 title: 'Month'
     }),
     yAxis: new Ext.chart.NumericAxis({
  title:'USD', 
         majorUnit: 500
     }),
     series: [{
  yField: 'sales',
  displayName: 'Sales',       
     },{
  yField: 'rev',
  displayName: 'Revenue'
            }],
     listeners: {
  itemmouseover: function(o) {
             var myGrid = Ext.getCmp('myGrid');
      myGrid.selModel.selectRow(o.index);       
  }
     }      
 },{
     xtype: 'grid',
     title:'The Sales Grid',
     id:'myGrid',
     store: store,
     height: 350,
     width: 300,
     stripeRows: true,
     sm: new Ext.grid.RowSelectionModel({singleSelect:true}),
     columns:[
  {header:'Month',dataIndex:'month'},
  {header:'Sales',dataIndex:'sales'},
  {header:'Revenue',dataIndex:'rev'}
     ]
 }]
 });

The area of interest would be to see how we did it. Have a close look at the itemmouseover event handler. Basically, the key to manipulation is the object that is passed to the event handler. Using this you will be able to access not only the index but also the chart object itself. The attributes of this object are:
  • Component – The chart component itself.
  • Index – The index position of the item in store.
  • Item – The row from store corresponding to the index. You can access individual attributes of the row.
  • seriesIndex – The index position of the series. The values starts with 0.
  • type – Name of the event
  • x – x coordinate 
  • y – y coordinate

Drag Events:
itemdrag, itemdragstart and itemdragend are used for drag events. I tried making use of these events to make a graph wherein user will be able to drag the points and modify the values. Unfortunately, I am stuck! If I get it running, I will present it in future.

Double Click Event (itemdoubleclick):
I had very bad time working with this event! It just doesn’t get fired. From the forum discussions I see that this event might not be implemented yet. I wonder why, but It would have been great if user can double click on a specific month’s sales and he get it a detail report to download.

Now, lets tackle the reader's problem.

Reader’s problem:
The reader asked how the click event works and how to know which series was clicked.

Solution:
Now, solving this is very easy. You can handle click using the itemclick event and to identify the series and values you can make use of the values provided by the object. Just modify the as shown below:
itemclick: function(o){
 var rec = store.getAt(o.index);
 if(o.seriesIndex==0)
  Ext.Msg.alert('Item Selected',
                "You Clicked on Sales: " +rec.get('sales') + 
                " for " + rec.get('month'));
 else
  Ext.Msg.alert('Item Selected',
               "You Clicked on Revenue: " +rec.get('rev') +
               " for " + rec.get('month'));
}

Well, thats all for now. Let me know your feedback through comments or my contact form. Enjoy the day and time for me to relax!

Read other ExtJS related articles!

May 29, 2010

Working with ExtJS Pie Charts

In the previous post we saw how to create & customize charts using ExtJS. In this post, we will have a look at Pie charts. Pie charts are little different from other charts as they do not have axis and the data displayed is in percentage.

First Pie Chart

Let’s start with the data store. In this tutorial, I am getting the data from a remote URL. My server returns me a set of JSON object with product name and their sales value. Here is the data store:
var store = new Ext.data.JsonStore({
      fields:['product','sales'],
      root: 'rec',
      url: ‘/piechart/data/’
});
Unlike other charts, pie charts do not have axis. So, instead of using xField and yField properties of charts to pass data, we have dataField and categoryField in pie charts. Here is the code for pie chart:
new Ext.Panel({
title: 'Pie Chart',
      renderTo: 'chartDiv',
      width:400,
      height:300,                        
      items: {
            xtype: 'piechart',
            store: store,
      dataField: 'sales',
            categoryField: 'product'
      }
});
Very simple indeed! ExtJS does all the necessary calculations even if you don’t represent the data in percentage.

Adding Legend

Now, let’s add a legend to this chart. Without it, there is no much use in displaying a chart. An important property for styling is extraStyle. It helps you to add extra styles that will add or override default styles of the chart. Here is the final code for the pie chart and panel:
new Ext.Panel({
       title: 'The Pie Chart',
       renderTo: 'chartDiv',
       width:400,
       height:300,
items: {
       xtype: 'piechart',
       store: store,
       dataField: 'sales',
       categoryField: 'product',
       extraStyle: {
            legend:{
                display: 'right',
                padding: 10,
                border:{
                   color: '#CBCBCB',
                   size: 1
                }
            }
        }
      }
 });
While displaying the legend,notice that I have also made some beautification to it. I have provided a thin border using a specific color. There is no chart specific code for displaying legend, so the same code will work for other types of charts as well.

Custom Colors in your Pie chart

By default, ExtJS picks out the colors when rendering the chart. You might find these color shade dull. Lets try to brighten up our chart. I am going to apply a color scheme called Esprit_80s. In order to apply, we need to basically modify the style of series. So we will modify seriesStyles property of our pie chart:
new Ext.Panel({
       title: 'The Pie Chart',
       renderTo: 'chartDiv',
       width:600,
       height:300,
       items: {
           xtype: 'piechart',
           store: store,
           dataField: 'sales',
           categoryField: 'product',
           seriesStyles: {
             colors:['#F8869D','#25CDF2',
                     '#FFAA3C','#DEFE39',
                     '#AB63F6'] //eSprit 80s
            },
           extraStyle: {
                 legend:{
                    display: 'right',
                 padding: 10,
                 border:{
                   color: '#CBCBCB',
                   size: 1
                 }
           }
       }
    }
});

Note that the property colors is used only for pie charts. If you need to change the colors for other charts you will have to use the color property.

Textures & images in your Pie chart

ExtJS also provides us the ability to use images instead of color. So, if you have few texture images or any other images, you can easily substitute them for colors. This is possible through the images property of seriesStyles. I have five simple texture images and here is how I am adding them to our pie chart:
new Ext.Panel({
       title: 'The Pie Chart',
       renderTo: 'chartDiv',
       width:600,
       height:300,
       items: {
           xtype: 'piechart',
           store: store,
           dataField: 'sales',
           categoryField: 'product',
           seriesStyles: {
           images:['images/one.png',
                'images/three.png',
                'images/two.png',
                'images/four.png',
                'images/five.png']
            },
            extraStyle: {
                legend:{
                display: 'bottom',
                padding: 10,
                border:{
                   color: '#CBCBCB',
                   size: 1
                }
            }
       }
   }
});

Apart from these properties, extraStyle can be used to change the font styles as well. Have a look at the APIs and try out different customizations. I will be back with more customization tutorials on ExtJS charts. Let me know your feedback either through comments or using the contact form.

Learn how to Handle events in ExtJS charts or read other articles on ExtJS.

May 19, 2010

Getting Started with ExtJS Charts

The Charts feature in ExtJS is not a new thing, but recently few Techno Paper readers asked me questions regrading the same. This article is about getting started with ExtJS Charts how to do some basic customizations. For now, we will see what kind of charts ExtJS provide and how to get your first chart displayed.

Prerequisites

I assume you already have knowledge in building the UI (panels at least) and have worked on DataStores ( I will be using JSONStore). If you are not ready with these, may be you can have a look at my basic tutorials like "All about...".

What ExtJS offers
ExtJS offers you Line, Bar, Column, Pie and stacked charts. It also offers good amount of customization options as well. All the chart related classes are under the package Ext.chart and Chart is the base class. Apart from the chart classes, the library also provides classes that can be used to customize the axis, series and even the chart display. But note that, ExtJS makes use of Flash to render the charts and its not pure JavaScript component. Internally ExtJS is making use of YUI charts features and classes. Now, lets get started with coding!

Hello World of Charts

Building charts with ExtJS requires three things. The Datastore, the Chart object and a Panel to display the chart. In our first example i am going to keep things very simple. Lets build a DataStore first:
var store = new Ext.data.JsonStore({
fields:['month', 'sales'],
data: [
    {month:'Jan', sales: 2000},{month:'Feb', sales: 1800},
    {month:'Mar', sales: 1500},{month:'Apr', sales: 2150},
    {month:'May', sales: 2210},{month:'Jun', sales: 2250},
    {month:'Jul', sales: 2370},{month:'Aug', sales: 2500},
    {month:'Sep', sales: 3000},{month:'Oct', sales: 2580},
    {month:'Nov', sales: 2100},{month:'Dec', sales: 2650}
]});
I have a simple JsonStore here with the data hardcoded. In later examples, we will be fetching the data through ajax request. In the JsonStore, I have provided metadata and data. The fields attribute describe the fields in my records. The data attribute actually holds the data in the form of JSON. Instead of using JSON, we could also use XML.

Next, to create the chart object. For this example, I have used the line chart. Here is the code:
var chart = new Ext.chart.LineChart({
    store: store,
    xField: 'month',
    yField: 'sales'
});
Its very clean and simple! I have just provided the data store and what has to be plotted along x and y axis. And finally we need to put the chart into display. Here is our Panel:
var Panel = new Ext.Panel({
    title: 'Yearly Sales',
    renderTo: 'chartDiv',
    width: 400,
    height: 200,
    items:[chart]
});
If you are experienced coder I suggest you define the chart object in the panel rather than declaring it separately. Lets begin dig deeper!

Working with Axis

Chat's axis can be configured using xAsix and yAsix properties. There properties can accept objects of CategoryAsix, NumericAxis or TimeAxis. Lets add titles to our chart's axis:
xAxis: new Ext.chart.CategoryAxis({
                 title: 'Month'
                  }),
                  yAxis: new Ext.chart.NumericAxis({
                  title:'USD',
                  majorUnit: 500
                  })
Note that we have made use of CategoryAxis for y-axis as it hold months. Whereas, we have used NumericAxis for x-axis as it represents sales value in USD. I also changed the units in which the x-axis is represented. Check the API for other properties of these classes.

Working with Series

You don't always plot one parameter on a chart. At times, you have multiple data to be visualized onto the charts. Lets take our example of sales per month and add revenue to it. Now we need to plot both sales and revenue for each month. ExtJS allows you to do this by adding series object to the chart. The framework provides five implementations for different types of charts. Let's modify our chart to show revenue as well:
new Ext.Panel({
       title: 'A Simple Chart',
       renderTo: 'container',
       width:600,
       height:300,
       items: {
           xtype: 'linechart',
           store: store,
           xField: 'month',
xAxis: new Ext.chart.CategoryAxis({
                 title: 'Month'
}),
yAxis: new Ext.chart.NumericAxis({
title:'USD',
majorUnit: 500
}),
series: [{
yField: 'sales'
},{
yField: 'rev'
             }]
}
   });
I have kept the series objects very simple. We have just added the data alone. Upon execution, you will notice that it difficult to interpret the data as we do not have a legend on our chart. And that's exactly our next objective. To start with, lets modify the series as:
series: [{
yField: 'sales',
displayName: 'Sales'
},{
yField: 'rev',
displayName: 'Revenue'
 }]
I have just added the displyName property. To complete our modifications we need to do one final task, i.e display the legend!

Working with Extra Styles

extraSyle is an important property for styling your charts. It helps in modifying the colors, fonts, borders for various parts of your chart like axis, data tips, legends etc. First lets add a legend to our existing chart. Here is the code:
new Ext.Panel({
       title: 'A Simple Chart',
       renderTo: 'container',
       width:600,
       height:300,
       items: {
           xtype: 'linechart',
           store: store,
           xField: 'month',
xAxis: new Ext.chart.CategoryAxis({
                 title: 'Month'
}),
yAxis: new Ext.chart.NumericAxis({
title:'USD',
majorUnit: 500
}),
series: [{
yField: 'sales',
displayName: 'Sales'
},{
yField: 'rev',
displayName: 'Revenue'
             }],
extraStyle: {
legend: {
display: 'right'
}
}
}
   });
If you think of more customizations and styling, you need to have a good look at the extraStyle.
Well, that all for now. Feel free to provide me your feedback on this post. Next, we will have a look at pie charts.

May 17, 2010

Creating JSON using ASP Repeater

I had to implement an interesting task over the last few days. A part of the task, had to deal with what this article is all about. It sounded simple and easy but it turned ugly! The aim was to use ASP.Net's Repeater tag to create JSON when the page is loaded and later use it for some user manipulations and ajax operation. But in this article, we will see how to create JSON.

The ASP Repeater is a very handy tag. Everybody know it, but at times you will have to get messy with it. You get to solve many interesting problems with it. I my real case I had to deal with multiple repeater tags. Here we will have a look at one simple example. Its assume we want to make a JSON with product information. Lets just implement it:

<asp:Repeater ID="ProductJSON" runat="server">
 <HeaderTemplate>
  <script type="text/javascript">
  var products = [
 </HeaderTemplate>
 <ItemTemplate>{ pid: '<%#((Product)Container.DataItem).ProductID%>',
  name: '<%#((Product)Container.DataItem).ProductName%>', 
  image: '<%#((Product)Container.DataItem).Image %>',                        
  summary: '<%#((Product)Container.DataItem).Summary %>',
  price: '<%#((Ecomm.Code.ProductDM)Container.DataItem).Price%>'},
 </ItemTemplate>    
 <FooterTemplate>
  ];</script>
 </FooterTemplate>
</asp:Repeater>
That was it! really? well unfortunately No! Problems occur when your javascipt start using this JSON. You will notice that the last JSON object completes with a comma (which is a syntax error). The hard part for me started from here. How do I eliminate the final comma so that the JSON array is correctly represented. Finally after lot of googling and trails, I got the correct result. Here is the final code:
<asp:Repeater ID="ProductJSON" runat="server">
 <HeaderTemplate>
  <script type="text/javascript">
  var products = [
 </HeaderTemplate>
 <ItemTemplate>{ pid: '<%#((Product)Container.DataItem).ProductID%>',
  name: '<%#((Product)Container.DataItem).ProductName%>', 
  image: '<%#((Product)Container.DataItem).Image %>',                        
  summary: '<%#((Product)Container.DataItem).Summary %>',
  price: '<%#((Ecomm.Code.ProductDM)Container.DataItem).Price%>'}
  <%#Container.ItemIndex==(((List<Product>)ListViewDisplay.DataSource).Count - 1)?' ':','%>
 </ItemTemplate>    
 <FooterTemplate>
  ];</script>
 </FooterTemplate>
</asp:Repeater>
Many of you will now argue why not use some event like PreRender or some other events.. I would say for doing such a thing, when you need to have other complex solutions! I hope this will come helpful to others.

March 30, 2010

How To configure Apache log4net for ASP.Net

Apache log4net is a tool that helps programmer to log outputs to a variety of output targets. Its basically a port of log4j framework and can be used with all types of .Net applications. In this post, we will see how to configure and start using the logging framework in an ASP.Net web application.

You can download the framework from Apache site. Once downloaded, you need to add the reference of Log4net.dll to the project.

Configuring the logging framework to work with your web application can be done by 3 simple steps:

Step 1: Update web.config file
In the web.config file, you will need to add a new section under configSections tag. Notice that you will already have some section in sectionGroup tag. Do not place the new tag in them as this will lead to build errors. You need to add the following:


<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" requirePermission="false" />

Step 2: Configure log4net
Next we need to provide some configurations to log4net. In our example, we are going to store all the logs in a file. You may refer the documentation for other Appenders available. Below is my log4net configuration:
<log4net>
    <appender name="FileAppender" type="log4net.Appender.FileAppender">
      <file value="D:\\Data\\logs\\log.txt" />
      <appendToFile value="true" />      
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%date [%thread] %-5level %logger - %message %newline" />
      </layout>
    </appender>
    <root>
      <level value="ALL" />
      <appender-ref ref="FileAppender" />
    </root>
  </log4net>
There are different ways of presenting this configuration to our framework. You can store the configuration in a separate xml file or use web.config to store it. In this example, I am storing it in web.config. just after ending the configSections tag, I have my log4net configurations. Now, we are ready to start using the logging framework.

Step 3: Start using log4net
To start using log4net, our web application should read the configurations. To do so, need to inform log4net to configure the logging environment. This is done with the help of the statement given below:
log4net.Config.XmlConfigurator.Configure();
I would recommend you add this to Application_Start method in Global.asax so that the logging environment is ready at the start of the applications. Inorder to log any infomation you need to get an instance of the Logger. This is done with the help of GetLogger method as shown below:
private static readonly ILog log = LogManager.GetLogger(typeof(MyclassName));
And finally, you just need to call log.Info, Debug etc methods to log you messages.

March 20, 2010

XML Transformation using C#

XML is now heavily used by developers for describing, transporting and storing data. XSLT is used to transform these XML files into different formats like HTML, XML, PDF and others. In my current project, my requirements are to generate XML and HTML. Here, I will explain how to transform XML file using C#.


Microsoft’s .Net framework provides us with a rich library. It supports XML document manipulation out of the box. All you need to do is use the necessary namespaces:


  • System.Xml
  • System.Xml.XPath
  • System.Xml.Xsl
I have created a simple class for my transformation activates. Below is the complete code:
public class Transformer
{
    private string xmlPath;
    public string xmlFilePath
    {
        get
        {
            return xmlPath;
        }
        set
        {
            xmlPath = value;
        }
    }

    private string xslPath;
    public string xslFilePath
    {
        get
        {
            return xslPath;
        }
        set
        {
            xslPath = value;
        }
    }

    private string htmlPath;
    public string htmlFilePath
    {
        get
        {
            return htmlPath;
        }
        set
        {
            htmlPath = value;
        }
    }


    public void xsltTransform()
    {
       XPathDocument xmlDoc = new XPathDocument(xmlPath);
       XslCompiledTransform xsltDoc = new XslCompiledTransform();

       xsltDoc.Load(xslPath);    

       XmlTextWriter writer = new XmlTextWriter(htmlPath, System.Text.Encoding.UTF8);       
       xsltDoc.Transform(xmlDoc, writer);
       writer.Close();
    }   
}
Lets staight way go to the xsltTransform method. Notice that, I need to set some of my class propeties; xmlPath, xslPath and htmlPath before I call the xsltTransform method.

First, I create a XPathDocument. This class provide a fast read only representation of the XML document. Next I need to load the stylesheet file. I create an instace of XslCompliedTrasform class to perform the transformation. The stylesheet is loaded using the Load method.

Now we are ready for the transformation. You can transform by call the Transform method. The method has over 15 overloads, so you will have to select the most appropriate for you. In my case, I am saving the output as a file to a specific location. I am using XmlTextWriter to do the task and provides the save to location and encoding type as construction parameters.

Here is the sample code:
Transformer tx = new Transformer();
tx.xmlFilePath = "D:\\Pragma\\data\\product.xml";
tx.xslFilePath = "D:\\Pragma\\xsl\\product.xsl";
tx.htmlFilePath = "D:\\Pragma\\output\\product.html";
tx.xsltTransform();
I suggest you try other overloaded methods available for Transform method. That’s all for now, you can expect few more .Net articles in the coming week.

March 02, 2010

Configuring View Resolver for Spring web flow

From the previous post, we learned how to setup spring web flow application. With the minimal set up there are few downsides. One of it is the usage default view revolver. In this post, we are going to see how to configure view resolver.

The major concern with the minimal setup is that, both flow definition XML file and the views should be in the same directory. Also, the default view resolver expect a JSP or JSPX page. If you look at the flow definition in the previous post, you will see that, we have provided the complete filename for the view attributes. What if I want to organize my views in different folders like MVC applications?

To configure view resolver, you need to "what is" and "how to configure" flow builder service. FlowBuilderServices class simply hold the services used by flow builder. When configuring these services, we need to provide concrete service implementations. We will configure a view resolver using the InternalResourceViewResolver. I am also using the JSTL view class and here is my bean definition:


<bean id="viewResolver" 
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" 
value="org.springframework.web.servlet.view.JstlView"/>
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
Well, that's pretty normal for a Spring MVC application. Notice that I have defined a prefix and all my JSP files will reside under WEB-INF/jsp/ folder. Next is the define the flow builder service. This is defined using flow-builder-services tag as shown below:
<flow:flow-builder-services id="flowBuilderService" view-factory-creator="viewFactoryCreator"/>
Since we are configuring the view resolver for our application, we need to provide reference of view-factory-creator. View factory creator is an instance of MvcViewFactoryCreator class. The class detects whether it is running in a Servlet or Portlet MVC environment, and returns instances of the default view factory implementation for that environment. Here is how the bean is configured:
<bean id="viewFactoryCreator" 
class="org.springframework.webflow.mvc.builder.MvcViewFactoryCreator">  
<property name="viewResolvers">  
<list>  
<ref bean="viewResolver"/>  
</list>  
</property>  
</bean>
We will use our previously configured viewResolver to set the viewResolvers propertyof the MvcViewFactoryCreator class.

To sum up the configurations:
<flow:flow-registry id="flowRegistry" 
flow-builder-services="flowBuilderService">
<flow:flow-location id="loginform" 
path="/WEB-INF/flows/simple-flow.xml" />
</flow:flow-registry>
<flow:flow-builder-services 
id="flowBuilderService" 
view-factory-creator="viewFactoryCreator"/>
<bean id="viewFactoryCreator" 
class="org.springframework.webflow.mvc.builder.MvcViewFactoryCreator">  
<property name="viewResolvers">  
<list>  
<ref bean="viewResolver"/>  
</list>  
</property>  
</bean>  
<bean id="viewResolver" 
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" 
value="org.springframework.web.servlet.view.JstlView"/>
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>

Hope this post help people who are trying out Spring web flow.

February 26, 2010

How to setup Spring Web Flow application

Spring web flow is solution for management of web application page flows. It's part of Spring web stack offering and works on top of Spring MVC. I have been working with the framework recently and had few troubles starting off with it. As a beginner to web flows, I had few hiccup ups. So, there is how to setup a minimal Spring web flow application.

This is not a tutorial for experts. What I am about to explain is just the basics and how to get going if you are starting with Spring web flow. You can begin with creation of a web application project using your Eclipse or Netbeans. You need to ensure that you have few jars:


  • Spring Web Flow (http://www.springsource.org/download#webflow). I used the version 2.0.8
  • ONGL (http://www.jarfinder.com/index.php/jars/versionInfo/433). I used version 2.6.7
  • I will assume you already have the Spring framework jars (I used version 2.5.6). I also used JSTL jars
The Spring web flow contains four jars. You need to add only the binding & webflow jars to the project.

Configuring the web.xml
There is no change in web.xml compared to a Spring MVC application. I just have my DispatcherServlet configured and other necessary configurations.

<servlet>
<servlet-name>swft1</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>        
</servlet>

<servlet-mapping>
<servlet-name>swft1</servlet-name>
<url-pattern>*.htm</url-pattern>
</servlet-mapping>
Configuring the application context
I have only one application context file and its named swft1-servlet.xml. Here is my configurations:
<bean id="handlerMapping"
class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<value>/msgform.htm=flowController</value>        
</property>
</bean>

<bean id="flowController"
class="org.springframework.webflow.mvc.servlet.FlowController">
<property name="flowExecutor" ref="flowExecutor" />
</bean>

<flow:flow-executor id="flowExecutor" flow-registry="flowRegistry"/>

<flow:flow-registry id="flowRegistry">
<flow:flow-location id="msgform"
path="/WEB-INF/flows/simple-flow.xml" />
</flow:flow-registry>
Just like a Spring MVC application, I have a used the SimpleUrlHandlerMapping and mapped msgform.htm to flowController. The flowController is an instance of a specialized contoller class available as part of the web flow package. we will configure it with a property named flowExecutor. Flow executor drives the execution of the flow. And its configured with the tag flow-executor. We have a flow registry that holds all the flows for the application. Flows can be defined in multiple files and a registry is maintained. A flow registry is defined using the flow-registry tag as shown above. In our example, I have a single file defining the application flow. The location if the file is defined using the flow-location tag as shown above.

This is minimal the minimal configuration required! You will notice, that there is no view resolver. We will be making use of the default view resolver here. I will further explain this as we go.

Configuring the flow
A flow is described using XML files. And the flow file has to be registered in flow registry. In this example, We have only one file named simple-flow.xml:

<var name="msgObj" class="com.tpblog.web.models.Message"/>

<view-state id="start" model="msgObj" view="message.jsp">
<transition on="sendAction" to="success-state" />
</view-state>

<end-state id="success-state" view="success.jsp" commit="true" />
Please note that I have removed the root element of the xml. I have only used few features to keep it simple. Here we get a message from one screen and its displayed in another (web flow is NOT for these kinda stuff!!!). I have a msgObj that holds the message we type in the first screen (message.jsp). On clicking the submit button, we display success.jsp with the message.

In this flow, I have just two states; a view state and an end state. Notice that, I have specified the JSP files in the view attribute. Since,I am not using any view resolver, I need to specify the complete file name. The JSP files should also reside in the same folder as the flow configuration file. Once you have the basic application running, you can add features to it and modify it with other configurations.

For demo, I have a simple example of user login.In the next post, we will have a look at how to configure the view resolvers.

February 16, 2010

Consuming web service using Spring

With the adoption of SOA in companies, we have many web applications accessing web services which are local and external. My application currently interacts with web services built by other team with in the organization and also with third party. Java frameworks offer different ways to consume web services and we will have a look what spring framework has to offer.

Consuming web services with Spring is very simple. With Spring you will be able to configure a web service client using XML bean configuration. Spring takes care of creating the client stub when the applications starts. You can then access the web service from the Spring bean container.

Spring provides remoting support for web services via JAX-WS with the help of two factory beans, namely LocalJaxWsServiceFactoryBean and JaxWsPortProxyFactoryBean. I will use the latter as it returns a proxy that implements our business service interface. For this tutorial, I will take a public web service available at WebserviceX.NET. For demo, I have taken the whois lookup service. Here is our bean configuration:


<bean id="whoisService" class="org.springframework.remoting.jaxws.JaxWsPortProxyFactoryBean">
<property name="wsdlDocumentUrl"  value="http://www.webservicex.net/whois.asmx?wsdl" />
<property name="namespaceUri"     value="http://www.webservicex.net" />
<property name="serviceName"      value="whois" />
<property name="portName"         value="whoisSoap" />
<property name="serviceInterface" value="com.spweb.services.WhoIsService" />
</bean>
Now, lets have a closer look at the bean configuration. I have defined five properties; wsdlDocumentUrl holds the WSDL URL for the web service we are going to consume. namespaceUri
defines the namespace, you can get this details from the WSDL file. Next comes the serviceName and portName of the web service. And the final property is the service interface. We will have to create the service interface so that we can interact with web service.

When the spring application starts, the bean gets created and we will be able to access the web service through this bean. To access, I injected the bean to one of my controller (I am using MVC) and call the necessary methods through my service interface. Now, lets have a look at our service interface. Its a simple java interface with some annotations and will have all the methods that we call. Here is our service interface:
@WebService(name = "whoisSoap",
targetNamespace = "http://www.webservicex.net")
public interface WhoIsService {

@WebMethod(operationName = "GetWhoIS",
action = "http://www.webservicex.net/GetWhoIS")
@WebResult(name = "GetWhoISResult", 
targetNamespace = "http://www.webservicex.net")
@RequestWrapper(localName = "GetWhoIS", 
targetNamespace = "http://www.webservicex.net",
className = "net.webservicex.GetWhoIS")
@ResponseWrapper(localName = "GetWhoISResponse", 
targetNamespace = "http://www.webservicex.net", 
className = "net.webservicex.GetWhoISResponse")
public String getWhoIs(@WebParam(name = "HostName", 
targetNamespace = "http://www.webservicex.net")String domain);
}
In order to work with web services, you need to study the WSDL file carefully. All the details come from this file. The first annotation is @WebService, which is used to define the interface as a service endpoint interface. In this case, I have specified the two properties namely, name and targetNamespace. The name property holds the name of wsdl:portType and targetNamespace holds the namespace of the the WSDL.

Next we declare methods which will be called. To tie these methods to the web service calls we use the @WebMethod annotation. The annotation specifies the operation name and action URL. Along with this, we also specify @WebResult,@RequestWrapper,@ResponseWrapper. These annotations provide information regarding request and response data types. The @WebParam is used to map the method parameters with the parameters of the web service.

Finally to consume the web service, I simple call the method as shown below:
if(whoService!=null) {
resultString = whoService.getWhoIs("hostname.com");
}
I do not create a instance of the service bean, instead it gets injected when the application starts. Here are few other points to note, I didn't use the Spring web service. The only jar dependency I had was saaj-impl apart from the spring framework's jars.

February 02, 2010

Access Control in ExtJS applications

When you implement large applications using Ext Js, you will definitely come across access control. Your application will have different type of users and you don't expect all users to have access to all features. Basically may have roles or groups defined for users and the big question is how do you implement it on to the front end of your application.

Before we proceed further you should remember an important point that permissions should be always be implemented on server side and JavaScript security is always secondary! This is because anybody with a JavaScript debugger and other web development tools can easily compromise the client side security. So, what is the use of adding client side security?

The client side security is used to improve user experience and abstract user so that he see only features or data that he have access to. So, the next question is how do we do it?

You will find many ways to implement the access control but the important point is avoiding unnecessary JavaScript logic to be downloaded when your access your application. At the same time, you can implement access control by avoiding code execution if its not available to the user.

Approach 1 : Permission Configuration
This is a simple approach wherein permission configurations is used to handle security. According to the role of the user who is accessing the application, a configuration class is dynamically built. This class is used to decide what the user can access and what not. When the user login to the application a JSON is created with list of accessible features.

Approach 2 : Control through Dynamic JavaScript
In this approach we will generate the JavaScript need for the user. Hence he will not get any code that he is not allowed to execute. When an user login to the application, his role or group to which he belongs to is determined. Using his role, the JavaScript is generated dynamically using a server side script (I used JSPs). The JavaScript file inclusion will look like:
<script type="text/javascript" src="scripts/application.jsp?role=${userRole}"></script>
Inside application.jsp, the administrator menu is only accessible if the user has the appropriate role.
<c:if test="${userRole=='ADMIN'}">

topMenuObject.add({id:'adminMenu',
text: 'Administrator',
handler: adminMenuHandler});
</c:if>

This approach has some disadvantages as well. The development can be little messy because you are coding JavaScript in JSP file. Also, there is an overhead created when you dynamically generate the JavaScript all the time. You will have to use caching mechanism in-order to reduce the overhead.

That's all for now. You are welcome to comment on these approaches and share other techniques if you have.

Read other ExtJS related articles!