follow me

Drag and Drop in javascript, and Save persisting position using ASP.net

Drag and Drop are one of the few jQuery's UI Library. jQuery UI provides abstractions for low-level interaction and animation, advanced effects and high-level, themeable widgets, built on top of the jQuery JavaScript Library, that you can use to build highly interactive web applications.

To make use of Draggables, you need to download the UI library and then use the ui.core and ui.draggable files along with jquery:


<script src="script/jquery-1.3.1.min.js" type="text/javascript"></script>
<script src="script/ui.core.min.js" type="text/javascript"></script>
<script src="script/ui.draggable.min.js" type="text/javascript"></script>

There are lots of demos you can see in some site about this drag and drop interactions of the elements but i think only few can give on how to save the persisting position of the dragged item across Postbacks, or even sessions.

So we need to have a simple example of asp.net form.


<form id="form1" runat="server">
<div id="div1" style="border: 1px solid blue; text-align: center; width: 100px; height: 20px;">
Move this text
</div>
</form>


Basically it looks like this:



The Javascript that makes the div draggable:


<script type="text/javascript">
$(function() {
$("#div1").draggable({
drag: function(event, ui) {
$("#div1").css("opacity", "0.6"); // Additional css. Transparency when drag.
},
stop: function(event, ui) {
saveCoords(ui.absolutePosition.left, ui.absolutePosition.top, ui.helper.attr('id'));
$("#div1").css("opacity", "1.0"); // Additional css. Full opacity when stopped
},
cursor: "move"
});
});
</script>


Take a look on the stop callback event a saveCoords() function will be called with 3 arguments are supplied: the x coordinate, y coordinate and the id of the current draggable - ui.helper.attr('id'). And here what that function does:


function saveCoords(x, y, el, id) {

$.ajax({
type: "POST",
url: "Coordinates.asmx/SaveCoords", // the function inside the handler
data: "{x: '" + x + "', y: '" + y + "', element: '" + el + "', userid: '1'}",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(response) {
if (response.d != '1') {
alert('Not Saved!');
}
},
error: function(response) {
alert(response.responseText);
}
});
}


This function makes a call to a Web Service called Coordinates, invoking its method, [url:]SaveCoords(). It passes [data:] in the x and y coordinates, the id of the element and a user ID (hardcoded for thos example, bit could be provided by a session variable, for instance). Here's the Web Service:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;
using System.Web.Script.Services;
using System.Data.SqlClient;
using System.Data;

///
/// Summary description for Coordinates
///
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]

//[System.ComponentModel.ToolboxItem(false)]
// To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line.
// [System.Web.Script.Services.ScriptService]

[ScriptService]
public class Coordinates : WebService
{
private String conString = System.Configuration.ConfigurationManager.ConnectionStrings["dragCon"].ConnectionString;

[WebMethod]
public int SaveCoords(int x, int y, string element, int userid)
{
int result = 0;
using (SqlConnection conn = new SqlConnection(conString))
{
string query = "UPDATE Coords SET xPos = @xPos, yPos = @yPos WHERE Element = @Element AND UserID = @UserID";
using (SqlCommand cmd = new SqlCommand(query, conn))
{
cmd.Parameters.AddWithValue("xPos", x);
cmd.Parameters.AddWithValue("yPos", y);
cmd.Parameters.AddWithValue("Element", element);
cmd.Parameters.AddWithValue("UserID", userid);
conn.Open();
result = (int)cmd.ExecuteNonQuery();
}
}
return result;
}


Note: in this sample i already had a database Drag in my server and a table name Coords with four fields xPos, yPos, Element and a UserID.

The WebMethod simply takes the arguments passed to it and saves them to the database. It returns the number of rows affected for error checking. Great. So the position of the element is saved. How does that get translated to a draggable being positioned where it was left when the page is next requested by the user with the ID of 1? We need another Web Method:


[WebMethod]
public DataSet GetSavedCoords(int userid)
{
DataSet dt = new DataSet();

string query = "SELECT xPos, yPos, Element FROM Coords WHERE UserID = '" + userid + "'";
SqlConnection con = new SqlConnection(conString);
SqlCommand cmd = new SqlCommand(query, con);
con.Open();

SqlDataAdapter sda = new SqlDataAdapter(cmd);
sda.Fill(dt);

return dt;
}


Taking the User ID as an argument, this method returns a DataSet filled with the positions of all elements saved against the user, and it is invoked in the Page_Load() event in the Code Behind:


protected void Page_Load(object sender, EventArgs e)
{
Coordinates coords = new Coordinates();
DataSet dt = coords.GetSavedCoords(1);
using(DataTableReader reader = dt.CreateDataReader())
{
while (reader.Read())
{
HtmlGenericControl ctl = (HtmlGenericControl)this.FindControl(reader["element"].ToString());
if (ctl != null)
{
ctl.Style.Add("left", reader["xPos"].ToString() + "px");
ctl.Style.Add("top", reader["yPos"].ToString() + "px");

}
}
}
}



The Web Service class is instantiated and its GetSavedCoords() method is called. For each row in the returned DataSet, an element on the page is sought with the same id as one saved in the database. If it is found, it has a dash of CSS applied to it through Attributes.Add(). These set the CSS top and left values. When the page is rendered again, the text is exactly where it was left last time.

-

4 comments:

Anonymous said...

not saved error

Anonymous said...

Hi,
Thanks for the code, i have to try your code now.In addition do you have code to retrieve back thise co-ordinates and draw the picture again?

Muhammad Hussain said...

Thanks for the nice article , but I want to apply persistence for more than one page of an user.
Is it possible that there are two parameters in the savecoord() mthod because I want to save the settings against the user and the page.....
Thanks

Anonymous said...

hay even though the last post was 2010 aiming to find the same logic , first info into database then find the way to retirve from database and place the objects on page on their moved state.

kosta59@hotmail.com

kosta

Post a Comment