October 11, 2013

Clearing SharePoint Designer Cache


Sometimes, SharePoint Designer just goes haywire! You try to edit or publish a workflow and it says the item cannot be displayed. At times, it even says that the site is disabled to be edited from SharePoint Designer. But, you know what you are doing and are sure that these are just "crazy" errors!

All you need to to fix these kind of issues are to clear the cache and make SharePoint Designer feel that you are starting from scratch. SharePoint Designer's cache is spread around three different folders. Close any running instance of designer and delete all folders and files in the following directories:
  1. C:\Users\<username>\AppData\Local\Microsoft\WebsiteCache
  2. C:\Users\<username>\AppData\Roaming\Microsoft\SharePoint Designer\ProxyAssemblyCache
  3. C:\Users\<username>\AppData\Roaming\Microsoft\Web Server Extensions\Cache
Fire up your SharePoint Designer and you should get a clean start.

April 20, 2013

Dashboard Designer: Cannot Connect to PerformancePoint Service

After configuring my PerformancePoint Service on SharePoint 2013. This error hit me when trying to create a new data source from Dashboard Designer.


Here are the steps to make sure you have your PerformancePoint service configured properly.

  1. Make sure you have the PerformancePoint Service and Secure Store Service started.


    You can check this by going to Central Administration | Application Management | Service Applications |Manage services on server
  2. Make sure you have a Secure Store service application running.


     You can check this by going to Central Administration | Application Management | Service Applications | Manage service applications.

    Ensure that you have configured the service application properly.
  3. Make sure you have a PerformancePoint Service application running


    You can check this by going to Central Administration | Application Management | Service Applications | Manage service application.

    Ensure that you have configured the service application properly. Click on your performance point service application to take you to the management screen as shown below:
    Verify you application setting by selecting PerformancePoint Service Application Settings.

    Make sure you have your secure store displayed and you are using your appropriate unattended service account (If you are using the service account, click Change User and reenter the username and password).
  4. And finally check service application associations.

    Go to Central Administration | Application Management | Service Applications | Configure service application associations

    Click on default and ensure that your performance point service is selected.


These steps should ensure that you get your PerformancePoint service up and running.

February 28, 2011

How to execute custom queries on Recess framework

Working with Recess framework can be fun if you are ready to dig into the source code of the framework. Due to its small code footprint, going through the code is no trouble for even a beginner. In this article, we will have a look at how to execute custom mysql query.


Recess framework keeps a registry of data sources available for an application. The Database class provides this registry and provides static methods to access the data sources. The class holds all the data sources in an array. It also has a separate variable to hold the default data source.

The framework does provide you with its own ORM and makes CRUD very simple and zero lines of coding. But there are times when you need to execute complex quires against our data sources. I assume you have set your data source as default in recess-conf.php. Now, to get hold of your PDO object (data source), you can simple call the getDefaultSource method. eg:
$pdo = Databases::getDefaultSource();
And here is an example of executing the query:
$pdo = Databases::getDefaultSource();
$sql = "SELECT * FROM MyTable";
$rows = $pdo->query($sql);
foreach ($rows as $row)
{
 /* Process the selected rows */
}

Other methods of Database class
The Database class also provides access to named data sources through other static methods. You can use the addSource and getSource methods to add and get a named source.

You can get the array containing all the data source using the method getSources. And also set the default data source using the setDefaultSource method.

February 23, 2011

Multiple file upload using ExtJS & ASP.Net MVC

Recently I had to build an image gallery for one of my project which used ExtJS & ASP.Net MVC. The gallery consisted of many components, and I will explain the multiple image file upload functionality used in this gallery.


There are many ExtJS plugins already available for file upload that uses flash. One of my requirements was to avoid flash in my project. So, I could not use plugins like
Awesome uploader or UploadForm. So, if you need some fancy looking component & functionality, I suggest you have a look at them as well!

