Tuesday, December 30, 2008

Asp.net Drag and Drop

Introduction:

Sometime back I visited a website that had the drag and drop shopping cart feature. Users can simply drag and drop the items they wish to buy in the basket and the basket is updated with the new results. I was extremely impressed with this feature and decided to create a small application that does the same.

In this article I will implement a page which enables the users to drag and drop the items they wish to buy into the shopping basket. The shopping basket items and the price will be updated. The code presented in this article is browser compatible.

The Database Design:

I used SQL SERVER 2005 Express to create a simple database called "ToyShopDatabase". The database contains a single table "tblToys" which contains four columns.

  • ToyID: The identity column is used as a primary key.
  • Title: The title of the toy.
  • ImageUrl: The image url of the toy.
  • Price: The price of the toy.

I have populated the database with some dummy data. Let's see how we can display the data on the page.

Displaying Data on the Page:

I have used DataList control to display the data on the page. Check out the BindData method below which is used to retrieve the data from the database.

private void BindData()

{
string connectionString = ConfigurationManager.ConnectionStrings _
["ConnectionString"].ConnectionString;
SqlConnection myConnection = new SqlConnection(connectionString);

SqlDataAdapter ad = new SqlDataAdapter("
SELECT * FROM tblToys",_

myConnection);
   DataSet ds = new DataSet();

ad.Fill(ds);

dlToys.DataSource = ds;
dlToys.DataBind();
}
You can see the items displayed on the page in the screen shot below:

You can also see the shopping cart displayed on the left side of the screen. The shopping cart displays $0.00 since there are no products added to the cart.

The interesting thing is the HTML code for the DataList. Let's check it out.

<asp:DataList Height="100%" Width="100%" ID="dlToys" runat="server"

RepeatColumns="3" CellPadding="20" CellSpacing="20">
<ItemTemplate>
<div ID="a" runat = "server" class="dragElement">
<asp:Label ID="lblTitle" runat=
"
server" Text='<%# Eval("Title") %>' />
<asp:Label ID="lblPrice" runat="server" Text =
'
<%# Eval("Price") %>' />
<asp:Image ID="imgPicture" runat="server" ImageUrl=
'
<%# Eval("ImageUrl") %>' />
</div>
</ItemTemplate>
</asp:DataList>
As you can see in the code above I have added a
element inside the
ItemTemplate of the DataList control. This means that each product is contained
inside the
element which will serve as a draggable object. The

control will have a unique ID since I have added the runat="server" attribute.


The unique ID will be assign by ASP.NET at runtime as shown below:


Making Elements Dragable:



At this point we know that our DIV elements will serve as the dragable
objects. But there can be several DIV controls on the page which will not be a
part of this drag and drop feature. We will use regular expression to filter the
correct DIV elements.


Here is the code that initiates the drag and creates the clone.

function InitiateDrag(e)

{
mouseState = 'down';

var evt = e || window.event;

startX = parseInt(evt.clientX);
startY = parseInt(evt.clientY);

clone = obj.cloneNode(true);

clone.style.position = 'absolute';
clone.style.top = parseInt(startY) + 'px';
clone.style.left = parseInt(startX) + 'px';

document.body.appendChild(clone);

document.onmousemove = Drag;
document.onmouseup = Drop;

return false;


}

Dropping the Element in the Drop Zone:



I had some hard time creating a browser-compatible drop zone event. The Drop
is only successful when the product is dropped inside the drop zone. In my
article, "Drag and Drop Using JavaScript", I used the parent approach where I found
the element based on the mouse position. But unfortunately, that approach was
not browser compatible. The approach that is discussed here is browser
compatible and it based on the mouse position and the drop zone position on the

page.
And here is the code for dropping the product in the drop zone:



function Drop(e)
{
var evt = e || window.event;
var evtTarget = evt.target || evt.srcElement;

var dZone = document.getElementById("dZone");

if( evt.clientX > dZone.offsetLeft &&
evt.clientX < (dZone.offsetLeft + dZone.offsetWidth) && evt.clientY > dZone.offsetTop &&
evt.clientY < (dZone.offsetTop + dZone.offsetHeight)) { AddPrice(); } document.onmouseup = null;
document.onmousemove = null;

document.body.removeChild(clone);
mouseState = 'up';
ResetColor();


}

f the product is not inside the drop zone then the product just disappears.
However, if the product is inside then it is added to the shopping cart.

Adding the Product to the Shopping Cart:



The AddPrice function is responsible for updating the total price and the
display of the shopping cart. Each product is embedded inside the DIV element
which is later added to the DropZone DIV container.

function AddPrice()

{

var title = GetProductTitle();
var price = GetProductPrice();


var dZone = document.getElementById("dZone");
var textNode = document.createTextNode(title);
var priceNode = document.createTextNode(price);

var spaceNode = document.createTextNode(': $');
var paragraphElement = document.createElement('p');

// create the delete button


var deleteButton = document.createElement('button');
deleteButton.value = 'Delete';
deleteButton.innerHTML = 'Delete';
deleteButton.onclick = DeleteItem;

var item = document.createElement('div');
item.id = 'itemDiv' + uniqueNumber;

item.appendChild(paragraphElement);
item.appendChild(textNode);
item.appendChild(spaceNode);
item.appendChild(priceNode);
item.appendChild(spaceNode);
item.appendChild(deleteButton);

dZone.appendChild(item);

// increment the price

IncrementTotal(price);
uniqueNumber++;

}
GetProductTitle and GetProductPrice are used to retrieve the title and
the price from the dragable product. uniqueNumber is a global variable
which is used to create a unique ID for the newly created DIV element. uniqueNumber is incremented each time a new product is added to the drop zone.
The IncrementTotal function is used to add the product's price to the total
price.

Deleting the Item from the Shopping Cart:



Once the product is added to the shopping cart it is displayed with the
delete button. The delete button is used to remove the product from the shopping

cart and adjust the total balance.


function DeleteItem(e)

{
var evt = e || window.event;
var evtTarget = evt.target || evt.srcElement;

if(IsFireFox())
{
price = evtTarget.parentNode.childNodes[2].nodeValue;
evtTarget.parentNode.parentNode.removeChild(evtTarget.parentNode);
}
else
{
price = evtTarget.parentElement.childNodes[2].nodeValue;
evtTarget.parentElement.parentElement.removeChild(
evtTarget.parentElement);
}

DecrementTotal(price);
}


5 comments:

  1. This comment has been removed by the author.

    ReplyDelete
  2. Could you post all of the code? It seems as though only some of the code is shown here. Thanks a lot!

    ReplyDelete
  3. Please provide the whole project. So, everything will be more clear for us. Will Appreciate.

    ReplyDelete
  4. provide the source code please.

    ReplyDelete
  5. Hi Dear h r u?I m very happy to know about u.I m Ashfaq Ahmad jadoon from Mangal chai Gadoon swabi.i have done msc Chemistry now to M.phil in Inoganic chemistry.
    pay my salam to of ur family mambers.thanks
    Ashfaq jadoon
    jadoon586@yahoo.com
    contact no;
    +923459700829
    +92938308029

    ReplyDelete