Wednesday, November 2, 2011

Persian Textbox

Hey...
Please take a look to these input boxes


At the first look, they are simple inputs. But they are not.
Try to write something on them. Yes the language will switch to Persian mode automatically. But your O.S. keyboard language stays on its old state.
Know press Alt+Ctrl. The language will change(if not try more and more until success).
Here I'm going to describe how I did this.
On the first step you should include the related js file like this:
<script type="text/javascript" src="persiankeyboard.js"></script>
Then your inputs should handle onkeydown and onkeypress javascript events(the read parts) like this:
<input type="text" onkeydown="switchTextLang(this, event)" dir="rtl" onkeypress="keyEnterToPersian(this, event)" lang="fa"/>
<textarea onkeydown="switchTextLang(this, event)" dir="rtl" onkeypress="keyEnterToPersian(this, event)" rows="10" lang="fa" cols="10"></textarea>
The last step is optional but I recommend you to do it to feel better. Its better to set dir and lang fields of your inputs(the yellow parts).
OK that's it. You have Persian input box.
Know the script logic:
The script logic is so simple. It contains three major functions.
  • keyEnterToPersian
    this function converts the input key to Persian character. There is an array containing Persian character key code in hexadecimal ordering by their equivalent English character key code. Please take a look to the array:
    var keys = [
    0x0020, 0x0021, 0x061B, 0x066B, 0xFDFC, 0x066A, 0x060C, 0x06AF,
    0x0029, 0x0028, 0x002A, 0x002B, 0x0648, 0x002D, 0x002E, 0x002F,
    0x06F0, 0x06F1, 0x06F2, 0x06F3, 0x06F4, 0x06F5, 0x06F6, 0x06F7,
    0x06F8, 0x06F9, 0x003A, 0x06A9, 0x003E, 0x003D, 0x003C, 0x061F,
    0x066C, 0x0624, 0x200C, 0x0698, 0x064A, 0x064D, 0x0625, 0x0623,
    0x0622, 0x0651, 0x0629, 0x00BB, 0x00AB, 0x0621, 0x0654, 0x005D,
    0x005B, 0x0652, 0x064B, 0x0626, 0x064F, 0x064E, 0x0670, 0x064C,
    0x0653, 0x0650, 0x0643, 0x062C, 0x005C, 0x0686, 0x00D7, 0x0640,
    0x200D, 0x0634, 0x0630, 0x0632, 0x06CC, 0x062B, 0x0628, 0x0644,
    0x0627, 0x0647, 0x062A, 0x0646, 0x0645, 0x067E, 0x062F, 0x062E,
    0x062D, 0x0636, 0x0642, 0x0633, 0x0641, 0x0639, 0x0631, 0x0635,
    0x0637, 0x063A, 0x0638, 0x007D, 0x007C, 0x007B, 0x007E];
    The equivalent Persian key code of input key code is "keys[key - 32]". Because the key code range that we should handle them are between 32(space) up to 127 which will be 0 up to 95 in array index.
  • pnhMozStringInsert
    This function is for Mozilla browsers to substitute the input key with its equivalent Persian character in the right position. It will find selection start and end and scroll top and left(for textarea) to insert the substituted character in the right position. In IE browsers we can set the calculated Persian key code directly in "event.keyCode" and it works. I did it in keyEnterToPersian function.
  • switchTextLang
    This function sets input language state. This will switch the language by handling Alt+Ctrl key down. It do it on this way:
    var event = document.all ? window.event : event;
    if (event.ctrlKey && event.altKey)

    .... 
You can download the client side sample from here.
I hope to solve end user Farsi typing of Persian developer problem by creating this tool.
Enjoy yourselves.
all rights reserved by Mostafa Rastgar and Programmer Assistant weblog

Sunday, July 17, 2011

Design Patterns2(Abstract Factory, Bridge, Facade)

Hey ...

Do you remember my past post about design patterns? Here I'm going to continue it.

4. Abstract Factory
4.1. Pattern Goal
The abstract factory pattern is a software design pattern that provides a way to encapsulate a group of individual factories that have a common theme. In normal usage, the client software creates a concrete implementation of the abstract factory and then uses the generic interfaces to create the concrete objects that are part of the theme. The client does not know (or care) which concrete objects it gets from each of these internal factories since it uses only the generic interfaces of their products. This pattern separates the details of implementation of a set of objects from their general usage.

In software development, a factory is the location in the code at which objects are constructed. The intent in employing the pattern is to insulate the creation of objects from their usage. This allows for new derived types to be introduced with no change to the code that uses the base class.

Use of this pattern makes it possible to interchange concrete implementations without changing the code that uses them, even at runtime. However, employment of this pattern, as with similar design patterns, may result in unnecessary complexity and extra work in the initial writing of code. Used correctly the "extra work" pays off in the second implementation of the factory.
4.2 Pattern Detail
In this pattern we should have 2 kinds of interfaces and classes. 1: Concrete Products 2:Concrete Factories
Please take a look to this class diagram:
as you see there are two kinds of classes. Factory classes are responsible for creation their own class. Client(Application) should only uses ConcreteFactory class and retrieve an object type of ConcreteProduct class.
4.3 Pattern sample
In this sample we want to have a block to support templates. We place a key property containing template name. When we change the template key to green or blue, the block color should change its color. To do that we need 2 interfaces:
public interface Panel {
    public String paint(String value);
}
public interface PanelFactory {
    public Panel createPanel();
}
two classes should implement Panel. Each class should implement its own color:
public class GreenPanel implements Panel{
    public String paint(String value) {
        return "<div style='border-width:1px; border-color:green; border-style:solid; margin:2px; padding:2px; color:green'>" + value + "</div>";
    }
}
public class BluePanel implements Panel{
    public String paint(String value) {
        return "<div style='border-width:1px; border-color:blue; border-style:solid; margin:2px; padding:2px; color:blue'>" + value + "</div>";
    }
}
And two classes should implement PanelFactory:
public class BluePanleFactory implements PanelFactory{
    public Panel createPanel() {
        return new BluePanel();
    }
}
public class GreenPanelFactory implements PanelFactory{
    public Panel createPanel() {
        return new GreenPanel();
    }
}
Now its join time. we should make a class to use a PanelFactory to create a Panel object and use its method:
public class PageUIManager {
    Panel panel;

    public PageUIManager(PanelFactory panelFactory) {
        this.panel = panelFactory.createPanel();
    }

    public String createPageElements(String value){
        return this.panel.paint(value);
    }
}
And here is the use of PageUIManager class:
@Controller
@Scope("prototype")
@RequestMapping("/graphicalpage")
public class PageController {
    @ModelAttribute("pagebody")
    public String pageBody() {
        ResourceBundle rb = ResourceBundle.getBundle("edu.patterns.abstractfactory.theme");
        if (rb.getObject("currentTheme").equals("blue")) {
            return (new PageUIManager(new BluePanleFactory())).createPageElements("This page color will be changed if you set 'currentTheme' key to 'green' value in edu.patterns.abstractfactory.theme file.");
        }
        return (new PageUIManager(new GreenPanelFactory())).createPageElements("This page color will be changed if you change 'currentTheme' key to 'blue' value in edu.patterns.abstractfactory.theme file.");
    }

