Showing posts with label tutorial. Show all posts
Showing posts with label tutorial. Show all posts

Tuesday, July 2, 2013

Struts2: How to display data contained in a list/map/List of Object from Java to screen

Today we will learn how to pass data stored in List or Map from Java classes to screens (JSP in this case) using Struts2
Display list/map data from java
using Struts2

Pre-requisite: You need to include the struts tag libaries in your web project and put the below line in your JSP to use the tags.
 <%@ taglib prefix="s" uri="/struts-tags"%>

Let's start with a list of string objects.

1. Suppose in your action class (Java) you have a list of String objects which you want to display on the screen.
For eg. List of Movies:
  • Batman Begins
  • The Dark Knight
  • The Dark Knight Rises
  • Inception
  • Memento
  • The Prestige
Yeah you get it! Like millions I am also a Nolan fan.
Now to display this list on the screen you need to create a List object in your action.

 private List movieList;

Now create the required getter/setter methods for this object as below.
Tip: For eclipse users, short-cut to creating getters/setters is ALT+SHIFT+S + R

public List getMovieList() {
  return movieList;
}
public void setMovieList(List movieList) {
  movieList.add("Batman Begins");
  movieList.add("The Dark Knight");
  movieList.add("The Dark Knight Rises");
  movieList.add("Inception");
  movieList.add("Memento");
  movieList.add("The Prestige");  
  this.movieList = movieList;
}

As you can see I have added the movies to the movieList object.
Now coming to the JSP, you will have to use the "iterator" tag of the struts library to iterate through the object.

 <s:iterator value="movieList"> //value field contains the name of the object in Java.  
 <div movie="<s:property>"><s:property /></div> //<s:property /> will get the movie names as there is only single value fields in the list  
 </s:iterator>  

That's pretty much it. You will get the movie names on your screen.

2. Now let's consider you have a Map and you want to use data from your map object on the screen.

First we will create a Map object just like we did for the list object.

 private Map<String, String> movieMap;  

And the getters/setters

 public Map<String, String> getMovieMap() {  
      return movieMap;  
 }  
 // I have created a movie:year of release(key:value) map  
 public void setMovieMap(Map<String, String> movieMap) {  
      movieMap.put("Batman Begins", "2005");  
      movieMap.put("The Dark Knight", "2008");  
      movieMap.put("The Dark Knight Rises", "2012");  
      movieMap.put("Inception", "2010");  
      movieMap.put("Memento", "2000");  
      movieMap.put("The Prestige", "2006");  
      this.movieMap = movieMap;  
 }  

Now in your JSP, let's suppose you want to create a node/div which will display the movie name and an attribute field storing the year of release. You need to do something like this.

 <s:iterator value="movieMap">  
 <div year="<s:property value="value">"><s:property value="key" /></div>  
 </s:iterator>  

And lastly what if you have a List of Java objects and you need to extract data from those Java objects?
Let's suppose you have a Movie class as below:

 public class Movie {  
      private String name;  
      private int year;  
      private String director;  
      private String genre;  
      public String getName() {  
           return name;  
      }  
      public void setName(String name) {  
           this.name = name;  
      }  
      public int getYear() {  
           return year;  
      }  
      public void setYear(int year) {  
           this.year = year;  
      }  
      public String getDirector() {  
           return director;  
      }  
      public void setDirector(String director) {  
           this.director = director;  
      }  
      public String getGenre() {  
           return genre;  
      }  
      public void setGenre(String genre) {  
           this.genre = genre;  
      }       
 }  

And you create a list of this Movie objects in your action class

 Movie movie = new Movie();  
 movie.setName("The Dark Knight");  
 movie.setYear(2008);  
 movie.setDirector("Nolan");  
 movie.setGenre("Action");  
 .  
 .  
 // similarly you create objects for other movies  
 List<Movie> movieList = new ArrayList<Movie>();  
 movieList.add(/*all the above movie objects*/);  

