Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Ajax In Action (2006).pdf
Скачиваний:
63
Добавлен:
17.08.2013
Размер:
8.36 Mб
Скачать

Implementing DHTML windows

439

 

 

11.4 Implementing DHTML windows

Our Ajax portal has a rich user interface that allows the user to dynamically position the windows. The user can also set the size of the window to the desired width and height. When the user changes these settings, we can use Ajax to interact with the server to store them as values in our database without the user even knowing anything is happening.

To enable this, we need to develop a database table to store the window properties such as height, width, and position. The server-side code needs to receive these new window properties and update the values in the database.

Writing browser-compliant DHTML can be complicated, so we are using a DHTML library script to perform the drag, drop, and resizing of the window. A library is nothing more than an external JavaScript file that contains all of the code for a given functionality. You can obtain the JavaScript library, JSWindow.js, for this project with the rest of the book’s downloads. We will need to make only a few modifications to the library to enable Ajax.

11.4.1The portal windows database

We need a database table that can hold the properties of several DHTML windows for each user. Each user can have multiple rows in this table, one for every window she has in her portal. The table is used to retrieve the last-known position and size of the window when the user first logs in. When the user makes changes, the values are then updated so that she can access them at future times and still see the same layout. The following SQL will create the portal_windows table:

create table portal_windows( id int primary key not null, user_id int not null,

xPos int not null, yPos int not null, width int not null, height int not null,

url varchar(255) not null, title varchar(255) not null

);

Each user can have multiple windows, all with different configurations. The column named user_id relates to our users database. Each of the windows must have an id as the primary key, so we can use this to save and update properties. Make sure you add the auto increment for the window’s id column. This id column is used by the Ajax code and the DHTML window library to obtain and update the user’s window properties.

440CHAPTER 11

The enhanced Ajax web portal

Figure 11.10 portal_windows database table structure

We need two columns to hold the x and y coordinates of our DHTML window. These give us the location of the window on the screen from the upper-left corner of the browser. The column names for coordinates are xPos and yPos. Two other properties we need to capture are the width and height properties of the DHTML window. These are all stored as integers in the table.

The last two columns in our database determine the URL of the content within the window and the title of the content that the user assigns as a quick reference. All of the database properties for portal_windows are shown in figure 11.10.

Now we need to enter some default values so we can perform some testing. We can add as many windows as we want for any of the users in the database table users. You can see in figure 11.10 that we have added three DHTML windows for user 1.

In figure 11.11, the three DHTML window parameters give us the information needed to create three windows on the screen with different dimensions and positions. The three windows in this table display three different websites: JavaRanch, Google, and Eric’s Ajax Blog. Now that the database table has been built, we have to get this information to the user when he logs into the portal. You’ll see how straightforward this is in the next section.

Figure 11.11 Data entered for the user with the id of 1

Implementing DHTML windows

441

 

 

11.4.2The portal window’s server-side code

Let’s assume that our login request has made it through the security filter. The next step is to retrieve the list of portal windows for our authenticated user and send back the JavaScript telling the browser what to display. We define a PortalWindow object that represents a row of data in the database, as shown in listing 11.7.

Listing 11.7 PortalWindow.java

public class PortalWindow { private int id=-1; private User user=null; private int xPos=0; private int yPos=0; private int width=0; private int height=0; private String url=null;

private String title=null;

public PortalWindow(

int id, User user, int xPos, int yPos, int width,int height,

String url, String title

) {

this.id = id; this.user = user; this.xPos = xPos; this.yPos = yPos; this.width = width; this.height = height; this.url = url; this.title = title;

}

public int getHeight() {return height;}

public void setHeight(int height) {this.height = height;} public int getId() {return id;}

public void setId(int id) {this.id = id;} public String getTitle() {return title;}

public void setTitle(String title) {this.title = title;} public String getUrl() {return url;}

public void setUrl(String url) {this.url = url;} public User getUser() {return user;}

public void setUser(User user) {this.user = user;} public int getWidth() {return width;}

public void setWidth(int width) {this.width = width;} public int getXPos() {return xPos;}

public void setXPos(int pos) {xPos = pos;}

442CHAPTER 11

The enhanced Ajax web portal

public int getYPos() {return yPos;}

public void setYPos(int pos) {yPos = pos;}

}

Again, this object is pretty much a straightforward mapping of the database structure. In production, we’d probably use an ORM system such as Hibernate or iBATIS to help us out, but we want to keep things fairly simple and platform-agnostic for now. Note that we provide setter methods as well as getters for this object, because we’ll want to update these objects dynamically in response to user events.