    @RequestMapping("/view")
    public String View() {
        return "graphicalpage.view";
    }
}

This class checks the resource bundle if decide which panel should be displayed.

5. Bridge
5.1 Pattern Goal
The bridge pattern is a design pattern used in software engineering which is meant to "decouple an abstraction from its implementation so that the two can vary independently".The bridge uses encapsulation, aggregation, and can use inheritance to separate responsibilities into different classes.
When a class varies often, the features of object-oriented programming become very useful because changes to a program's code can be made easily with minimal prior knowledge about the program. The bridge pattern is useful when both the class as well as what it does vary often.
5.2 Pattern Detail
This pattern has four major classes. Please Take a look here:
Abstraction:
    defines the abstract interface
    maintains the Implementor reference
RefinedAbstraction:
    extends the interface defined by Abstraction
Implementor:
    defines the interface for implementation classes
ConcreteImplementor:
    implements the Implementor interface

On the other hands, whenever we have some classes with the same materials(ConcreteImplementor), we can standardize them with an super class(Implementor), then we can make a Bridge to connect and maintain them. We can generalise it because each set of Implementor classes has its own protocols(Abstraction). Finally the bridge implementation classes implement Abstraction class and during its implementation they will follow set of Implementor classes protocol.
5.3 Pattern Sample
We are going to create some components for HTML pages. All of them are containing component. This is the share point of them. I'll show you how to create them with Bridge pattern.
First of all I should define the component standard:
public abstract class Container {
    private Map<String, String> styles;

    protected Container() {
        this.styles = new HashMap<String, String>();
    }

    public void addStyle(String key, String value){
        styles.put(key, value);
    }

    protected String renderStyles(){
        if (!styles.isEmpty()) {
            String[] styleArray = new String[styles.size()];
            int i = 0;
            for (String key : styles.keySet()) {
                styleArray[i++] = key + ":" + styles.get(key);
            }
            return "style='" + org.springframework.util.StringUtils.arrayToDelimitedString(styleArray, ";") + "'";
        }
        return "";
    }
    public abstract String startTag();

    public abstract String endTag();
}
As you see every component classes should implement startTag and endTag method. It also has a style attribute type of List and two usefull method for that: addStyle to add a new style and renderStyle to render the list of styles as HTML styles.
Now its the time to implement the component classes. They should implement Container.
public class Div extends Container {

    public String startTag() {
        return "<div " + renderStyles() + ">";
    }

    public String endTag() {
        return "</div>";
    }
}
public class Paragraph extends Container {
    public String startTag() {
        return "<p " + renderStyles() + ">";
    }

    public String endTag() {
        return "</p>";
    }
}
public class Span extends Container {
    public String startTag() {
        return "<span " + renderStyles() + ">";
    }

    public String endTag() {
        return "</span>";
    }
}
every componets implement its own tag as easy as possible via the two methods wich is determined in super class.
Now its the time of bridge class. It has some fields which will be render as html styles in Container class. So the role of this class is a bridge with client class and Container class. Take a look here:
public abstract class ContainerBridge {
    int width;
    int height;
    String color;
    String backgroundColor;
    int borderWidth;
    String borderColor;
    String borderStyle;

    protected Container implementor;

    protected ContainerBridge(Container implementor) {
        this.implementor = implementor;
    }

    public int getWidth() {
        return width;
    }

    public void setWidth(int width) {
        this.width = width;
        implementor.addStyle("width", (new Integer(width)).toString());
    }

    public int getHeight() {
        return height;
    }

    public void setHeight(int height) {
        this.height = height;
        implementor.addStyle("height", (new Integer(height)).toString());
    }

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
        implementor.addStyle("color", color);
    }

    public String getBackgroundColor() {
        return backgroundColor;
    }

    public void setBackgroundColor(String backgroundColor) {
        this.backgroundColor = backgroundColor;
        implementor.addStyle("background-color", backgroundColor);
    }

    public int getBorderWidth() {
        return borderWidth;
    }

    public void setBorderWidth(int borderWidth) {
        this.borderWidth = borderWidth;
        implementor.addStyle("border-width", (new Integer(borderWidth)).toString());
    }

    public String getBorderColor() {
        return borderColor;
    }

    public void setBorderColor(String borderColor) {
        this.borderColor = borderColor;
        implementor.addStyle("border-color", borderColor);
    }

    public String getBorderStyle() {
        return borderStyle;
    }

    public void setBorderStyle(String borderStyle) {
        this.borderStyle = borderStyle;
        implementor.addStyle("border-style", borderStyle);
    }

    public abstract String wrapText(String text);
}
As you see it maintains Componet passed parameter in constructor as a field(implementor) and  in every setter method it adds a new attribute in style of implementor.This class has also an abstract method called wrapText which should be implemented.
Finally we should implement Bridge class. HtmlContainer will do it:
public class HTMLContainer extends ContainerBridge {
    public HTMLContainer(Container implementor) {
        super(implementor);
    }

    public String wrapText(String text) {
        return implementor.startTag() + text + implementor.endTag();
    }
}
As you see in HTML we should start a tag and place our text then close the tag. This class follows this standard and implement it.

Now its the time to use these tage. we do it in BridgeController:
@Controller
@Scope("prototype")
@RequestMapping("/bridgecontroller")
public class BridgeController {
    @ModelAttribute("pagebody")
    public String pageBody() {
        HTMLContainer div = new HTMLContainer(new Div());
        div.setWidth(200);
        div.setHeight(100);
        div.setColor("lightgray");
        div.setBackgroundColor("gray");

        HTMLContainer p = new HTMLContainer(new Paragraph());
        p.setBorderStyle("solid");
        p.setBorderWidth(1);
        p.setBorderColor("black");
        p.setColor("green");
        p.setWidth(200);
        p.setBackgroundColor("orange");

        HTMLContainer span = new HTMLContainer(new Span());
        span.setColor("lightblue");
        span.setBackgroundColor("brown");
        return div.wrapText("this is div tag from bridge pattern. width:200; height:100; Color:lightgray; Background Color:gray")
                + p.wrapText("this is p tag from bridge pattern. width:200; Border Style:solid; Border Width:1; Border Color:black; Color:cyan; Background Color:orange")
                + span.wrapText("this is span tag from bridge pattern. Color:lightblue; BackgroundColor:brown");
    }

    @RequestMapping("/view")
    public String View() {
        return "bridgecontroller.view";
    }

}

3. Facade
3.1 Pattern Goal
The facade pattern is a software engineering design pattern commonly used with Object-oriented programming. The name is by analogy to an architectural facade.
A facade is an object that provides a simplified interface to a larger body of code, such as a class library. A facade can:
  • make a software library easier to use, understand and test, since the facade has convenient methods for common tasks;
  • make code that uses the library more readable, for the same reason;
  • reduce dependencies of outside code on the inner workings of a library, since most code uses the facade, thus allowing more flexibility in developing the system;
  • wrap a poorly-designed collection of APIs with a single well-designed API (as per task needs).