In the JSP, you need to do two things.
  1. Iterate over the list
  2. Use a local variable to extract the individual properties from the java object
 <s:iterator value="movieList" var="eachMovie"> //here eachMovie is a local variable
 <div year="<s:property value="#eachMovie.year">" //attribute year created with the correspoding value  
       director="<s:property value="#eachMovie.director">" //similarly director and genre are created  
       genre="<s:property value="#eachMovie.genre">">  
 <s:property value="#eachMovie.name"></div> // name of the movie display on screen.  
 </s:iterator>  

That's it! That's how you bind your java objects with your JSP using struts and access the data.
Please post your comments and views on this tutorial.

Sunday, June 23, 2013

ExtJs: How to filter data of a store in extjs: A small and useful tutorial

Damn I hate these English summers. It's not summer if it's gonna rain every now and then!
It's disappointing to see a final of a tournament getting washed out and that too when India was looking so invincible. Sigh! (This was when I thought there won't be a match today).


India wins Champions Trophy
India wins Champions Trophy 2013
But guess what, rain stopped and there was a 20 overs match eventually. And India came out victorious in an absolutely spectacular fashion. Great to see them finally lift the cup. They totally deserved it.

Anyways, today I will show you how to set filters on the data of a combobox (or rather any component having a store).
We shall first start with creating simple store containing data for a combobox: 

// The data store containing the list of cars  
 var cars = Ext.create('Ext.data.Store', {  
   autoLoad: true,  
   fields: ['key', 'name'],  
   data: [{  
     "key": "Benz",  
       "name": "Mercedes-Benz"  
   }, {  
     "key": "Audi",  
       "name": "Audi"  
   }, {  
     "key": "Ferrari",  
       "name": "Ferrari"  
   }, {  
     "key": "Prius",  
       "name": "Prius"  
   }, {  
     "key": "Lamborghini",  
       "name": "Lamborghini"  
   }, {  
     "key": "BMW",  
       "name": "BMW"  
   }]  
 });  

Now I will create a combobox and assign the above created store to it.
Note: Here I am creating a toolbar and adding the combobox into it. We will need the filter elements along with the combobox further.

Ext.create('Ext.toolbar.Toolbar', {
    renderTo: document.body,
    items: [{
        xtype: 'combobox',
        fieldLabel: 'Choose Car',
        labelWidth: 70,
        store: cars,
        queryMode: 'local',
        displayField: 'name',
        valueField: 'key'
    }]
}); 

So now you have a combobox displaying all the cars that we have added to the store.
Now let's say we want to add a filter on this data. 
We want two radio buttons, one for BMW and other for Benz. 
If a user selects BMW then only BMW car should be available for selection in the combobox.
And similarly, if he selects Benz then only Mercedes-Benz should be available.
So for this we will first add two radio buttons to our existing toolbar.

 Ext.create('Ext.toolbar.Toolbar', {
    renderTo: document.body,
    items: [{
        xtype: 'combobox',
        fieldLabel: 'Choose Car',
        labelWidth: 70,
        store: cars,
        queryMode: 'local',
        displayField: 'name',
        valueField: 'key'
    }, {
        xtype: 'fieldcontainer',
        fieldLabel: 'Filter',
        defaultType: 'radiofield',
        labelWidth: 40,
        layout: 'hbox',
        items: [{
            boxLabel: 'Benz',
            name: 'size',
            id: 'radio1'
        }, {
            boxLabel: 'BMW',
            name: 'size',
            id: 'radio2'
        }]
    }]
});

Now you have your two radio buttons. But they are not filtering the data as we wanted.
To do that we have to handle the filtering in the radiobutton's change event.

 listeners: {
    change: function (radio2, newvalue, oldvalue) {
 //if the newvalue is true that means the radio button is selected
 if (newvalue) {
  // first clear all the existing filters
  cars.clearFilter();
  // apply filter to the store. Field on which we are filtering is "key"
  cars.filter('key', 'Benz');
        }
    }
}

We just need to add a similar listener to the other radio button as well. 
Everything remains same except for the filter value

cars.filter('key', 'BMW');

What if you need multiple filters like say you want to see both Benz as well as BMW in the dropdown.
Add another radio button which will filter on both Benz and BMW.