The URL that we requested on login, portalLogin.servlet, is mapped to a servlet that retrieves all the portal windows for that user and sends back JavaScript instructions. Listing 11.8 shows the main servlet.

Listing 11.8 SelectServlet.java (mapped to 'portalLogin.servlet')

public class SelectServlet extends HttpServlet { protected void doPost(

HttpServletRequest request, HttpServletResponse response

) throws ServletException, IOException { HttpSession session=request.getSession(); User user=(User)

(session.getAttribute("user"));

b Check session

StringBuffer jsBuf=new StringBuffer();

if (user==null){

 

 

 

 

 

jsBuf.append(JSUtil.logout());

 

 

 

 

}else{

 

c Define object

List windows=DBUtil

 

 

 

 

 

 

.getPortalWindows(user);

 

 

 

 

d Utilize the JSUtil object

 

 

 

 

jsBuf.append(JSUtil.initUI());

 

 

 

 

 

 

for (Iterator iter=windows.iterator();iter.hasNext();){ PortalWindow window=(PortalWindow)(iter.next()); session.setAttribute("window_"+window.getId(),window); jsBuf.append

(JSUtil.initWindow(window)); e Declare portal window

}

}

Writer writer=response.getWriter(); writer.write(jsBuf.toString()); f Write to output stream writer.flush();

}

}

Again, we use the DBUtil object to abstract out the database interactions and the JSUtil to generate JavaScript code. DBUtil provides a getPortalWindows()

Implementing DHTML windows

443

 

 

method cthat takes a User object as an argument. We have one of those sitting in the session, so we pull it out now b. The actual JavaScript is written by the JSUtil object again, providing some user interface initialization code d, declaring each of the portal windows that we’ve extracted from the database e and then writing them directly to the servlet output stream f.

Let’s briefly review the helper objects that we’ve used along the way, DBUtil and JSUtil. We used DBUtil to get a list of the portal windows. As we noted, we’d probably automate this in production using Hibernate or something similar; but listing 11.9 provides a method from DBUtil that is a simple home-rolled implementation of accessing the portal_windows table in the database, for teaching purposes. We’re using straightforward SQL directly here, so it should be easy to adapt to the server language of your choice.

Listing 11.9 getPortalWindows() method

public static List getPortalWindows(User user){ List list=new ArrayList();

Connection conn=getConnection(); try{

String sql="SELECT * FROM portal_windows "

+"WHERE user_id="+user.getId(); b Construct SQL statement Statement stmt=conn.createStatement();

ResultSet rs=stmt.executeQuery(sql); PortalWindow win=null;

while (rs.next()){ c Iterate through results int id=rs.getInt("id");

int x=rs.getInt("xPos"); int y=rs.getInt("yPos"); int w=rs.getInt("width"); int h=rs.getInt("height");

String url=rs.getString("url"); String title=rs.getString("title");

win=new PortalWindow( d Add Object

id,user,x,y,w,h,url,title

);

list.add(win);

}

rs.close();

stmt.close();

}catch (SQLException sqlex){

}

return list;

}

444CHAPTER 11

The enhanced Ajax web portal

We simply construct the SQL statement b, iterate through the result set that it generates c, and add a PortalWindow object to our list in each case d.

Second, we use the JSUtil helper object to generate some initialization code and declare our window objects in JavaScript. The methods are basically exercises in string concatenation, and we won’t show the full class here. The following code gives a flavor of how it works:

public static String initWindow(PortalWindow window) { StringBuffer jsBuf=new StringBuffer()

.append("CreateWindow(new NewWin('")

.append(window.getId())

.append("',")

.append(window.getXPos())

.append(",")

.append(window.getYPos())

.append(",")

.append(window.getWidth())

.append(",")

.append(window.getHeight())

.append(",'")

.append(window.getUrl())

.append("','")

.append(window.getTitle())

.append("'));\n"); return jsBuf.toString();

}

The initWindow() method generates the JavaScript code for initializing a single portal window. The JavaScript code from a successful request might look like this, with initWindow() being called for each window in turn (the code has been formatted here for improved readability):

document.getElementById('login')

.innerHTML='Welcome back!' document.getElementById('defaultContent')

.style.display='none';

CreateWindow( new NewWin(

'1',612,115,615,260,

'http://www.javaranch.com','JavaRanch'

)

);

CreateWindow( new NewWin(

'2',10,115,583,260,

'http://www.google.com','Google'

)

);