![]() |
Web Development »
Ajax and Atlas »
Samples
Beginner
License: The Code Project Open License (CPOL)
Jigsaw Puzzle Game using AJAX Drag and DropBy Ferreri Gabriele (Megasoft78)A jigsaw puzzle game using AJAX drag and drop (ASP.NET 2.0 AJAX Futures November CTP). |
C# (C# 1.0, C# 2.0, C# 3.0), Javascript, HTML, .NET (.NET 2.0, .NET 3.0, .NET 3.5), ASP.NET, Ajax, Dev
|
|
Advanced Search Add to IE Search |
|
|
|
||||||||||||||||

This tutorial is intended to explain quickly how to implement drag and drop using the ASP.NET 2.0 AJAX Futures November CTP. To explain this technology, I've created a simple project with a custom AJAX control that implements a jigsaw puzzle game.
When I started to learn the new ASP.NET AJAX framework, I asked my company to buy a book, and I chose an amazing book:
In this book, I found a chapter that explains how to use the PreviewDragDrop to implement drag and drop on web. I used this chapter and other information from Internet (Google) to create my AJAX control.
The basic idea within the ASP.NET AJAX Framework is to have a possibility to use object-oriented programming in JavaScript (simulated OOP) and make it similar to C#. Most C# features are available in JavaScript: namespace, class, interface, enum etc. Besides the OOP features is available the possibility to implement visual custom controls (client side controls) that extend the HTML elements' functionalities.
Basically, we have two types of controls (visual controls):
Sys.UI.Behavior)Sys.UI.Control)The difference is just logic, but whilst generally Sys.UI.Behavior is used to extend HTML element behaviors for different types of elements, Sys.UI.Control is used to extend HTML element behaviors for a single type of element.
For example, if we want to implement a behavior that shows an alert on the click event, we can create a class that extends Sys.UI.Behavior, and then we can use this code with several HTML element types: DIV, SPAN, INPUT etc.
//Namespace declaration
Type.registerNamespace("MyNamespace");
//Constructor
MyNamespace.MyBehavior = function(element)
{
MyNamespace.MyBehavior.initializeBase(this, [element]);
}
MyNamespace.MyBehavior.prototype =
{
initialize : function()
{
// Add event handler on click
// Parameters:
// 1) The HTML element
// 2) Event name without "on" ("onclick"="click")
// 3) Control instance
$addHandlers(this.get_element(), { "click" : this._onClick }, this);
},
dispose : function()
{
// Remove all events handlers for the current HTML element
$clearHandlers(this.get_element());
},
// Event handler onclick
_onClick : function(evt)
{
// Show the id of current HTML Element
alert(this.get_id());
}
};
// Register class
MyNamespace.MyBehavior.registerClass("MyNamespace.MyBehavior", Sys.UI.Behavior);
When we need to use it within our page, we can just write the following code:
// Create an instance of our Behavior
// and attach it to HTML element with id 'elementId'
// Parameters:
// 1) Class name with namespace
// 2) Properties in JSON format
// 3) Events in JSON format
// 4) References in JSON format
// 5) HMTL element
$create(MyNamespace.MyBehavior, {}, {}, {}, $get('elementId'));
If we need to implement behaviors for an element type or we need to implement a complex control (a visual control composed of different elements), we need to extend Sys.UI.Control.
Generally, control are not manually created using $create in JavaScript, but automatically generated by an ASP.NET Server Control (server side version of the control). This way, we can implement a server control and have design-time support within Visual Studio. When we want to create a AJAX enabled Server Control, we need to extend ScriptControl (instead of WebControl). This base class contains all methods useful to make a relation between the client control (JavaScript) and the server control (.NET).
In ScriptControl, we need to override two methods:
GetScriptDescriptors: pass the name of the JavaScript class and the properties to the client control.GetScriptReferences: pass the scripts used by our client control. (The ScriptManager automatically loads these scripts during page load).protected override IEnumerable<System.Web.UI.ScriptDescriptor> GetScriptDescriptors()
{
if (!string.IsNullOrEmpty(this.Filename))
{
ScriptControlDescriptor descriptor = new
ScriptControlDescriptor("JigsawPuzzleGameControl.PuzzleGameAjax",
this.ClientID);
descriptor.AddProperty("nRows", this.NRows);
descriptor.AddProperty("nColumns", this.NColumns);
yield return descriptor;
}
}
protected override IEnumerable<System.Web.UI.ScriptReference> GetScriptReferences()
{
if (!string.IsNullOrEmpty(this.Filename))
{
List<ScriptReference> scripts = new List<ScriptReference>();
ScriptReference scriptReference1 = new ScriptReference("PreviewScript.js",
"Microsoft.Web.Preview");
scripts.Add(scriptReference1);
ScriptReference scriptReference2 = new ScriptReference("PreviewDragDrop.js",
"Microsoft.Web.Preview");
scripts.Add(scriptReference2);
ScriptReference scriptReference3 = new ScriptReference();
scriptReference3.Path = this.Page.ClientScript.GetWebResourceUrl(this.GetType(),
"JigsawPuzzleGameControl.Resources.Helpers.js");
scripts.Add(scriptReference3);
ScriptReference scriptReference4 = new ScriptReference();
scriptReference4.Path = this.Page.ClientScript.GetWebResourceUrl(this.GetType(),
"JigsawPuzzleGameControl.Resources.PuzzleGameAjax.js");
scripts.Add(scriptReference4);
return scripts;
}
else
{
return new List<ScriptReference>();
}
}
To implement drag and drop in our control, we need to implement two interfaces within two client controls:
Sys.Preview.UI.IDropTarget: This control represents the drop areaSys.Preview.UI.IDragSource: This control represents the drag elementIn Sys.Preview.UI.IDropTarget, we need to implements the following methods:
get_dropTargetElement: return the HTML element of the drop areacanDrop: check if drop is available for a particular drag elementdrop: execute the drop actiononDragEnterTarget: normally used with onDragLeaveTarget to implement the visual effectonDragLeaveTarget: normally used with onDragEnterTarget to implement the visual effectWe also need to add an event handler within the method Initialize for the MouseDown event and then call Sys.Preview.UI.DragDropManager.startDragDrop:
initialize : function()
{
JigsawPuzzleGameControl.DragPuzzleGameAjaxElement.callBaseMethod(this,
"initialize");
$addHandlers(this.get_element(),
{ "mousedown" : this._onMouseDown }, this);
},
_onMouseDown : function(evt)
{
window._event = evt;
evt.preventDefault();
Sys.Preview.UI.DragDropManager.startDragDrop(this,
this.get_element(), null);
},
In Sys.Preview.UI.IDragSource, we need to implement the following methods:
get_dragDataType: return the type of the drag element (the string used in canDrop to check if the drag item is compatible with the drop area)getDragData: return data that drags the item and passes to the drop area (drop method)get_dragMode: return if the drag operation is Move or CopyonDragStart: is called when the drag operation startsonDragEnd: is called when the drag operation endsonDrag: is called when the drag operation is completedWe also need to register and unregister the client component as the drop area:
initialize : function()
{
JigsawPuzzleGameControl.DropPuzzleGameAjaxElement.callBaseMethod(this, "initialize");
Sys.Preview.UI.DragDropManager.registerDropTarget(this);
},
dispose : function()
{
Sys.Preview.UI.DragDropManager.unregisterDropTarget(this);
JigsawPuzzleGameControl.DropPuzzleGameAjaxElement.callBaseMethod(this, "dispose");
},
The project is divided into two projects:
Within the library project is a class called PuzzleGameAjax that extends ScriptControl (the base class for all custom controls in AJAX). This class is the server side code of my control.
On the client side, we have three JavaScript classes:
PuzzleGameAjax (contains code to implement the game)DropPuzzleGameAjaxElement (contains code to implement a drop area)DragPuzzleGameAjaxElement (contains code to implement a drag area)DropPuzzleGameAjaxElement implements the Sys.Preview.UI.IDropTarget interface and DragPuzzleGameAjaxElement implements the Sys.Preview.UI.IDragSource interface. These two interfaces are used by the AJAX framework to handle the drag and drop in a generic way.
AJAX ASP.NET is a very good technology, and I'm currently working with it to implement a very complex behavior to improve the user experience. The drag and drop feature is absolutely the most user friendly feature, and it makes a software very intuitive to use. Normally, on web, this feature takes a lot of JavaScript code, but with PreviewDragDrop, everything is easy.
General
News
Question
Answer
Joke
Rant
Admin
|
PermaLink |
Privacy |
Terms of Use
Last Updated: 20 Apr 2008 Editor: Smitha Vijayan |
Copyright 2008 by Ferreri Gabriele (Megasoft78) Everything else Copyright © CodeProject, 1999-2009 Web18 | Advertise on the Code Project |