Here I have a simple uploader form that can be used for any server side. I will be using ASP.Net MVC. I have clean URLs as my application follows REST. Let’s have a look at the javascript first:
UploaderWindow =  Ext.extend(Ext.Window,{
    title: 'Upload Window',
 closeAction: 'close',
 id: 'upload-window',
 folderID: null,
 initComponent : function() {
  
  // Upload Form
  var uploadForm = new Ext.form.FormPanel({
   id: 'upload-form',
         fileUpload: true, 
         frame: true,  
   border: false,      
         bodyStyle: 'padding: 10px 10px 0 10px;',
   labelWidth: 50,
   defaults: {
          anchor: '100%'
         },          
   items: [{
             xtype: 'hidden',
             name: 'fieldCount',
    id: 'fieldCount',
    value: 0             
   },{
    xtype: 'hidden',
    name: 'folderID',
    id: 'folderID',
    value: 0
   },{
             xtype: 'fileuploadfield',
             emptyText: 'Select an image',
             fieldLabel: 'Image',
             name: 'file0'            
   }],
   buttons: [{
    text: 'Add File',
    iconCls: 'add_icon',
    handler: function(button,event) {
      
     var fIndex = parseInt(uploadForm.findById('fieldCount').getValue()) + 1;
     uploadForm.add(newField('file' + fIndex));
     uploadForm.findById('fieldCount').setValue(fIndex);
      
     uploadForm.doLayout();
            
    }
   },{
    text: 'Upload',
    handler: function(button, event){
     
     if (uploadForm.getForm().isValid()) {
      uploadForm.getForm().submit({
       url: '/Gallery/Upload',
       waitMsg: 'Uploading your photo...',
       success: function(form, o){        
        alert('Successfuly uploaded!');
       },
       failure: function(form, o){
        alert('Error in uploading the files');
       }
      });
     }
    }
   },{
    text: 'Cancel',
    handler: function() {
     var win = Ext.getCmp('upload-window');
     win.close();
    }
   }]
  });
  
  // Initial Configuration for the window
  var initConfig = {
   resizeable: false,
   modal: true,
   frame: true,
   width: 400,
   autoHeight: true,
   items: [uploadForm]
  };
  
  Ext.apply(this, Ext.apply(this.initialConfig, initConfig));
        UploaderWindow.superclass.initComponent.call(this);
 },
 onRender: function(){
  var fidField = this.upForm.findById('folderID');
  fidField.setValue(this.folderID); 
  UploaderWindow.superclass.onRender.apply(this, arguments);
 } 
});
I have extended Ext.Window class to create my component. The window provides all the controls necessary to upload multiple files onto the server. The upload form is basically embedded within the window. This helps in reuse of the entire component and also helps in customization. In the new component, we have some custom parameters. Once, such parameter is folderID (the default value is null). But when the upload window is created, I would pass a real value. On the server side, the uploaded images are stored according to the folderID passed.



The initComponent method is used to initialize the component. I have the form panel and its elements defined here. Note that I a hidden field to hold the number of files being uploaded (fieldCount) and is set to zero. I also have a field to hold the folder information. This hidden field is populated when the window is instantiated. The file selection functionality is provided by the well known ExtJS component: FileUploadField.

Each time the user click on “Add File” button, we create a new element of the type FileUploadField. This is done with the help of newField method:
function newField(name) {
    var rulesField = new Ext.ux.form.FileUploadField({
        name: name,
        emptyText: 'Select an image',
        fieldLabel: 'Image'
    });
    return rulesField;
}
Now, let’s have a look at the server side code. Our server side is accessed through the URL /Gallery/Upload and the method will be obviously POST. One of my requirements was to upload only images so; I added a simple check for the file extension on the server side. You could do the same on the client side as will. Here is the server side code:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Upload()
{
    string[] supportedTypes = new string[]{ "png", "gif", "jpg", "jpeg" };
    int count = int.Parse(Request.Params["fieldCount"]);
    int folderID = int.Parse(Request.Params["folderID"]);
    
    try
    {
        for (int i = 0; i <= count; i++)
        {
            HttpPostedFileBase postedFile = Request.Files["file" + i];
            if (postedFile != null)
            {
                string x = Path.GetExtension(postedFile.FileName);
                if (supportedTypes.Contains(x.TrimStart('.')))
                {
                   // Process the image
                } else {
                   // document not supported!
                }
            }
        }
        
    }
    catch (Exception e)
    {
        
    }
}
Improvements: There is always space for improvements. You can go ahead with lots of modifications to this component. By end of the day, I had lot of changes. Few improvements are:
  1. Removing added files from the form. 
  2. Client side validations.
  3. Option for entering meta data for the images being uploaded.
  4. Progress bar like other components mentioned above. .. etc 
