Friday, July 6, 2007

Drag and Drop -Ajax Page Elements

Ever wondered how Google creates personalized home
page with drag and drop effects.

Yes you can also create similar drag and drop page elements in your own web page by using Ajax Javascript libraries like Scriptaculous and Prototype.js in conjunction with StyleSheets.

Here is the code snippet to do that.
Step 1: Ajax JavaScript library
Download the latest scriptaculous js library from the site
http://script.aculo.us/downloads
To create the drag and drop elements in your page you will need the following js file from the scriptaculous library. You can remove all other js files from the library.
1. Dragdrop
2. Effects
3. Prototype
4. Scriptaculous

Step 2: JavaScript to produce draggable elements

Create a JavaScript file portal.js.
Include the following code to this file. The functions added here are used to create draggable page elements.
var Portal = Class.create();
Portal.prototype = {
initialize: function (options) {
this.setOptions(options);
var sortables = document.getElementsByClassName(
this.options.column, this.options.portal
);
sortables.each(function (sortable) {
Sortable.create(sortable, {
containment: sortables,
constraint: false,
tag: 'div',
only: this.options.block,
dropOnEmpty: true,
handle: this.options.handle,
hoverclass: this.options.hoverclass,
onUpdate: function (container) {
if (!this.options.saveurl) {
return;
}
if (container.id == this.options.blocklist) {
return;
}
var url = this.options.saveurl;
var postBody = container.id + ':';
var blocks = document.getElementsByClassName(
this.options.block, container
);
postBody += blocks.pluck('id').join(',');
postBody = 'value=' + escape(postBody);

new Ajax.Request(url, {
method: 'post',
postBody: postBody
}
);
}.bind(this)
});
}.bind(this));

var blocks = document.getElementsByClassName(
this.options.block, this.options.portal
);
blocks.each(
function (block) {
var content = Element.childrenWithClassName(
block, this.options.content, true
);

var toggle = Element.childrenWithClassName(
block, this.options.toggle, true
);
Event.observe(
toggle, 'click',
function (e) { Effect.toggle(content, 'Slide'); },
false
);

}.bind(this)
);

Event.observe(
this.options.blocklistlink, 'click',
this.displayBlockList.bindAsEventListener(this),
false
);

new Draggable(this.options.blocklist, {
handle: this.options.blocklisthandle
}
);

},

displayBlockList: function (e) {
Effect.toggle(this.options.blocklist);
Event.stop(e);
},

setOptions: function (options) {
this.options = {
portal: 'portal',
column: 'portal-column',
block: 'block',
content: 'content',
handle: 'handle',
hoverclass: 'block-hover',
toggle: 'block-toggle',
blocklist: 'portal-column-block-list',
blocklistlink: 'portal-block-list-link',
blocklisthandle: 'block-list-handle',
saveurl: ''
}
Object.extend(this.options, options || {});
},

applySettings: function (settings) {
for (var container in settings) {
settings[container].each(function (block) {
$(container).appendChild($(block));
});
}
}
}

Step 3: CSS file
Create a CSS file portal.css. This CSS file is needed to produce the drag and drop effect in your page.
Copy the following contents into the file
#portal .portal-column {
float: left;
width: 30%;
margin: 5px;
padding: 5px;

}
#portal .portal-column h2 {
color: #bbb;
text-align: center;
}

#portal #portal-column-block-list {
position: absolute;
width: 200px;
top: 140px;
left: 0;
z-index: 10;
background-color: #FFEAB1;
}
#portal #portal-column-block-list .block {
margin: 2px;
}
#portal #portal-column-block-list .block .content {
display: none;
}

#portal .block {
margin: 15px;
padding: 5px;
border: 1px solid #0F3974;
}
#portal .block h3 {
margin: 0;
padding: 5px;
font-size: 14px;
color: #fff;
background-color: #2153AA;
}
#portal .block .content {
padding: 5px;
}
#portal .block .block-toggle {
background-image: url(block-slide.png);
display: block;
float: right;
width: 7px;
height: 7px;
background-repeat: no-repeat;
background-position: center;
cursor: pointer;
}
#portal .block .block-toggle span {
display: none;
}