An Adapter is used when the wrapper must respect a particular interface and must support a polymorphic behavior. On the other hand, a facade is used when one wants an easier or simpler interface to work with.
3.2 Pattern Detail
Facade is a simple class which know when and how to create and use other classes and methods of them. Take a look here:
3.3 Pattern Sample
We have a list of people. Suppose that they are our employee so they have these fields:
public class Person {
    Long id;
    String firstname;
    String lastname;
    Long durationTime;
    Long fractionTime;
    Long overtime;
    Long contraction;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getFirstname() {
        return firstname;
    }

    public void setFirstname(String firstname) {
        this.firstname = firstname;
    }

    public String getLastname() {
        return lastname;
    }

    public void setLastname(String lastname) {
        this.lastname = lastname;
    }

    public Long getDurationTime() {
        return durationTime;
    }

    public void setDurationTime(Long durationTime) {
        this.durationTime = durationTime;
    }

    public Long getFractionTime() {
        return fractionTime;
    }

    public void setFractionTime(Long fractionTime) {
        this.fractionTime = fractionTime;
    }

    public Long getOvertime() {
        return overtime;
    }

    public void setOvertime(Long overtime) {
        this.overtime = overtime;
    }

    public Long getContraction() {
        return contraction;
    }

    public void setContraction(Long contraction) {
        this.contraction = contraction;
    }
}
duration fraction and over times are in minutes and contraction is amount of person salary per hour. PersonSalary is a class wich maintain the person salary:
public class PersonSalary{
    Person person;
    Long salary;

    public PersonSalary(Person person, Long salary) {
        this.person = person;
        this.salary = salary;
    }

    public Person getPerson() {
        return person;
    }

    public void setPerson(Person person) {
        this.person = person;
    }

    public Long getSalary() {
        return salary;
    }

    public void setSalary(Long salary) {
        this.salary = salary;
    }
}
We have claculator class for duration, overtime and fractiontime.
public class DurationCalculator {
    public Long calculate(Person p) {
        return (p.getDurationTime() / 60) * p.getContraction();
    }
}
public class OvertimeCalculator {
    Long overtimeFactor;

    public OvertimeCalculator(Long overtimeFactor) {
        this.overtimeFactor = overtimeFactor;
    }

    public Long calculate(Person p) {
        return (p.getOvertime() / 60) * overtimeFactor * p.getContraction();
    }
}
public class FractiontimeCalculator {
    Long fractiontimeFactor;

    public FractiontimeCalculator(Long fractiontimeFactor) {
        this.fractiontimeFactor = fractiontimeFactor;
    }

    public Long calculate(Person p) {
        return (p.getFractionTime() / 60) * fractiontimeFactor * p.getContraction();
    }
}
the salary formula is: duration salary(duration / 60 * contraction) + overtime salary(overtime / 60 * contraction * overtime factor) - fractiontime salary(fractiontime / 60 * contraction * fractiontime factor)
every parantheses will calculate in calculator class but the facade class is responsible for create these calculator class and summation and subtraction of them:
public class CalculatorFacade {
    public static final Long OVER_TIME_FACTORLONG = 2l;
    public static final Long FRACTMENT_TIME_FACTORLONG = 3l;

    Person person;
    DurationCalculator durationCalculator;
    OvertimeCalculator overtimeCalculator;
    FractiontimeCalculator fractiontimeCalculator;

    public CalculatorFacade(Person person) {
        this.person = person;
        durationCalculator = new DurationCalculator();
        overtimeCalculator = new OvertimeCalculator(OVER_TIME_FACTORLONG);
        fractiontimeCalculator = new FractiontimeCalculator(FRACTMENT_TIME_FACTORLONG);
    }

    public Long calculate() {
        return durationCalculator.calculate(person) + overtimeCalculator.calculate(person) - fractiontimeCalculator.calculate(person);
    }
}
The client class should only create CalculatorFacade and then use the calculate method of it:
@Controller
@Scope("prototype")
@RequestMapping("/employee")
public class EmployeeController {

    public List<PersonSalary> initPersonSalary() {
        List<PersonSalary> personSalaryList = new ArrayList<PersonSalary>();

        Person p1 = new Person();
        p1.setId(1l);
        p1.setFirstname("Jack");
        p1.setLastname("Shepard");
        p1.setContraction(50l);
        p1.setDurationTime(10200l);
        p1.setOvertime(900l);
        p1.setFractionTime(300l);

        Person p2 = new Person();
        p2.setId(2l);
        p2.setFirstname("John");
        p2.setLastname("Luke");
        p2.setContraction(40l);
        p2.setDurationTime(10800l);
        p2.setOvertime(480l);
        p2.setFractionTime(120l);

        Person p3 = new Person();
        p3.setId(3l);
        p3.setFirstname("Mostafa");
        p3.setLastname("Rastgar");
        p3.setContraction(60l);
        p3.setDurationTime(11400l);
        p3.setOvertime(1200l);
        p3.setFractionTime(0l);

        personSalaryList.add(new PersonSalary(p1, 0l));
        personSalaryList.add(new PersonSalary(p2, 0l));
        personSalaryList.add(new PersonSalary(p3, 0l));
        return personSalaryList;
    }

    @ModelAttribute("personList")
    public List<PersonSalary> getPersonList() {
        return initPersonSalary();
    }

    @RequestMapping("/view")
    public String View() {
        return "employee.view";
    }

    @RequestMapping("/calculate")
    public String calculate(@ModelAttribute("personList") List<PersonSalary> personSalaryList) {
        for (PersonSalary p : personSalaryList) {
            CalculatorFacade calculatorFacade = new CalculatorFacade(p.getPerson());
            p.setSalary(calculatorFacade.calculate());
        }
        return View();
    }
}

Source Code

You can download those 3 samples(Abstract Factory, Bridge, Facade) and old 3 samples(Singleton, Decorator, Immutable Class) from here. After the deployment the start page is: http://localhost:8080/button/view.html



all rights reserved by Mostafa Rastgar and Programmer Assistant weblog

Monday, June 27, 2011

Spring Web Service using JAX-WS

Hey ...

Nowadays, most of enterprise applications are linked together to do their jobs. Some of them expose some services, the others use the services which are exposed. Here, the role of web service appears. Here I'm going to explain more about spring-ws using jax-ws and take a simple example.

OK. let's start

1. Spring Web Service

Spring provides full support for standard Java web services APIs:
  • Exposing web services using JAX-RPC
  • Accessing web services using JAX-RPC
  • Exposing web services using JAX-WS
  • Accessing web services using JAX-WS

