Eden Ridgway's Blog

.Net and Web Development Information

  Home :: Contact :: Syndication  :: Login
  105 Posts :: 1 Stories :: 78 Comments :: 3 Trackbacks

Search

Article Categories

Archives

Post Categories

Development

General

It's incredible at how easy it is to create an IE specific drag and drop treeview. While playing aroudn with this I created a survey editor where questions may be reordered or dragged on to answers to create drill down survey question dependencies.

To start off I setup a set of nested survey questions and answers using ordered lists, like this:

<!-- Level 1 questions -->
<OL class="Questions">
<LI> Where do you like to eat?
<OL class="Answers">
<LI>At home</LI>
<LI> At the pub <!-- Level 2 sub questions -->
<OL class="Questions">
<LI> How often do you eat at the pub?
<OL class="Answers">
<LI>Once a week</LI>
<LI>Twice a week</LI>
</OL>
</LI>
<LI> How much money do you spend at the pub? </LI>
</OL>
</LI>
<LI>At a restuarant</LI>
<LI>Take away</LI>
</OL>
</LI>
</OL>

As you can see from the HTML above, the idea is that if you answered that you like to eat at the pub, you would then be presented with a question as to how often you eat there. I used the class names to identify whether the lists were questions or answers. While I'm not entirely happy with this solution, it makes a fair amount of practical sense since you would most likely style the two differently in any case.

Then comes the fun part hooking up the drag and drop code. I decided that instead of adding all the event handlers inline I would add them using a script that ran once the survey elements had been rendered. This was because the markup was becoming messy and confused with all the handlers. It would also easily facilitate the turning on and off of the drag and drop functionality. I did this using the following script block to loop through all the ordered lists on the page and attach the relevant event handlers to questions and answers:

var listItems = document.getElementsByTagName("LI");

for
(i=0; i < listItems.length; i++)
{
if (listItems[i].parentElement.className == "Questions")
{
listItems[i].onmousedown
= function() { StartDrag(this) };
listItems[i].ondrag = DragQuestion;
listItems[i].ondragend = function() { RepositionQuestion(this) };
listItems[i].ondragenter = function() { DisplayDropOption(this) };
listItems[i].ondragleave = function() { RemoveDropOption(this) };
listItems[i].ondragover = AllowDrop;
}
//Allow users
to drop questions under answers and thereby create a recursive question
//based
on an answer
else if (listItems[i].parentElement.className == "Answers")
{
listItems[i].ondragenter
= function() { DisplayDropOption(this) };
listItems[i].ondragleave = function() { RemoveDropOption(this) };
listItems[i].ondragover = AllowDrop;
}
}

As you can see questions are both drop targets and draggable while answers can only act as drag targets. The event sequence when performing a drag and drop operation is therefore as follows:

  1. OnMouseDown - start the drag and drop operation on the element using element.dragDrop() (note that this is IE specific code). In this handler I created two clones of the question being dragged, one to drag around under the cursor as the user selects a target and another to act as a preview of the drag & drop.
  2. OnDrag - draws the question as it is being dragged around
  3. OnDragEnter - adds a preview of the dragged question to the relevant list or if the drag target is an answer it will dynamically create an ordered list container for the element and display it within that.
  4. OnDragOver - simply cancels the default event handler and thereby makes the question or element a valid drag target
  5. OnDragLeave - removes the previewed element from the target element
  6. OnDragEnd - repositions the question at the target position by swapping out the preview question with the question originally clicked on

Since there is a fair amount of code involved in this, you will want to take a look at this demo page to see it all in action: DragAndDropDemo.htm

posted on Monday, October 24, 2005 4:34 AM
Comments have been closed on this topic.