Monday, November 17, 2008

Changing Effects without resorting to javascript in RichFaces JSF

Recently I had to use <rich:effect> to make a richPanel appear with BlindDown effect on user action. It was easy for me as I just had to use code as below to accomplish this

 
.....





Just as it was given in RichFaces Demo site. Now I had to do this tricky part, I have to show the panel when user clicks the link "click" for the first time and BlindUp to close the panel when clicked again. I know we can easily do it with javascript as it just uses the scriptaculous library, I wanted to avoid javascript (rather explicitly in JSF applications), so came up with this solution.

As I will be toggling the effect for panel based on the values that I am going to display from my seam action, i wanted to use the data to differentiate if I need to show or hide the panel

 
.....








Note that the oncomplete handler is unchanged (where I thought I will have to call a different javascript here initially ..), we will be changing the effect type based on our business specific condition which can help us determine whether to close the panel or to open it.

Also notice, that the style element for the richPanel is set to display:none or display:block , this is to hide the panel initially so that BlindDown effect make sense.. and similarly used display:block to make sure user can see the effect of panel hiding using the BlindUp effect


..

..


Thursday, November 6, 2008

Readonly Value Binding in JSF for a hidden field

Many of the newbies of JSF will encounter situations where they find everything they wrote perfect but the JSF implementation throws strange errors. Here is one of the classic ones that you may step on.. .

Imagine you want to store some number(like some count) in a hidden field so that you can use it in your javascript to perform some task.


     .....
     
     
     


you strongly know this should work fine, particularly when you are coming from a JSP/struts/struts2 background, but when this page gets submitted you will see errors from JSF saying that the count is not writable for int . This is because there is no setCount method on the someList bean, Although we are not writing anything to the hiddenField, we have to understand when ever a form gets submitted JSF tries to apply back the values into the component tree.

How to solve this ? Here is how they do it.

just add readonly="true" attribute to h:inputHidden, this will ensure JSF will not try to apply values through setCount method, but still renders the value to the page


     .....
     
       
     
 


Hope this helps..

By the way ..this is my first post from my new MacBook Pro :-)

Friday, March 21, 2008

Quick Sequence diagrams

Though there are great tools available to draw UML diagrams , some times we will be in a situation to quickly draw a sequence diagram for a presentation or to discuss some thing in a design meeting and we dont want to waste our time working with those heavy tools.

I came across http://www.websequencediagrams.com/ and felt this a cool site in which we can describe our sequence diagrams using simple text like A->B:create() to produce cool diagrams like the below image.

how to access constants from JSTL (EL)

During our web development we may come across a situation where we want to use a constant (static final) variable for some reason in our JSP using JSTL's Expression Language (EL). As you know we access properties very easily using JSTL as below.

you might alreay know.. if we want to access a property called studentName and a method is defined as getStudentName() in the target object (lets cal it 'student') the EL would be "${student.studentName}".

But if we want to access a constant defined in the above class as
public static int MAX_RETRY_ATTEMPTS=10;

using the EL "${student.MAX_RETRY_ATTEMPTS}" , will fail
I am sure you will need to use these constants sometimes.

We can use a simple trick to solve this.

we will make use of a Map to store the constants , as below


.....
.....
......
public final static int MAX_ALLOWED_USERS=10;
public final static int MAX_LOGIN_ATTEMPTS=2;
Map constants=new HashMap();

public Map getConstants(){
constants.put("MAX_ALLOWED_USERS", MAX_ALLOWED_USERS);
constants.put("MAX_LOGIN_ATTEMPTS", MAX_LOGIN_ATTEMPTS);
return constants;
}


As you can see we have defined a method getConstants which returns a HashMap with our constants with appropriate keys.

Now how can we use this in our JSP ?


The Maximum number of attempts is : "${MyForm.constants['MAX_LOGIN_ATTEMPTS']}"