Why two standard Java web services APIs?
JAX-RPC 1.1 is the standard web service API in J2EE 1.4. As its name indicates, it focuses on on RPC bindings, which became less and less popular in the past couple of years. As a consequence, it has been superseded by JAX-WS 2.0 in Java EE 5, being more flexible in terms of bindings but also being heavily annotation-based. JAX-WS 2.1 is also included in Java 6 (or more specifically, in Sun's JDK 1.6.0_04 and above; previous Sun JDK 1.6.0 releases included JAX-WS 2.0), integrated with the JDK's built-in HTTP server.

Spring can work with both standard Java web services APIs. The choice is effectively dependent on the runtime platform: On JDK 1.4 / J2EE 1.4, the only option is JAX-RPC. On Java EE 5 / Java 6, the obvious choice is JAX-WS. On J2EE 1.4 environments that run on Java 5, you might have the option to plug in a JAX-WS provider; check your J2EE server's documentation.

In addition to stock support for JAX-RPC and JAX-WS in Spring Core, the Spring portfolio also features Spring Web Services, a solution for contract-first, document-driven web services - highly recommended for building modern, future-proof web services. Last but not least, XFire also allows you to export Spring-managed beans as a web service, through built-in Spring support.

As I mentioned, here I'm going to describe more about jax-ws. Here, more details are available about remoting and web services using Spring.

When your application uses Spring for wiring your code, you'll find it more convenient to use the same Spring for configuring JAX-WS. For example, that would allow your service implementations to receive resource injection via Spring, AOP stuff, logging, etc, etc. This RI extension provides this functionality.


2. JAX-WS

This Spring extension also allows you to configure various aspects of your web service through Spring, such as the use of MTOM, handlers, custom transports, encoding, etc., etc.

Another purpose of this extension is to provide a general purpose mechanism that JAX-WS extension authors can use, to let users use their extensions. For example, when you write a custom transport, custom codec, or custom pipeline assembler, you can use Spring to allow users to configure your extensions.

This deployment mechanism supercedes sun-jaxws.xml and JSR-109 deployment.

3. Server Side

Let's consider the most typical case, where you develop a web application and you want to deploy JAX-WS services. First your web.xml needs to have a JAX-WS servlet registered (if servlet could be deployed from Spring without web.xml , we could have gotten rid of this altogether!)
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
          http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
         version="2.5">

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:spring-ws.xml</param-value>
    </context-param>


    <listener>
        <listener-class>
            org.springframework.web.context.ContextLoaderListener
        </listener-class>
    </listener>

    <servlet>
        <servlet-name>jaxws-servlet</servlet-name>
        <servlet-class>
            com.sun.xml.ws.transport.http.servlet.WSSpringServlet
        </servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>jaxws-servlet</servlet-name>
        <url-pattern>*.ws</url-pattern>
    </servlet-mapping>
</web-app>
I used WSSpringServlet class as major web service servlet. Then I mapped any *.ws to this servlet.

spring-ws.xml is spring context configuration also containing web service configuration.
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns:beans="http://www.springframework.org/schema/beans"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xmlns:ws="http://jax-ws.dev.java.net/spring/core"
             xmlns:wss="http://jax-ws.dev.java.net/spring/servlet"
             xmlns:context="http://www.springframework.org/schema/context"
             xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
      http://jax-ws.dev.java.net/spring/core
      http://jax-ws.dev.java.net/spring/core.xsd
      http://jax-ws.dev.java.net/spring/servlet
      http://jax-ws.dev.java.net/spring/servlet.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

    <context:component-scan base-package="com.ws.service"/>

    <wss:binding url="/hello.ws">
        <wss:service>
            <ws:service bean="#helloService"></ws:service>
        </wss:service>
    </wss:binding>

    <wss:binding url="/calculator.ws">
        <wss:service>
            <ws:service bean="#calculatorService"></ws:service>
        </wss:service>
    </wss:binding>

</beans:beans>
The two wss:binding definitions define what services are exposed to which part of the URL space. In the above code, it deploys two services on two URLs(hello, calculator). In "ws:service" tag we should map the specific url to its spring bean. We should determine it on this way: '#'+'bean id'. I have two spring components in spring context including: helloService and calculatorService. component-scan tag would find them.


helloService
package com.ws.service;

import org.springframework.stereotype.Component;

import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import javax.jws.soap.SOAPBinding.Style;
import javax.jws.soap.SOAPBinding.Use;

@Component("helloService")
@WebService(serviceName = "Hello",
        portName = "HelloPort",
        targetNamespace = "http://service.ws.com/")
@SOAPBinding(style = Style.RPC, use = Use.LITERAL)
public class HelloService{

    @WebMethod
    public String sayHello(@WebParam(name = "name") String name) {
        return "Hello " + name;
    }

}

calculatorService
package com.ws.service;

import org.springframework.stereotype.Component;

import javax.jws.WebService;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.soap.SOAPBinding;

@Component("calculatorService")
@WebService(serviceName = "Calculator",
        portName = "CalculatorPort",
        targetNamespace = "http://service.ws.com/")
@SOAPBinding(style = SOAPBinding.Style.RPC, use = SOAPBinding.Use.LITERAL)
public class CalculatorService {
    @WebMethod
    public Float add(@WebParam(name = "input1") Float input1, @WebParam(name = "input2") Float input2) {
        return input1 + input2;
    }
    @WebMethod
    public Float subtract(@WebParam(name = "input1") Float input1, @WebParam(name = "input2") Float input2) {
        return input1 - input2;
    }
    @WebMethod
    public Float multiply(@WebParam(name = "input1") Float input1, @WebParam(name = "input2") Float input2) {
        return input1 * input2;
    }
    @WebMethod
    public Float devide(@WebParam(name = "input1") Float input1, @WebParam(name = "input2") Float input2) {
        return input1 / input2;
    }
}

We should determine the serviceName, portName, targetNamespace in WebService annotation to use them in client side code.

Now two web services are ready to use. When you run your server side application, you can find these two web services here:
  • http://localhost:8080/hello.ws
  • http://localhost:8080/calculator.ws

and their WSDL are available here:

  • http://localhost:8080/hello.ws?wsdl
  • http://localhost:8080/calculator.ws?wsdl
4. Client Side
In client side we should define these two beans(hello, calculator) in spring context. But there are no implementation of them. We should bind them via SOAPBinding to the client interface of them. So first we should create these two interfaces:
HelloService
package com.ws.service;

import javax.jws.WebService;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.soap.SOAPBinding;

@WebService
@SOAPBinding(style = SOAPBinding.Style.RPC, use = SOAPBinding.Use.LITERAL)
public interface HelloService {
    public String sayHello(@WebParam(name = "name") String name);
}
CalculatorService
package com.ws.service;

import javax.jws.WebService;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.soap.SOAPBinding;

@WebService
@SOAPBinding(style = SOAPBinding.Style.RPC, use = SOAPBinding.Use.LITERAL)
public interface CalculatorService {
    @WebMethod
    Float add(@WebParam(name = "input1") Float input1, @WebParam(name = "input2") Float input2);

    @WebMethod
    Float subtract(@WebParam(name = "input1") Float input1, @WebParam(name = "input2") Float input2);

    @WebMethod
    Float multiply(@WebParam(name = "input1") Float input1, @WebParam(name = "input2") Float input2);

    @WebMethod
    Float devide(@WebParam(name = "input1") Float input1, @WebParam(name = "input2") Float input2);
}

Then in spring context configuration we should define these two bean on this way:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

    <context:component-scan base-package="com.calculator"/>

    <!--Tiles 2-->
    <bean id="tilesConfigurer" class="org.springframework.web.servlet.view.tiles2.TilesConfigurer">
        <property name="definitions">
            <list>
                <value>/WEB-INF/layout/tiles-config.xml</value>
            </list>
        </property>
    </bean>

    <bean id="tilesViewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver">
        <property name="viewClass" value="org.springframework.web.servlet.view.tiles2.TilesView"/>
        <property name="order" value="1"/>
    </bean>

    <!--webservice-->
    <bean id="helloService" class="org.springframework.remoting.jaxws.JaxWsPortProxyFactoryBean">
        <property name="serviceInterface" value="com.ws.service.HelloService"/>
        <property name="wsdlDocumentUrl" value="http://localhost:8080/hello.ws?WSDL"/>
        <property name="namespaceUri" value="http://service.ws.com/"/>
        <property name="serviceName" value="Hello"/>
        <property name="portName" value="HelloPort"/>
    </bean>

    <bean id="calculatorService" class="org.springframework.remoting.jaxws.JaxWsPortProxyFactoryBean">
        <property name="serviceInterface" value="com.ws.service.CalculatorService"/>
        <property name="wsdlDocumentUrl" value="http://localhost:8080/calculator.ws?WSDL"/>
        <property name="namespaceUri" value="http://service.ws.com/"/>
        <property name="serviceName" value="Calculator"/>
        <property name="portName" value="CalculatorPort"/>
    </bean>

</beans>

As you see, we use JaxWsPortProxyFactoryBean. This class will be an instance of the interface which you define in its "serviceInterface" property. "wsdlDocumentUrl", "namespaceUri", "serviceName" and "portName" properties are the values which you determined them in server side. You can also refer to the urls which these web services are exposed.

From now you have two new beans called: "helloService" and "calculatorService". You can autowrie them in your controllers and use them like 'CalculatorController' class
package com.calculator;

import org.springframework.stereotype.Controller;
import org.springframework.context.annotation.Scope;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.beans.factory.annotation.Autowired;
import com.base.BaseController;
import com.ws.service.CalculatorService;

/**
 * User: mostafa
 * Date: Jun 27, 2011
 * Time: 9:19:40 AM
 */
@Controller
@Scope("prototype")
@RequestMapping("/calculator")
public class CalculatorController extends BaseController {
    @Autowired
    CalculatorService calculatorService;

    Float input1;
    Float input2;
    Float result;

    public Float getInput1() {
        return input1;
    }

    public void setInput1(Float input1) {
        this.input1 = input1;
    }

    public Float getInput2() {
        return input2;
    }

    public void setInput2(Float input2) {
        this.input2 = input2;
    }

    public Float getResult() {
        return result;
    }

    public void setResult(Float result) {
        this.result = result;
    }

    public void init() {
    }

    @RequestMapping("/view")
    public String view() {
        return "calculator.view";
    }

    @RequestMapping("/add")
    public String add() {
        result = calculatorService.add(input1, input2);
        return view();
    }

    @RequestMapping("/subtract")
    public String subtract() {
        result = calculatorService.subtract(input1, input2);
        return view();
    }

    @RequestMapping("/multiply")
    public String multiply() {
        result = calculatorService.multiply(input1, input2);
        return view();
    }

    @RequestMapping("/devide")
    public String devide() {
        result = calculatorService.devide(input1, input2);
        return view();
    }

    @RequestMapping("/clear")
    public String clear() {
        return "redirect:view.html";
    }
}

6. Source Code
Here you can download the source code. When you extract zipped file, you will find two projects. You can run server side project (springWS) on port 8080 and client side project(springWSClient) on port 9090 for example. So the urls will be:
  • Server: http://localhost:8080/calculator.ws
  • Client: http://localhost:9090/calculator/view.html
enjoy yourselves
all rights reserved by Mostafa Rastgar and Programmer Assistant weblog

Saturday, May 28, 2011

JQuery-Plugin, JQuery Dialog

Hey...

In the most web applications we need a dialog to show extra information, confirm or alert something, view the detail of selected row of current table and so on. A dialog is a floating window that contains a title bar and a content area. The dialog window can be moved, resized and closed with the 'x' icon by default. It can be a modal window or non-modal window but mostly modal mode is used. Here I'm going to present a very useful jquery base tool for dialog. JQuery Dialog is one of the useful component of JQueryUI plugin. You can find useful information of it from here.

Like other JQueryUI plugins, this plugin is also should be initiated first and withing the initiation you can set some properties or change the default of them. A very simple call of dialog is like this:
<div id="dialog" title="User View">This is my first dialog</div>
<script type="text/javascript">
    $(function() {
        $("#dialog").dialog("open");
    });
</script>
As you see, You should prepare a div then place every things you want in it. Then create a script to make it as a dialog. so you should do it on you page start up.
The table of options, methods and events are available here:

Live Demo:

This is the default dialog which is useful for displaying information. The dialog window can be moved, resized and closed with the 'x' icon.



Please click this button to display a simple dialog:

Options:

NameTypeDefaultDescription
disabledBooleanfalseDisables (true) or enables (false) the dialog. Can be set when initialising (first creating) the dialog.
Code examples

Initialize a dialog with the disabled option specified.

    $( ".selector" ).dialog({ disabled: true });

Get or set the disabled option, after init.

    //getter
    var disabled = $( ".selector" ).dialog( "option", "disabled" );
    //setter
    $( ".selector" ).dialog( "option", "disabled", true );
autoOpenBooleantrueWhen autoOpen is true the dialog will open automatically when dialog is called. If false it will stay hidden until .dialog("open") is called on it.
Code examples

Initialize a dialog with the autoOpen option specified.

    $( ".selector" ).dialog({ autoOpen: false });

Get or set the autoOpen option, after init.

    //getter
    var autoOpen = $( ".selector" ).dialog( "option", "autoOpen" );
    //setter
    $( ".selector" ).dialog( "option", "autoOpen", false );
buttonsBoolean{ }Specifies which buttons should be displayed on the dialog. The property key is the text of the button. The value is the callback function for when the button is clicked. The context of the callback is the dialog element; if you need access to the button, it is available as the target of the event object.
Code examples

Initialize a dialog with the buttons option specified.

    $( ".selector" ).dialog({ buttons: { "Ok": function() { $(this).dialog("close"); } } });

Get or set the buttons option, after init.

    //getter
    var buttons = $( ".selector" ).dialog( "option", "buttons" );
    //setter
    $( ".selector" ).dialog( "option", "buttons", { "Ok": function() { $(this).dialog("close"); } } );
buttonsArray[ ]Specifies which buttons should be displayed on the dialog. Each element of the array must be an Object defining the properties to set on the button.
Code examples

Initialize a dialog with the buttons option specified.

    $( ".selector" ).dialog({ buttons: [
        {
            text: "Ok",
            click: function() { $(this).dialog("close"); }
        }
    ] });

Get or set the buttons option, after init.

    //getter
    var buttons = $( ".selector" ).dialog( "option", "buttons" );
    //setter
    $( ".selector" ).dialog( "option", "buttons", [
        {
            text: "Ok",
            click: function() { $(this).dialog("close"); }
        }
    ] );
closeOnEscapeBooleantrueSpecifies whether the dialog should close when it has focus and the user presses the esacpe (ESC) key.
Code examples

Initialize a dialog with the closeOnEscape option specified.

    $( ".selector" ).dialog({ closeOnEscape: false });

Get or set the closeOnEscape option, after init.

    //getter
    var closeOnEscape = $( ".selector" ).dialog( "option", "closeOnEscape" );
    //setter
    $( ".selector" ).dialog( "option", "closeOnEscape", false );
closeTextString'close'Specifies the text for the close button. Note that the close text is visibly hidden when using a standard theme.
Code examples

Initialize a dialog with the closeText option specified.

    $( ".selector" ).dialog({ closeText: 'hide' });

Get or set the closeText option, after init.

    //getter
    var closeText = $( ".selector" ).dialog( "option", "closeText" );
    //setter
    $( ".selector" ).dialog( "option", "closeText", 'hide' );
dialogClassString''The specified class name(s) will be added to the dialog, for additional theming.
Code examples

Initialize a dialog with the dialogClass option specified.

    $( ".selector" ).dialog({ dialogClass: 'alert' });

Get or set the dialogClass option, after init.

    //getter
    var dialogClass = $( ".selector" ).dialog( "option", "dialogClass" );
    //setter
    $( ".selector" ).dialog( "option", "dialogClass", 'alert' );
draggableBooleantrueIf set to true, the dialog will be draggable will be draggable by the titlebar.
Code examples

Initialize a dialog with the draggable option specified.

    $( ".selector" ).dialog({ draggable: false });

Get or set the draggable option, after init.

    //getter
    var draggable = $( ".selector" ).dialog( "option", "draggable" );
    //setter
    $( ".selector" ).dialog( "option", "draggable", false );
heightNumber'auto'The height of the dialog, in pixels. Specifying 'auto' is also supported to make the dialog adjust based on its content.
Code examples

Initialize a dialog with the height option specified.

    $( ".selector" ).dialog({ height: 530 });

Get or set the height option, after init.

    //getter
    var height = $( ".selector" ).dialog( "option", "height" );
    //setter
    $( ".selector" ).dialog( "option", "height", 530 );
hideStringnullThe effect to be used when the dialog is closed.
Code examples

Initialize a dialog with the hide option specified.

    $( ".selector" ).dialog({ hide: 'slide' });

Get or set the hide option, after init.

    //getter
    var hide = $( ".selector" ).dialog( "option", "hide" );
    //setter
    $( ".selector" ).dialog( "option", "hide", 'slide' );
maxHeightNumberfalseThe maximum height to which the dialog can be resized, in pixels.
Code examples

Initialize a dialog with the maxHeight option specified.

    $( ".selector" ).dialog({ maxHeight: 400 });

Get or set the maxHeight option, after init.

    //getter
    var maxHeight = $( ".selector" ).dialog( "option", "maxHeight" );
    //setter
    $( ".selector" ).dialog( "option", "maxHeight", 400 );
maxWidthNumberfalseThe maximum width to which the dialog can be resized, in pixels.
Code examples

Initialize a dialog with the maxWidth option specified.

    $( ".selector" ).dialog({ maxWidth: 600 });

Get or set the maxWidth option, after init.

    //getter
    var maxWidth = $( ".selector" ).dialog( "option", "maxWidth" );
    //setter
    $( ".selector" ).dialog( "option", "maxWidth", 600 );
minHeightNumber150The minimum height to which the dialog can be resized, in pixels.
Code examples

Initialize a dialog with the minHeight option specified.

    $( ".selector" ).dialog({ minHeight: 300 });

Get or set the minHeight option, after init.

    //getter
    var minHeight = $( ".selector" ).dialog( "option", "minHeight" );
    //setter
    $( ".selector" ).dialog( "option", "minHeight", 300 );
minWidthNumber150The minimum width to which the dialog can be resized, in pixels.
Code examples

Initialize a dialog with the minWidth option specified.

    $( ".selector" ).dialog({ minWidth: 400 });

Get or set the minWidth option, after init.

    //getter
    var minWidth = $( ".selector" ).dialog( "option", "minWidth" );
    //setter
    $( ".selector" ).dialog( "option", "minWidth", 400 );
modalBooleanfalseIf set to true, the dialog will have modal behavior; other items on the page will be disabled (i.e. cannot be interacted with). Modal dialogs create an overlay below the dialog but above other page elements.
Code examples

Initialize a dialog with the modal option specified.

    $( ".selector" ).dialog({ modal: true });

Get or set the modal option, after init.

    //getter
    var modal = $( ".selector" ).dialog( "option", "modal" );
    //setter
    $( ".selector" ).dialog( "option", "modal", true );
positionString, Array'center'Specifies where the dialog should be displayed. Possible values:
1) a single string representing position within viewport: 'center', 'left', 'right', 'top', 'bottom'.
2) an array containing an x,y coordinate pair in pixel offset from left, top corner of viewport (e.g. [350,100])
3) an array containing x,y position string values (e.g. ['right','top'] for top right corner).
Code examples