Your comments are welcome. Enjoy coding! :)

Read other ExtJS related articles!

February 14, 2011

Recess framework - An ignored PHP RAD tool!


My new personal project is being built on PHP stack instead of Java or .Net! My team (group of friends) not I are regular PHP coders and we decided to give PHP a try. Our application needed a simple MVC framework, REST support & small learning curve. During the search I stumbled upon Recess! - A RESTful PHP framework.

Recess! is a RESTful PHP framework that claims to be built for implementing RESTful application with strong object-oriented design, annotations and RAD tools. I decided to give it a try even though we have plenty of famous frameworks like Zend stack, CakePHP, Symphony etc.

I got quite exited after viewing the first screen cast about the framework. At the same time, I was little disappointed to see the framework was versioned 0.2 and dated to 2009. Nevertheless, I decided to download and try. I got my first blockade with the framework in 20 minutes to deploying it on my PC. Turned out that, the version 0.2 had bugs and I had to switch to the cutting edge version. With the latest version, I was running my first application in no time. But when you go beyond “Hello Wold” applications you will find real trouble due to lack of documentation.

The framework introduces annotations to PHP! Unlike java, annotation symbol used is ‘!’ annotation. Applications routing information, data model relationships, etc. are all provided in the form of annotations. In addition to this the framework provides an interactive toll to create application, scaffolding and manage your data models. Yes! You have CLI tools for other frameworks but this is simple and real RAD. Apart from these features, the framework had a plugin architecture and easy to extend.

But, even with these features, I don’t see the framework becoming popular. One reason for this could be the lack of documentation and tutorials. The framework lacks documentation and you will have to read the source code in order to understand and fix your issues. The community is also very small, so you are left out in the cold. This actually takes away the ‘RAD’ in Recess and your learning cure shoots up.

Another reason for lack of community would be because the framework has had very little changes after 2009. With no active development happening, new developers (like me) usually do not try it and end up with other frameworks.

Here is my final take on the framework:
Pros:

  • Create RESTful application quickly and with great ease.
  • GUI based tool for creating project structure, scaffolding etc.
  • Declarative PHP with the help of annotations.
  • Loosely coupled Model-View-Controller.
  • Makes use of Don’t Repeat Yourself (DRY) philosophy & practice.
  • Caching-oriented architecture.
  • Provides a simple ORM library that is integrated into the framework.

Cons:

  • Lack of community interaction and support.
  • Lack of Manuals, tutorials and API documentation.
  • Very slow development of the framework.
  • ORM is still not powerful enough compared to other available libraries.

Recess framework is really good RAD and its developers and community should take it forward. It makes PHP programming real fun!

January 28, 2011

Cascading Combo box in ExtJS

This week, two Techno Paper readers had approached me with questions on cascaded loading of combo box in ExtJS. Rather than replying them with mails, I decided to put it up for on the blog so other readers can also get it. In this tutorial I will explain how to cascade the loading of combo box options.


Cascading combo box can help in avoiding huge combo boxes. You can provide the user with a drill down of options that you offer and this helps them narrow down the options to select. When you have large data to display, it would be better to avoid combo boxes and go for a list view.

For now, let’s take a simple form where the user is asked to select geographical location & language. The selection of city is made by selecting country and region. So, we have three combo box:
  • To select region (Continent)
  • To select country
  • To select city
User does a drilldown on these three combos to finally select the city. First the user selects the continent. Selection triggers loading of all the countries in that continent. And similarly selection of country will trigger the loading of cities of that country.