clearly, we first get the Map using getConstants() method and then value of the constant using the key 'MAX_LOGIN_ATTEMPTS'.

Easy ?

Please let me know if there is a better way to do this

Wednesday, March 19, 2008

What's nice about seaside ?

Its been very interesting week, trying to get my head around seaside. Honestly it took some time for me to unlearn many things which I learned over past many years. Not only a great idea, I feel it will speed up the the web development process in a great way. Although many seaside experts have written great examples, I wanted to post the one I started with.

The functionality is quite simple
1) Display the Login Page
2) User enters username and password and clicks on validate button
3) If the credentials are validated (in this case username='smalltalk' ) a welcome message is displayed , otherwise login page is displayed again.

Quite simple.... lets see how intuitive it can be

Lets start with defining our Login Component as below



WAComponent subclass: #Login

instanceVariableNames: 'username password retry'
classVariableNames: ''
poolDictionaries: ''
category: 'LearnSeaside'!



this should be self explaining , We defined a class Login subclassing it from WAComponent.
It has three instance variables , I used "retry" to indicate if it is a retry or first attempt. (may not be the best way ..)

Seaside calls renderComponentOn method when it is appropriate to display the content on the web page. Let us look at how we want to display the content on page.


renderContentOn: html

html
form: [
retry ifTrue: [
html text: 'Retry..'.

html break].
html text: 'User Name'.
html textInput on: #username of: self.
html passwordInput on: #password of: self.

html submitButton callback: [self answer: self];
value: 'Validate']



Nothing special .. it just displays user name and password fields, in addition to that , it display text "Retry" based on the instance variable "retry".

Now lets add some magic. we will now write a Task to start this.

we will name our task WASchoolTask , subclassing WATask. it will have a method "go" which will be called by seaside as entry point to the application.

let us look at the go method.


go
| login |
login := self call: Login new.
[login username = 'smalltalk']
whileFalse: [login retry: true.
login := self call: login].
self inform: 'Welcome ' , login username

as you can see in the above code we want to display the login screen until the user enters username as smalltalk. What a great way to write your applications describing the natural flow of the application! Notice the statement
self inform:'Welcome ',login username

The best part of the code is that this statement will not be executed unless the loop is broken. Imagine how you would do this in a Action based framework.

Sunday, March 2, 2008

Some new ways to Develop web applications

Its been long since I started working on developing Java based web applications. Quite frankly, developing applications, although critical for earning rice :-) , I am no more enjoying developing them with the MVC models using heavy boilerplate code and scaringly big XML files for configuration.
The typical request response model sounded great for me in the initial days , probably I was used to develop using cgi and later php with code scattered all over the page.
The interest in some different stuff automatically dragged me to Ruby on Rails, and found it really cool, but again the basic approach was same but with emphasis on convention over configuration.

Looks like atlast I found some thing interesting in Seaside , a Continuation based framework in Smallatalk !! Yess.. I wrote it correctly , It is Smalltalk, that language we heard about in our College days.


So whats new about it ? Lets have a look at the following figure



In a typical Struts based or any Action based framework , Control flows from Browser to Action Class (or similar ) for processing some business logic by parsing the request parameters (many framework do this automatically ..but still we are dealing with fields and request parameters) and based upon the result control will be passed to render appropriate page, and this process repeats. This model allows business logic to be written in separate classes .

Now , lets us look at the Continuations based Seaside framework, In a striking contrast with the above approach , we can write our web applications , very similar to the way we write any console based application, like the below pseudo code

1) Get Values From Browser
.... Suspend Processing till user click on Submit
2) Process
3) Display Result
..Suspend processing till user responds with something
4 ....


I found it very different and very intuitive way of developing applications. There is a lot of Buzz around this framework , you too may find it interesting.

Currently I am exploring this framework and finding it a great way to develop the applications. I will write about this further in my future posts.

Saturday, March 1, 2008

Handling multiple checkboxes in Struts 2