Initialize a dialog with the position option specified.

    $( ".selector" ).dialog({ position: 'top' });

Get or set the position option, after init.

    //getter
    var position = $( ".selector" ).dialog( "option", "position" );
    //setter
    $( ".selector" ).dialog( "option", "position", 'top' );
resizableBooleantrueIf set to true, the dialog will be resizeable.
Code examples

Initialize a dialog with the resizable option specified.

    $( ".selector" ).dialog({ resizable: false });

Get or set the resizable option, after init.

    //getter
    var resizable = $( ".selector" ).dialog( "option", "resizable" );
    //setter
    $( ".selector" ).dialog( "option", "resizable", false );
showStringnullThe effect to be used when the dialog is opened.
Code examples

Initialize a dialog with the show option specified.

    $( ".selector" ).dialog({ show: 'slide' });

Get or set the show option, after init.

    //getter
    var show = $( ".selector" ).dialog( "option", "show" );
    //setter
    $( ".selector" ).dialog( "option", "show", 'slide' );
stackBooleantrueSpecifies whether the dialog will stack on top of other dialogs. This will cause the dialog to move to the front of other dialogs when it gains focus.
Code examples

Initialize a dialog with the stack option specified.

    $( ".selector" ).dialog({ stack: false });

Get or set the stack option, after init.

    //getter
    var stack = $( ".selector" ).dialog( "option", "stack" );
    //setter
    $( ".selector" ).dialog( "option", "stack", false );