Now, let’s get our hands dirty with the code. We will have a data store for each of the comobo boxes. In this tutorial, we will use Json store. You should be able to use any other store Ext JS library provide. Let me introduce the store for holding continents:
var mainStore = new Ext.data.JsonStore({
 autoLoad: true,
 url: '/GetContient',
 fields: ['item','value']
});
The store is very simple and straight forward. We set three properties of the json store. Unlike other dropdowns, the continent is starting point of our cascading. In order to load it along with the form, we will use autoLoad property of the stores. You need to define the url from which the store will be loaded & the fields array provides information on the fields.

The other two stores are slightly different. They will be loaded through selection of the respective drop downs. So, they are not initially loaded with values. Here are the stores for country and city:
var countryStore = new Ext.data.JsonStore({
 autoLoad: false,
 pruneModifiedRecords: true,
 url: '/GetCountry',
        fields: ['item', 'value']                   
});
     
var cityStore = new Ext.data.JsonStore({
 autoLoad: false,
        pruneModifiedRecords: true,
        url: '/GetCity',
 fields: ['item', 'value']                   
});
We have set pruneModifiedRecords property inorder to clear records each time the store is loaded. Now we have our stores ready. Let’s code our form and its fields.

Apart from the three drop downs, I will have a text field for keying in the language. We will render the directly onto the HTML document’s body tag. So, here is the code:
var Example = new Ext.Panel({
    title: 'Example of Cascading combos',
    renderTo: document.body,
    width: 400,       
    frame: true,
    items: [{
        xtype: 'form',
        url: '/FormSubmitURL',
        id: 'ex-form',                                                                      
        method: 'post',
        defaults: {
            anchor: '95%'
        },
        items: [{
            xtype: 'combo',
            fieldLabel: 'Continent',
     emptyText: 'Select a Continent',
            store: mainStore,                            
            editable: false,
            allowBlank: false,
            forceSelection: true,
            valueField: 'value',
            displayField: 'item',
            triggerAction: 'all',
            hiddenName: 'continent',
            id: 'continent',
  listeners: {        
          'select' : function(field,nval,oval) {
    countryStore.load({
                      params: {'id': nval.data.value }
             });
    }
   }
        }, {
   xtype: 'combo',
            fieldLabel: 'Country',
   emptyText: 'Select a Country',
            store: countryStore,
   mode: 'local',
            editable: false,
            allowBlank: false,
            forceSelection: true,
            valueField: 'value',
            displayField: 'item',
            triggerAction: 'all',
            hiddenName: 'country',
            id: 'country',
   listeners: {
    'select' : function(field,nval,oval) {
     cityStore.load({
                params: {'id': nval.data.value }
             });
    }
   }
  },{
   xtype: 'combo',
            fieldLabel: 'City',
   emptyText: 'Select a City',
            store: cityStore,
   mode: 'local',
            editable: false,
            allowBlank: false,
            forceSelection: true,
            valueField: 'value',
            displayField: 'item',
            triggerAction: 'all',
            hiddenName: 'city',
            id: 'city'       
  },{
   xtype: 'textfield',
            fieldLabel: 'Language',
            name: 'language',
            id: 'language'
        }],                        
        buttons: [{
            text: 'Submit',
            handler: function() {
    alert('Submit the form');
   }
        }]
    }]
});
Now, lets focus on one of the combo boxes. Notice how we cascade the loading of the combo boxes using the select event. The select event callback function provides us with all the information we need. It has three parameters and they are:
  1. The combo box
  2. The newly selected field record
  3. Numerical index value of old selection
From the callback’s parameters, we get the new selection information, which is used to load the country or city data store using the load method.

You can download the Javascript source code and try it. I have not included the any server side or ExtJS files with the package. Please provide your comments and suggestions. :)

Read other ExtJS related articles!

January 18, 2011

Working with .Net serialized dates in ExtJS

ASP.Net’s JSON serialize encodes DateTime instance as a string. If you return a JSON from a MVC contoller, you will notice your data encoded in the form:
\/Date(1295163209177)\/