{
 boxLabel: 'Both',
 name: 'size',
 id: 'radio3',
 listeners: {
  change: function (radio3, newvalue, oldvalue) {
            if (newvalue) {
    // first clear all existing filters
    cars.clearFilter();
    // use filterBy() to create a customized filter
    cars.filterBy(function (record) {
     // if the key matches either Benz or BMW then return that record
     if (record.get('key') == 'Benz' || record.get('key') == 'BMW') return record;
    });
   }
        }
    }
}

And lastly you will want to clear all your filters and get the original set of records back.
This is easy and if you have noticed it is something which we have already been doing.

{
 boxLabel: 'None',
        name: 'size',
 id: 'radio4',
        listeners: {
  change: function (radio4, newvalue, oldvalue) {
   if (newvalue) {
    // clear all filters.
    cars.clearFilter();
   }
  }
 }
}

There you go.
Now you can apply filter to all your stores

JSFiddle Demo

Hope you guys find this useful.
Please leave your comments and suggestions here.

Friday, June 14, 2013

ExtJS: How to create static and dynamic trees

Today I am going to show how to create static and dynamic trees in ExtJS.
Create a static/dynamic tree like this one here.

Static/Basic trees: Creating static trees is quite easy and straightforward.
  • You will need a data model to hold your tree's data (Nodes).
  • Create a tree store and add the above model to it.
  • Set the above store to a tree panel and display the panel on the screen.
First we will create our model.
Let's create a "Car" model having different cars as its children.
You can see we have added our cars in the "children" property of the model.
"leaf" config is used to set whether the root will be a branch or a leaf.

  Ext.define('Car', {
    extend: 'Ext.data.Model',
    fields: [{
        name: 'name',
        type: 'string'
    }],
    proxy: {
        type: 'memory',
        data: {
            success: true,
            children: [{
                name: 'Cars',
                leaf: false, // this is a branch   
                expanded: false,
                children: [{
                    name: 'Mercedes-Benz',
                    leaf: true // this is a leaf node. It can't have children. Sad! :-(   
                }, {
                    name: 'Audi',
                    leaf: true
                }, {
                    name: 'Ferrari',
                    leaf: true
                }]
            }]
        }
    }
});

Now let's create a TreeStore object and attach our model to it.

  var store = Ext.create('Ext.data.TreeStore', {
    model: 'Car'
}); 

Now last step add our tree store to a Tree panel so that we can view our tree on screen.

  Ext.create('Ext.tree.Panel', {
    title: 'Car Simple Tree',
    width: 200,
    height: 150,
    store: store,
    rootVisible: false,
    lines: true, // will show lines to display hierarchy.    
    useArrows: true, //this is a cool feature - converts the + signs into Windows-7 like arrows. "lines" will not be displayed
    renderTo: Ext.getBody(),
    columns: [{
        xtype: 'treecolumn',
        dataIndex: 'name', // value field which will be displayed on screen   
        flex: 1
    }]
});

JSFiddle Demo
That's pretty much it. Just place this panel wherever you want your tree.

Now let's create a dynamic tree programmatically.

This is very much similar to what we did for the static tree.
Only difference is that we will have to add the children to our root node one by one.

 var carTree = new Ext.tree.TreePanel({
    title: 'Car Dynamic Tree',
    useArrows: true,
    lines: false,
    height: 150,
    width: 200,
    renderTo: Ext.getBody()
}); 

Now create a root node and add it to the tree panel using "setRootNode()" function.


var carRootNode = {
    name: 'Cars',
    text: 'Cars',
    expanded: true,
    leaf: false,
    children: []
};
//set root node
carTree.setRootNode(carRootNode);

Now if you have an array/store of data which you want to add to a tree, you need to iterate over each record and append the record to your root node.
In my case I have got a store. So I will iterate over my store, get each record and append it as a child.

 //get the root of the tree
var root = treeCarsPanel.getRootNode();

//iterate over your store and append your children one by one
carStore.each(function (rec) {
    var childAttrModel;
    //Create a new object and set it as a leaf node (leaf: true)  
    childAttrModel = {
        name: rec.data.name,
        text: rec.data.name,
        leaf: true,
    };
    // add/append this object to your root node 
    root.appendChild(childAttrModel);
}); 