titleString''Specifies the title of the dialog. Any valid HTML may be set as the title. The title can also be specified by the title attribute on the dialog source element.
Code examples

Initialize a dialog with the title option specified.

    $( ".selector" ).dialog({ title: 'Dialog Title' });

Get or set the title option, after init.

    //getter
    var title = $( ".selector" ).dialog( "option", "title" );
    //setter
    $( ".selector" ).dialog( "option", "title", 'Dialog Title' );
widthNumber300The width of the dialog, in pixels.
Code examples

Initialize a dialog with the width option specified.

    $( ".selector" ).dialog({ width: 460 });

Get or set the width option, after init.

    //getter
    var width = $( ".selector" ).dialog( "option", "width" );
    //setter
    $( ".selector" ).dialog( "option", "width", 460 );
zIndexInteger1000The starting z-index for the dialog.
Code examples

Initialize a dialog with the zIndex option specified.

    $( ".selector" ).dialog({ zIndex: 3999 });

Get or set the zIndex option, after init.

    //getter
    var zIndex = $( ".selector" ).dialog( "option", "zIndex" );
    //setter
    $( ".selector" ).dialog( "option", "zIndex", 3999 );


Events:

NameTypeDescription
createdialogcreateThis event is triggered when dialog is created.
Code examples

Supply a callback function to handle the create event as an init option.

    $( ".selector" ).dialog({
       create: function(event, ui) { ... }
    });