This is basically nothing but Jan 16 2011 10:33:29! ExtJs components like data grid, datepicker do not consume this format and needs to be transformed.

Why does Microsoft serialize DateTime in this form?

One of the major disadvantages of using JSON is its lack of date/time literal. The support for date and time values is provided by the Date object in javascript. So, In order to represent the date and time, there are two options available:

1. To express the data as string
2. To express it in numerical form.

The numeric form would be the the number of milliseconds in Universal Coordinated Time (UTC) since epoch. But in either form, we still have the issue of not being able to identify it as date / time. In order to overcome this, MS came up with encoding DateTime values as string in the form:
\/Date(ticks)\/

How to fix it in ExtJS?

Deserializing in ExtJS can be done with the help of Date class. You can use the parseDate static method to convert the serialized date into Date object.
var dt = Date.parseDate(date,'M$');
dt.format('d/m/y');
The deserialized dates can be displayed in any desired format! :)

Read other ExtJS related articles!

January 11, 2011

Getting "Dive into HTML5" for Free!!!

There are many references available for HTML5. But, there is one reference you should not miss as a web developer.

Dive into HTML5 by Mark Pilgrim is free for the public. Site: http://diveintohtml5.org/

For those you need the hard copy, you can get the book titled HTML5: Up & Running by the same author (Costs around $18).

January 10, 2011

Creating toolbar in ExtJS Viewport

Building application UI using Ext JS can be complex and confusing for new comers. When you build applications, you usually make use of the border layout for placing different components onto the main screen of your application. In most of the cases you will require a toolbar with menus and buttons. But the viewport component has a catch.


Unlike the panel component of Ext JS, Viewport does not have a tbar option. So, you cannot attach a toolbar component into viewport. The best solution is to convert north region of your application to a toolbar.

To keep things simple, will have north, west and center regions of my border layout. I will also avoid handler methods and other actual content of the application. First lets simple define the application layout alone.
var application = new Ext.Viewport({
    renderTo: document.body,
    layout: 'border',
    items: [{
        region: 'north',
        border: false,
        frame: true,
        html: 'this is north'        
    }, {
        region: 'west',
        layout: 'fit',
        width: 200,
        border: true,
        frame: true,
        html: 'This is the left panel'
    }, {
        region: 'center',
        html: 'This is the center panel',
        frame: true,
        border: true
    }]
});
Once you have the layout, you just need to convert the north region into a toolbar. To do so, you will have to create a tbar instance in the north region’s panel. The complete code given below:
Ext.onReady(function(){
    Ext.QuickTips.init();
        
    var application = new Ext.Viewport({
        renderTo: document.body,
        layout: 'border',
        items: [{
            region: 'north',
            border: false,
            tbar: [{
                text: 'New',
                menu: [{
                    text: 'Add New X'
                }, {
                    text: 'Add New Y'
                }]
            }, {
                text: 'Refresh'
            }, {
                text: 'Tools'
            }, '->', {
                text: 'Options',
                iconCls: 'options_icon',
                menu: [{
                    text: 'User Info'
                }, {
                    text: 'Settings'
                }, {
                    text: 'Switch Theme'
                }]
            }, {
                text: 'Help'
            }, '-', {
                text: 'Logout'
            }]
        }, {
            region: 'west',
            layout: 'fit',
            width: 200,
            border: true,
            frame: true,
            html: 'This is the left panel'
        }, {
            region: 'center',
            html: 'This is the center panel',
            frame: true,
            border: true
        }]
    });    
});
You will have to add handlers for the buttons or menu you added to the toolbar. You can add the appropriate handler function to the property named handler. For example, let’s assume we are adding a handler to “Add New X” menu item:
text: 'New',
                menu: [{
                    text: 'Add New X',
      handler: function() {
Ext.Msg.alert(‘Alert’, 'Add new X item!');
} 
                }, {
                    text: 'Add New Y'
                }]
As always your ideas, doubts and comments are always welcome. Also share your experience on web technologies on Techno Paper facebook page!

Read other ExtJS related articles!

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.