Refresh your panel.

 treeCarsPanel.doLayout(); //refresh layouts form most cases  

And show your panel to your users.

treeCarsPanel.show();

JSFiddle Demo

That's it! we are done.
Hope you find this useful. Leave your comments/suggestions.

Wednesday, June 12, 2013

Extjs: store.proxy.extraParams is undefined only in Internet Explorer 8; works fine in FF, chrome


White walker from Game of Thrones season 3


Just done with the Game of Thrones's last episode of season 3.
It has left me both sad and happy at the same time.
Sad cause no more game of thrones for quite sometime now.
Happy cause now I have time to do other things, one of which is writing today's post.

Today I faced this very peculiar problem while working with ExtJS store.
I was testing my code in Google Chrome and was quite happy to see it work like a charm.
Then I tried to check the same screen in IE8 and bam! It crashed!!

Reason being:
store.proxy.extraParams is undefined

Now let me show you my store first:
 var fieldsStore = new Ext.create('Ext.data.Store', {  
      model : 'FieldsModel',  
      proxy : {  
           type : 'ajax',  
           url : 'action_getDetails',  
           extraParams : {  
                queryID : queryID  
           },  
           reader : {  
                type : 'json'  
           }  
      }  
 });  

So in my store I had an extraParams field which I was setting before loading the store.
This is what I was doing earlier

fieldsStore.proxy.extraParams.queryID = arrQuery.queryId; //set extraparams field
fieldsStore.load() //load the store

And this was working perfectly fine in Chrome as well as Firefox.
But turns out it gave error in my IE8.

After googling a bit I even tried calling it in this way

fieldsStore.getProxy().setExtraParam('queryID', arrQuery.queryId); //set extraparams field

This time it said
Object doesn't support this property or method

Damn, this was mind boggling and annoying at the same time.
Later, thanks to a lot of tweaking in the chrome developer tool, I found this alternative:

fieldsStore.proxy.extraParams = {queryID : arrQuery.queryId};

Apparently this worked in all of the above mentioned browsers!
Honestly I am still trying to figure out the reason why IE8 wants a JSON while other browsers don't throw any of such tantrums. So for now am gonna continue with the above fix.

Please post your comments and alternatives (if any) to this issue.

Tuesday, June 11, 2013

Ext-JS: Form Submit always returns to the failure block

Got late in writing today’s post.
I was busy watching the India vs West Indies cricket match of the Champions Trophy. Well it was a good match and glad India won it quite convincingly in the end.
India winning the match against WI
thanks to Jadeja and Dhawan


It was a pleasant day at the office today overall for me. No major hiccups but this one thing was really troubled me for quite some time. 

I had an ExjJs form where I was uploading an excel file to the server, processing it and sending success/failure messages back to the client. 

When I wrote the code I went with an assumption that if any error occurs at the server (while doing the IO operations on the file), the control will automatically reach the “failure” handler of the AJAX call. Otherwise, it will execute the code inside the “success” handler.

Turned out the control always reached the failure handler even in case of successful processing! Quite baffling to me at first. 

But later I realized that the AJAX call requires a “success” parameter (Boolean) inside the response from server. The value of this parameter will determine which handler to invoke.

So this is what I did. 
Now please note, there may be many other better ways to handle this. 

So my form.submit method looked like this:

 form.submit({  
      url : 'url_to_call_Action_method?fileName='+ Ext.getCmp("FileControl").value,  
      data : {  
           fileName : Ext.getCmp("FileControl").value  
      },  
      // success handle  
      success : function(fp, o) {   
           //Parse the JSON string, in case of success, returned inside the response object  
           var flds = JSON.parse(o.response.responseText);  
           // do further operations  
      },  
      //failure handler  
      failure : function(fb, o) {  
           //Parse the JSON string, in case of failure, returned inside the response object  
           var flds = JSON.parse(o.response.responseText);  
           // show error to the user  
           ShowExtError(flds.errors);  
      }  
 });  

Now in case of success what I was expecting in return from the server was something like this:

 {"cols":[
         {"header":"request_id","dataType":"Integer","fieldFound":false,"seq":1},
         {"header":"employee_code","dataType":"Integer","fieldFound":false,"seq":2}
        ]
}  