Bind to the create event by type: dialogcreate.

    $( ".selector" ).bind( "dialogcreate", function(event, ui) {
      ...
    });
beforeClosedialogbeforecloseThis event is triggered when a dialog attempts to close. If the beforeClose event handler (callback function) returns false, the close will be prevented.
Code examples

Supply a callback function to handle the beforeClose event as an init option.

    $( ".selector" ).dialog({
       beforeClose: function(event, ui) { ... }
    });

Bind to the beforeClose event by type: dialogbeforeclose.

    $( ".selector" ).bind( "dialogbeforeclose", function(event, ui) {
      ...
    });
opendialogopenThis event is triggered when dialog is opened.
Code examples

Supply a callback function to handle the open event as an init option.

    $( ".selector" ).dialog({
       open: function(event, ui) { ... }
    });

Bind to the open event by type: dialogopen.

    $( ".selector" ).bind( "dialogopen", function(event, ui) {
      ...
    });
focusdialogfocusThis event is triggered when the dialog gains focus.
Code examples

Supply a callback function to handle the focus event as an init option.

    $( ".selector" ).dialog({
       focus: function(event, ui) { ... }
    });

Bind to the focus event by type: dialogfocus.

    $( ".selector" ).bind( "dialogfocus", function(event, ui) {
      ...
    });
dragStartdialogdragstartThis event is triggered at the beginning of the dialog being dragged.
Code examples

Supply a callback function to handle the dragStart event as an init option.

    $( ".selector" ).dialog({
       dragStart: function(event, ui) { ... }
    });

Bind to the dragStart event by type: dialogdragstart.

    $( ".selector" ).bind( "dialogdragstart", function(event, ui) {
      ...
    });
dragdialogdragThis event is triggered when the dialog is dragged.
Code examples

Supply a callback function to handle the drag event as an init option.

    $( ".selector" ).dialog({
       drag: function(event, ui) { ... }
    });

Bind to the drag event by type: dialogdrag.

    $( ".selector" ).bind( "dialogdrag", function(event, ui) {
      ...
    });
dragStopdialogdragstopThis event is triggered after the dialog has been dragged.
Code examples

Supply a callback function to handle the dragStop event as an init option.

    $( ".selector" ).dialog({
       dragStop: function(event, ui) { ... }
    });

Bind to the dragStop event by type: dialogdragstop.

    $( ".selector" ).bind( "dialogdragstop", function(event, ui) {
      ...
    });
resizeStartdialogresizestartThis event is triggered at the beginning of the dialog being resized.
Code examples

Supply a callback function to handle the resizeStart event as an init option.

    $( ".selector" ).dialog({
       resizeStart: function(event, ui) { ... }
    });

Bind to the resizeStart event by type: dialogresizestart.

    $( ".selector" ).bind( "dialogresizestart", function(event, ui) {
      ...
    });
resizedialogresizeThis event is triggered when the dialog is resized. demo
Code examples

Supply a callback function to handle the resize event as an init option.

    $( ".selector" ).dialog({
       resize: function(event, ui) { ... }
    });

Bind to the resize event by type: dialogresize.

    $( ".selector" ).bind( "dialogresize", function(event, ui) {
      ...
    });
resizeStopdialogresizestopThis event is triggered after the dialog has been resized.
Code examples

Supply a callback function to handle the resizeStop event as an init option.

    $( ".selector" ).dialog({
       resizeStop: function(event, ui) { ... }
    });

Bind to the resizeStop event by type: dialogresizestop.

    $( ".selector" ).bind( "dialogresizestop", function(event, ui) {
      ...
    });
closedialogcloseThis event is triggered when the dialog is closed.
Code examples

Supply a callback function to handle the close event as an init option.

    $( ".selector" ).dialog({
       close: function(event, ui) { ... }
    });

Bind to the close event by type: dialogclose.

    $( ".selector" ).bind( "dialogclose", function(event, ui) {
      ...
    });


Methods:

NameUsageDescription
destroy.dialog( "destroy" )Remove the dialog functionality completely. This will return the element back to its pre-init state.
disable.dialog( "disable" )Disable the dialog.
enable.dialog( "enable" )Enable the dialog.
option.dialog( "option" , optionName , [value] )Get or set any dialog option. If no value is specified, will act as a getter.
option.dialog( "option" , options )Set multiple dialog options at once by providing an options object.
widget.dialog( "widget" )Returns the .ui-dialog element.
close.dialog( "close" )Close the dialog.
isOpen.dialog( "isOpen" )Returns true if the dialog is currently open.
moveToTop.dialog( "moveToTop" )Move the dialog to the top of the dialogs stack.
open.dialog( "open" )Open the dialog.

Sample
Do you remember my post about JQGrid. I'm going to extend that sample making it popup base. I use JQuery Dialog as project popups. That project has two major parts and I'll make some changes in both of them:
  • User List: I'll show the detail of user in new window(using jquery dialog)
  • File List: I'll show delete confirmation using jquery dialog when user click delete button of the file list grid.
User List
Here is the user-list.jsp code:
<script type="text/javascript">
    function setFormAction(action) {
        document.getElementById("userForm").action = action;
    }
    function setUserId(id) {
        document.getElementById("userId").value = id;
    }
    function deleteAll() {
        if (confirm('Do you want to delete the selected rows?')) {
            setFormAction('<spring:url value="/user/delete.html"/>');
            return true;
        } else {
            return false;
        }
    }
    $(function() {
        $("#dialog").dialog({ autoOpen: false,
            resizable:true,
            draggable:true,
            show: "blind",
            hide: "explode",
            position: 'center',
            modal: true,
            closeOnEscape: true,
            buttons:[{text:"back", click : function() {
                $(this).dialog("close");
            }}]
        });
    });
    function showDialog(userid) {
        $("#userview").load("/user/view.html", {'user.id':userid});
        $("#dialog").dialog("open");
    }
