The code for this example can be found here.
Here is an interesting functionality I had to implement the other day:
- a floating / draggable window
- loads its content (a web control) from a web service through an AJAX callback, based on information that is sent from the client
- keeps the last location in cookies, when you come back the window pops up where you left it the last time
Here is how it will look like:
Let's start.
First of all, I am working with a Web Application project (which is included in Visual Studio 2008, but needs to be installed manually in Visual Studio 2005). With a simple Website project you might encounter problems with Web Services (for example, I was unable to access the classes for my user controls from inside the web service class).
I am adding the Javascript files that I need:
and putting them into the page:
<head runat="server">
<title>Untitled Page</title>
<script src="JS/jquery-1.2.6.pack.js" type="text/javascript"></script>
<script src="JS/jquery.easydrag.js" type="text/javascript"></script>
<script src="JS/JSON.js" type="text/javascript"></script>
<script src="JS/jquery.cookie.pack.js" type="text/javascript"></script>
</head>
You can get these files from the following locations:
Also, a reference to JSON .Net:
which you can get from here.
I am also adding a div for the draggable window (with a handle area containing a title and a close button, and a content area where we will load the data from the server):
<div>
<div id="divExample">
<div id="divExample_handle">
<span id="divExample_title">This is a draggable window</span> <span id="divExample_close">
<a href="javascript:clearExamplePosition();" id="lnkExampleClose">[ x ]</a></span>
</div>
<div id="divExample_content">
</div>
</div>
</div>
and a link to show / hide the draggable window:
<a href="#" id="lnkShowDraggableWindow">Show the draggable window</a>
To prepare the stage, let's add
- a JSON serializer helper:
using Newtonsoft.Json;
namespace DraggableWindow.CodeFiles
{
public delegate T Action<T>(T value);
public class JsonConverter
{
public static string Serialize(object entity)
{
return JavaScriptConvert.SerializeObject(entity);
}
}
}
public class BaseResponse
{
public string htmlValue { get; set; }
public IList<string> errorMessages { get; set; }
}
- a base service (which basically knows how to serialize a BaseResponse) - I am using an idea and some code from Rick Strahl's West Wind Ajax Toolkit for ASP.NET
- a user control to fill the content of the draggable window with (DraggableWindowContent.ascx)
- and finally the web service which will handle the client calls:
namespace DraggableWindow.Services
{
[ToolboxItem(false)]
[ScriptService]
public class DraggableWindowService : BaseService
{
[WebMethod(EnableSession = true)]
public string GetDraggableWindowContent(string text)
{
return Response(delegate(Page p)
{
DraggableWindowContent ctrl =
p.LoadControl("~/DraggableWindowContent.ascx") as
DraggableWindowContent;
if (ctrl != null) ctrl.Initialise(text);
return ctrl;
});
}
}
}
Back to the client-side, we need to initialize the draggable window:
if($ != 'undefined'){
$('document').ready(function(){
$("#divExample").easydrag();
$("#divExample").setHandler('divExample_handle');
$("#divExample").ondrop
(
function(e, element)
{
$.cookie('examplePosLeft', element.offsetLeft);
$.cookie('examplePosTop', element.offsetTop);
}
);
$('#lnkExampleClose').click(function()
{
$("#divExample").hide();
$.cookie('showExample', 0)
});
$('#lnkShowExample').click(function()
{
$.cookie('showExample', 1);
$.cookie('examplePosLeft', 100);
$.cookie('examplePosTop', 100);
loadData();
});
loadData();
});
}
We store the user preference of showing the window or not in the showExample cookie. The position cookies (examplePosLeft and examplePosTop) will be set each time the draggable window is dropped.
I also need to write the loadData method:
function loadData()
{
var show = $.cookie('showExample');
if (parseInt(show) == 0)
{
$("#divExample").hide();
return;
}
$("#divExample").show();
var left = $.cookie('examplePosLeft');
var top = $.cookie('examplePosTop');
if (left != undefined && left.length != 0 && top != undefined && top.length != 0)
{
$("#divExample").css('top', parseInt(top));
$("#divExample").css('left', parseInt(left));
}
var text = 'Client Side Text';
var dataForPost = {
someText : text
};
$.ajax({
type: "POST",
url : "/Services/DraggableWindowService.asmx/GetDraggableWindowContent",
contentType: "application/json; charset=utf-8",
dataType : "json",
data : JSON.stringify(dataForPost),
success : function(res){
var objReturned = eval("("+res.d+")");
$("#divExample_content")[0].innerHTML = objReturned.value;
},
error: function(res){
alert(res.responseText);
}
});
return false;
}
which checks if the user wants to see the draggable window or not. If yes, it puts it in the last known location and loads the content from the server.
That's it. You can get the code from here.