#portal .block-hover {
border: 1px dashed #f00;
}

#portal .block-list-handle, #portal .handle {
cursor: move;
}
* html body #portal .handle {
width: 100%;
}
#portal #portal-column-block-list .block .block-toggle {
display: none;
}

Step 4: HTML Page

In your html page include the following javascript libraries and css files
1. Prototype.js
2. Scriptaculous.js
3. Portal.js
4. Portal.css
The Scriptaculous.js and Prototype.js internally uses DragDrop and Effect js.
Make sure these files are included in your lib folder.
To make a page element draggable enclose the element within the following div tags

<div class="portal-column" id="portal-column-0">
<div class="block block-archive" id="Div1">
[Draggable page element]
</div>
</div>

To create a droppable column in your page add the following div tags

<div class="portal-column" id="portal-column-block-list">
[Page column – Page elements can be dragged to this column]
</div>

Sample html code:

Here is the entire code sample which can be used to test the drag and drop effect.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<title>Ajax Drag and Drop</title>
<script type="text/javascript" src="lib/prototype.js">
</script>
<script type="text/javascript" src="lib/scriptaculous.js">
</script>
<script type="text/javascript" src="lib/portal.js">

</script>
<script type="text/javascript">
//<!--
var settings = {};
var portal;
function init() {
portal = new Portal();
portal.applySettings(settings);
}
Event.observe(window, 'load', init, false);
//-->
</script>
<style type="text/css" media="all"> @import "css/portal.css";
</style>
</head>
<body>
<div id="portal">
<div class="portal-column" id="portal-column-0">
<div class="block block-archive" id="Div1">
Draggable item 1
</div>
</div>
<div class="portal-column" id="portal-column-block-list">
<div class="block block-archive" id="block-archive-0">
Draggable item 2
</div>
<div class="block block-archive" id="block-archive-1">
Draggable item 3
</div>
</div>
</div>
</body>
</html>

Now you can drag any page element included within the “block block-archive column” to the column marked by the “portal-column block-list” in the page.

In the above sample you will be able to drag the text marked “Drag1” to the column created by “portal-column-block-list” id.

Tuesday, July 3, 2007

Javascript debugger

Here are a few tips to debug a javascript code

1.Use alert statement to check the values of the variables.
2.Use firefox javascript debugger option to check for javascript errors.
3.IE also provides with the error status which gives you the line number where the error occured.
4.One of the best ways to debug is using the visual studio.If you have visual studio installed write a 'debugger;' statement to set the breakpoint in the javascript code.When the execution reaches this code ,the visual studio prompts you to attach the debugger to this code.You can do a line by line debugging and also check for variable values by this method.

Monday, July 2, 2007

Debugging a JSP Page

Here are a few techniques which i use for debugging a JSP Page.

Debugging a JSP Page is not the same as debugging a Java program.
A Java program has is own set of rules.This makes it easy to find the problem.Whereas a JSP is a combination of html tags and java.The html tags behave differently in different browsers.Though the rules are defined the results are unexpected sometime because of browser behavior.Compared to html, JSP has well defined tags, which means there is a end tag for every begin tag.

One of the first thing you have to look when your changes does not get reflected in the JSP Page is if the page is properly deployed.An easy technique to do this is clear the contents of the page, make a copy separately and create an empty page.Deploy this page and view it in a browser.You will see nothing in this page.Copy the contents again and deploy to see the page.You can see the changes made to the page this time.The reason for this is sometimes the JSP container gets the contents from the cache.Hence you were not able to see your changes in the first case.By clearing the contents we reduce the file size.By doing this we force the container not to take the page from cache.

This technique helped me reduce the effort.Hope this is useful.