Many a time in Web applications we implement a form with a table of records with checkboxes , allowing users to select some rows for performing operations on selected rows. In this post let us look at how it is implemented.

This example is based on Struts 2 framework, with StudentAction as the action class and student.jsp as JSP to display a list of students

The general requirement in these forms is to be able to get the list of selected rows in the "Action" class to perform the required operations and when the control is passed to render the jsp the previously selected rows should be still shown as selected. To achieve this we will add a special field to the StudentAction to hold the list of selected rows (normally identified with some primary key) , as shown in the below code snippet from StudentAction.java


public class StudentAction extends ActionSupport {
List students = new ArrayList();
List selected = new ArrayList();
public List getSelected() {
return selected;
}
public void setSelected(List selected) {

this.selected = selected;
}


.....



The corresponding JSP page to display the list of students with a checkbox will have to name that checkbox as "selected" as shown in below snippet

 















What this code does ? look at the line





if you find everything is straight forward except value="%{name in selected}" , it is a OGNL expression which returns "true" if the value returned by getName() (on the StudentAction instance) is contained in the list returned by getSelected() method, and because this list will be empty for the first time no checkbox will be selected (as the above expression returns false), on clickin Submit button after selecting some checkboxes Struts2 will automagically populates the selected List with the values of selected checkboxes (which happens to be name here), after the performing the business logic when the page is displayed again the above expresion will return true for the previously selected names resulting in those checkbox rendered selected.

Easy ?

Sunday, February 24, 2008

Implementing File download feature in Struts 2 & Struts

Although file upload is a common feature that many struts application developers implement , it is less common to implement file download , in this post we will see how to provide file download feature in your struts 2 application.

Before we see how to implement this feature, let us first understand the requirement

1) A web page contains a link , which upon clicking it responds with a browser's file save dialog with a default name
2) User can choose the save location to save the file (as with any file save dialog)

This example uses a simple ActionClass with name DownloadAction and a jsp to show the link for downloading an arbitrary file



Let us start with the JSP , this is the simplest thing with a link pointing to the action class


Click to download


The action class which provides the download of file just needs to implement the getInputStream() method returning the InputStream of the required file to dowload !! Simple ...isn't ?

DownloadAction.java

public class DownloadAction {
private String fileName="YOUR FILE PATH";
public InputStream getInputStream(){
try{
return new FileInputStream(new File(fileName));
}catch(Exception e){}
}
public String execute(){
return "success"
}
}


Now the final thing is to wire these up in struts.xml , NOTE... there is something that is different from other regular configurations!! ... unlike other cases the control need not be passed to the JSP , instead we want the content to be handled by the browser itself (to bring up required download dialog), hence the result type is specified as "stream", which by default looks for getInputStream method (it can be configured) and sends it back as response














Easy !! isn't ? Then how about the implementation in Struts 1.xx ?

We can achieve this with the following steps

1) In the Action Class obtain the servlet response object
2) get the OutputStream from the response object
3) Get the InputStream of the target file (which we want to send to the browser)
4) Write the contents of the file to the Outputstream of step #2.
5) Don't forward the request by returning null to terminate the action.

Now, let us take a look at the code snippet of the DownloadAction.


...
...
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
File f = new File("C:\\myTestFile.xml");
response.setContentType("application/octet");
byte[] buffer = new byte[2048];
FileInputStream inputStream=new FileInputStream(f);
int bytesRead = inputStream.read(buffer);
ServletOutputStream outputStream=response.getOutputStream();
while (bytesRead >= 0) {
if (bytesRead > 0) {
outputStream.write(buffer, 0, bytesRead);
}
bytesRead = inputStream.read(buffer);
}
outputStream.flush();
//no need to forward ..
return null;
}


Here for the sake of brevity I have hardcoded the file name you will get the file name Or file Object probably from your models or from the form ..(Or any other way)

Thats it!! Hope it helps

Monday, January 21, 2008