</script>
<div id="dialog" title="User View"><div id="userview"></div></div>
<form:form id="userForm">
    <form:hidden path="user.id" id="userId"/>
    <table>
        <tr>
            <td>
                <label for="name">name</label>
            </td>
            <td>
                <form:input path="user.name" id="name"/>
            </td>
        </tr>
    </table>
    <input type="submit" value="search" onclick="setFormAction('<spring:url value="/user/list.html"/>')"/>
    <table>
        <tr>
            <th></th>
            <th>name</th>
            <th>username</th>
            <th></th>
        </tr>
        <c:forEach items="${userList}" var="user">
            <tr>
                <td>
                    <security:authorize access="hasRole('administrator')">
                        <input type="checkbox" name="ids" value="${user.id}"/>
                    </security:authorize>
                </td>
                <td>${user.name}</td>
                <td>${user.username}</td>
                <td>
                    <security:authorize access="hasRole('administrator')">
                        <input type="submit" value="edit"
                               onclick="setUserId(${user.id}); setFormAction('<spring:url value="/user/edit.html"/>');"/>
                    </security:authorize>
                    <input type="button" value="view"
                           onclick="showDialog(${user.id});"/>
                </td>
            </tr>
        </c:forEach>
    </table>
...
</form:form>
As you see, I should prepare a div to display my content(the blue line). But my content is not a fix content. I should load it dynamically whenever the view button is clicked via ajax. So firstly I create the dialog but do not display it(the red lines). Then I will call showDialog method in view button click(the green lines). In this method I load the user detail in 'userview' div then I show the dialog.

File List
Here is the file-list.jsp code:
...
<script type="text/javascript">
    function folder(cellValue, opts, rowObject) {
        if (!rowObject.file) {
            return "<div class='ui-state-default'><span class='ui-icon ui-icon-folder-collapsed'></span></div>";
        }
        return "<div></div>";
    }
    function edit(cellValue, opts, rowObject) {
        return "<input type='submit' value='edit' onclick='setFileId(" + rowObject.id + "); setFormAction(\"<spring:url value="/file/edit.html"/>\");'/>";
    }

    function setFormAction(action) {
        document.getElementById("fileForm").action = action;
    }

    function setFileId(id) {
        $("#fileId").val(id);
    }

    function setFolderId(id) {
        $("#folderId").val(id);
    }

    $(function() {
        $("#deleteConfirmDlg").dialog({ autoOpen: false,
            resizable:true,
            draggable:true,
            show: "blind",
            hide: "explode",
            position: 'center',
            modal: true,
            closeOnEscape: true,
            buttons:[{text:"cancel", click : function() {
                $(this).dialog("close");
            }}, {text:"ok", click:function() {
                var selectedRowIds = $("#fileGrid").getGridParam("selarrrow");
                var params = "";
                for (var i = 0; selectedRowIds[i]; i++) {
                    params += "ids=" + selectedRowIds[i] + "&";
                }
                $.ajax({
                    type: 'POST',
                    url: '<spring:url value="/file/delete.html"/>',
                    data: params,
                    success: function(msg) {
                        if (msg != '') {
                            alert(msg);
                        } else {
                            $("#deleteConfirmDlg").dialog("close");
                            $("#fileGrid").trigger("reloadGrid");
                        }
                    }
                });
            }}]
        });

        $("#deleteNoRowDlg").dialog({ autoOpen: false,
            dialogClass: 'alert',
            resizable:true,
            draggable:true,
            show: "blind",
            hide: "explode",
            position: 'center',
            modal: true,
            closeOnEscape: true,
            buttons:[{text:"ok", click : function() {
                $(this).dialog("close");
            }}]
        });

        $("#fileGrid").jqGrid({
            url:'${listUrl}',
            datatype:'json',
            contentType:'contentType:"application/json; charset=utf-8"',
            jsonReader:{repeatitems: false,id:"id"},
            direction:'ltr',
            width:'500',
            colNames:['','name', 'file','edit'],
            colModel:[{sortable:false, width:'20', formatter:folder},{name:'name',sortable:true},{name:'file',hidden:true},{align:'center', sortable:false, width:'50',formatter:edit}],
            rowNum:10,
            rowList:[10,20,30],
            pager:'#filePager',
            sortname:'id',
            viewrecords:true,
            multiselect:true,
            multiboxonly:true,
            sortorder:'desc',
            prmNames:{rows:'pagination.rowSizePerPage', page:'pagination.currentPage', sort:'pagination.sortIndex', order:'pagination.sortOrder'},
            caption:'File List',
            recordtext:'View {0} - {1} of {2}',
            emptyrecords:'No Records',
            loadtext:'Loading ...',
            pgtext:'Page {0} Of {1}',
            ondblClickRow: function(rowid) {
                var row = $("#fileGrid").getRowData(rowid);
                if (row.file == 'true') {
                    setFormAction('<spring:url value="/file/download.html"/>');
                    setFileId(rowid);
                    $("#fileForm").submit();
                } else {
                    setFormAction('<spring:url value="/file/list.html"/>');
                    setFolderId(rowid);
                    $("#fileForm").submit();
                }
            }
        });
        $("#fileGrid").jqGrid('navGrid', '#filePager', {search:false, edit:false, add:false, del:false}).navButtonAdd("#filePager", {
            caption:'',
            buttonicon: "ui-icon-plus",
            onClickButton:function() {
                setFormAction('<spring:url value="/file/add.html"/>');
                $("#fileForm").submit();
            },
            position:"first", title:'add'}).navButtonAdd("#filePager", {
            caption:'',
            buttonicon: "ui-icon-trash",
            onClickButton:function() {
                deleteSelectedRows();
            },
            position:"first", title:'delete selected rows'});
    });
    function deleteSelectedRows() {
        var selectedRowIds = $("#fileGrid").getGridParam("selarrrow");
        if (selectedRowIds.length > 0) {
            $("#deleteConfirmDlg").dialog("open");
        } else {
            $("#deleteNoRowDlg").dialog("open");
        }
    }
</script>
<div id="deleteConfirmDlg" title="Delete Confirmation">Are you sure to delete the selected rows?</div>
<div id="deleteNoRowDlg" title="No Rows Selected">you should select some rows</div>
<form:form id="fileForm">
...

</form:form>
Here we have 2 dialogs. One for delete confirmation other for no row selection alert. So I should prepare 2 divs for them(the green lines). Then I should initiate them(the blue lines). I should display them when the delete button is clicked(the red lines). Here I call the deleteSelectedRows method. In this method I check if any row is selected or not. If selected I should display the 'deleteConfirmDlg' dialog otherwise I should dislplay 'deleteNoRowDlg' dialog.

Source Code:
It's the time to download the source code and try it yourselves. The application needed jar files are the same as previous post example. So you can copy all of them to here: [app-root]/lib/
The application database script is available in [app-root]/db/filerepository.sql. you can restore it in your mysql server. the connection datasource properties is in [app-root]/src/database.properites. And after you deploy the project home page will be: http://localhost:8080/home/view.html
the admin user specification is:
username: administrator
password: 123456
you can use it to log in for the first time.


all rights reserved by Mostafa Rastgar and Programmer Assistant weblog