But like I mentioned the control was always going inside the "failure" block and never in the "success" block.

So this is what I did:

In my Java (Action) class I explicitly {"success" : true} in a map object in case of successful processing of the file

 Map map = new HashMap();  
 map.put("success", true); //explicitly setting success = true  
 map.put("cols", headers); // my cols object which I was expecting at the client  
 Gson gson = new Gson(); // created a temporaray Gson object  
 String str = gson.toJson(map); // converted map to JSON string  
 response.setContentType("text/html; charset=UTF-8"); // set the content type  
 response.getWriter().print(returnMsg); //write the JSON string to be returned  

And if there was any error/exception while processing I set the success parameter to false. Like this:

 Map map = new HashMap();  
 map.put("success", false);  
 map.put("errors", "File not found in the specified path.");  
 // create GSON, parse and set the string into the response writer  

That’s it. Now the control reached the designated handlers perfectly file.

In case of Success I got the following JSON string as the response:

 {"success":true,
 "cols":[
       {"header":"request_id","dataType":"Integer","fieldFound":false,"seq":1},
       {"header":"employee_code","dataType":"Integer","fieldFound":false,"seq":2}
       ]
}  

And in case of failure, this:

 {"success": false, "errors":"File not found in the specified path"}  

So next time, if you happen to face a similar issue just remember "success" parameter has to be set in your response text.
It only depends on you how you do it!

Please post your comments and valuable suggestions and better alternatives to this.

Monday, June 10, 2013

Java/JS/ExtJs: How to convert/serialize Java objects to and from JSON string


Serialize JSON to Java and vice versa
Today I will show you how to convert JSON string to a Java/JS object and vice versa.
Trust me it’s very easy and fast. Also there are few online tools which I would recommend you all while working with JSON. These are really helpful.

  1. JSON online editor : This tool will validate and convert your JSON string to an object like structure. You can add/edit/delete elements from your JSON string quite easily. But this is only for viewing and validating your JSON. Still quite useful.
  2. JSON to POJO generator : Well this tool comes very handy if you want to make Java skeletons of all the classes present inside your JSON string. It will quickly help you create the respective bean classes. You will need this when you have a very large JSON string and you need to create the Java classes having properties matching the JSON string.

With that, let’s start with the actual topic.
How do we serialize JSON string into a Java/JS object and vice versa?

If you need a Java object, import gson-2.2.2.jar into your project.
Gson (also known as Google Gson) is an open source Java library to serialize and deserialize Java objects to (and from) JSON.
  • We will start with serializing Java object to JSON string:
Suppose you have a bean class (having proper getter/setter methods) with following data:

 public class Book {  
  private String name;  
  private String author;  
  private String genre;  
  private Double cost;  
  private Book () {  
  }  
  public Book (String name, String author, String genre, Double cost) {  
   this.name = name;  
   this.author = author;  
   this.genre = genre;  
   this.cost = cost;  
  }  
 @Override  
  public String toString() {  
   return("Name: " + name + ", " + "Author: " + author + ", " + "Genre: " + genre + ", " + "Cost: " + cost);  
  }  


Now let’s create an instance of this class.

 Book wimpyKid = new Book("Diary of a Wimpy Kid", "Jeff Kinney", "Comedy", 200);  

Now to serialize/convert this object into a JSON string you just need to

 Gson gson = new Gson();  
 String wimpyKidJSON = gson.toJson(wimpyKid);  

Print "wimpyKidJSON" and you will get something like this:

 {  
   "name": "Diary of a Wimpy Kid",  
   "author": "Jeff Kinney",  
   "genre": "Comedy",  
   "cost": 200  
 }  

If you are working on Javascript then you need to fire this command:

 JSON.stringify(wimpyKid); //supposing wimpyKid is a Javascript object  

And in ExtJS do the following:

 Ext.encode(wimpyKid); //supposing wimpyKid is a Javascript object  

  • Now let’s do the other way round. Convert/deserialize a JSON string to POJO/JS object:
Now this is interesting, suppose you have only instance of the Book class, then simply execute this:

 Book wimpyKid = new Gson().fromJson(wimpyKidJSON, Book.class); 

This will set all the values from JSON string into the corresponding properties of the Book class.
But in case you have an array of books in the json string, and you want an array of Book classes in return then this can also be done by executing a single command:


List bookList = gson.fromJson(arrayOfBooksJSON, new TypeToken< List <Book >>;()}.getType());