List of Values in Web Apps



I recall the days where we used to develop using Developer 2000 , and many applications (Desktop apps) used to feature a List of Values functionality (LOVs) where users click on a button to select from a set of options which can be better displayed in separate screen providing search/filter capabilities and an ID is returned to the Original Window's control. Although not common in websites , many web applications require this functionality ..Here is how they do it...

Let us consider a sample web application in which
1) User has to select a part ID from a list of available parts ,
2) This cannot be modled as a select(Combo) box as we need to show some extra info in a table
3) We just need part ID from popup where user can search based on part name or description

now..Look at the above figure, Page1 requires Part ID from Popup, and we are using Struts . The best way (In my opinion) is :
1) Create a JSP (Popup.jsp) with a table showing the information of Parts (array of Part Objects)
2) Create a mapping in struts-config.xml






As you know ...PartsForm is the FormBean,

1) LovParts is the Action name which will be invoked by Page1 (refer to figure above)
2) Popup.jsp is the popup that displays Parts information in a HTML table
3) PartsAction Contains(or calls) required business methods to get the list of Parts

We are almost done with this.. inorder to bring up the popup there are many methods but all involve using javascript's window.open, for our example let us assume that we just have one field in the Page 1 that can be sumbitted (using POST) to determine what to show in the Popup initially (Like pre-fetching values for a already existing Part ID)

Write a function in your JSP (or your js file) which does the following

1) but the target page shall not replace the existing one
2) Submits the contents of the form to a different window so that the resulting page will not replace the current one (we want the existing page and the Popup)


  1. function postToPopup(winName){
  2. var winProps = 'Width='+20+', Height='+30+', top='+10+', left='+50; //ADJUST THESE VALUES..
  3. var hndWin = window.open("", winName, winProps); //OPEN A BLANK POPUP
  4. document.forms[0].target=winName;
  5. document.forms[0].submit(); //submit the form and open the content in popup identified by winName
  6. }

now Just call this function on the button press :
postToPopup("partsIdPopup")


Congrats!! We have just completed the first part , ie., Opening the popup, Now after user selects the Required Part and clicks OK , the Popup should close and the PartID should be returned to the Page1. Doing this is also easy , we just need to use window.opener property to get the parent window which opened this Popup and use DOM to access the field we want to set the PartID

For example: the name of the field we want to set is partID then the code in the Popup.jsp will have this in the Button click event of OK


 
function okClicked(){
window.opener.document.forms[0].partsId=partID;
//NOw cose the Popup Window
window.close();
}


Thats it..

Hope it helped you

How to try/test/learn Objective C without a Mac

At last I am convinced that I should now move to Mac platform. Although Java is my primary dev platform , I know(or heard) that the real fun will be developing using Cocoa for Mac. Now.. I never even looked at a Objective C program and was curious to learn it before buying my MacBook Pro, used my friend Mr. Google for resources but few point to Objective C on Windows, to make it easy for others..here is how .....

Basically there are two options to compile /run Objective C programs

1) Use a Linux distro like Ubuntu on Virtual PC and start compiling your programs using gcc (Yes ..it compiles Objective C)
2) Download GNUStep for Windows from http://www.gnustep.org/ ,to write Objective C in your favorite old Windows Box

Option 1 is fairly simple , but if you are a Linux hater Option #2 is also an easier one

1) On Installing GNUstep on your windows box, it will provide you with developer tools like gcc
2) You can use command line provided by Gnustep if you are familiar with *nix by writing programs in vi and compiling manually using gcc
3) You can even use your favorite editor like EditPlus or TextPad to write programs easily (I prefer this..for sake of keeping it simple)

To Compile and Run your programs, configure you editor to invoke the following on your source files


gcc *.m -lobjc -lm

Execute the resulting a.out file

There is good information in http://en.wikibooks.org/wiki/Programming:Objective-C

I am still learning Objective C , please let me know if there are better ways to do all this :-)