Similary, in case of javascript:

 var bookObj = JSON.parse(wimpyKidJSON) // will give you a javascript object 

And in case of ExtJS:

 var bookObj = Ext.decode(wimpyKidJSON); // will give you a javascript object 

That’s it! Neat, Right?

Thursday, June 6, 2013

ExtJS: Grid: How to get/set values of a specific cell of a row in grid

Imagine you have an ExtJs grid having 3-4 columns and several rows.
Let us consider the below grid.
Please note it has to be an ExtJs grid.

Field Type Control
Name
Age
Sex

Now what I want to do is if I change the "Type" field of any row, the "Control" field of the corresponding row should get set to a defined value automatically.

For eg.
1. Name : I select "Varchar" in Type field - its Control field should get changed to "TextField".


How do I do it? Here it is...

You will have to write your code in the "change" event of the dropdown box.
In our case it will be the "Type" combobox.

 
 listeners: {
                change: function (field, newValue, oldValue) {
                    // if type selected is varchar   
                    if (newValue == 'Varchar') {
                        // get the handler to the grid 
                        var grid = this.up().up();
                        // get selection model of the grid  
                        var selModel = grid.getSelectionModel();
                        // set control of the record to text  
                        //NOTE: 'control' here is the value set in the dataIndex property of the Control combobox  
                        selModel.getSelection()[0].set('control', 'TextField');
                    }
                }
            }

JSFiddle Demo

That's it! Now you can test by changing the type of any row to varchar. Control of the corresponding row will get set to text instantaneously.

Cheers!

ExtJS : How to make combobox perform "Contains"/LIKE search

Hi,

I am a software engineer working mostly on Java, Javascript, Struts, Spring and MySQL.
Recently I have started working on ExtJS and I found it really interesting and exciting.
It surely is a great way to develop webapps with rich and stable GUI.

Here I will be sharing some of the daily learnings, tips&tricks, solutions to issues that I face every day.
Hope this helps someone..

So today I will start with something small but very useful functionality in ExtJs.
How to get a '%LIKE%' search functionality in a textbox or a combobox?

Lets start with creating a simple combobox in ExtJs

 
// The data store containing the list of states
var cars = Ext.create('Ext.data.Store', {
    fields: ['key', 'name'],
    data: [{
        "key": "Benz",
            "name": "Mercedes-Benz"
    }, {
        "key": "Audi",
            "name": "Audi"
    }, {
        "key": "Ferrari",
            "name": "Ferrari"
    }, {
        "key": "Prius",
            "name": "Prius"
    }, {
        "key": "Lamborghini",
            "name": "Lamborghini"
    }, {
        "key": "BMW",
            "name": "BMW"
    }
    //...
    ]
});

// Create the combo box, attached to the states data store
Ext.create('Ext.form.ComboBox', {
    fieldLabel: 'Choose Car',
    store: cars , //store name defined above
    queryMode: 'local',
    displayField: 'name', // value field
    valueField: 'key', //key field
    renderTo: Ext.getBody() //render on the page
});

So this will create a simple dropdown on the screen.
Notice we two properties in the above configuration:
1. typeAhead: true and 2. editable: true

These properties will by default provide search functionality on the data of the combobox as you start typing.
But this will do a "Starts With" search instead of a "Contains" or "LIKE" search.

To do that, do the following:

 
listeners: {
        beforequery: function (record) {
            record.query = new RegExp(record.query, 'i');
            record.forceAll = true;
        }
    } 

Just add the above listeners having 'beforequery' event to your dropdown.
That's it!! Your dropdown will do a "Contains" search.

Now last step, converting the combobox into a texbox

 hideTrigger: true  

Now it's a textbox with search functionality.

JSFiddle Demo