Here's the source code for the example

Note that the code sample below contains formatting and images - if you want to cut and paste the actual source code for the example, open the working example and use your browser to view the source.

<HTML>
<HEAD>
<SCRIPT LANGUAGE="JavaScript">
var startPositionX, startPositionY
dragInProgress=false;
returnLayerIfIncorrect=true;

function initialise() {
        if (navigator.appName=="Netscape") {
              startPositionX=document.layers['dragLayerName'].left;
              startPositionY=document.layers['dragLayerName'].top
       } else {
              startPositionX=dragLayerName.style.pixelLeft;
              startPositionY=dragLayerName.style.pixelTop
    }
}

function startDrag() {
       dragInProgress=true
       if (navigator.appName!="Netscape") {
              event.returnValue = false;
       }
       return false;
}

function enactDrag(netscapeEvent) {
       if (dragInProgress) {
              if (navigator.appName=="Netscape") {
                     document.layers['dragLayerName'].left=netscapeEvent.pageX
                     document.layers['dragLayerName'].top=netscapeEvent.pageY
              } else {
                     dragLayerName.style.pixelLeft=event.clientX
                     dragLayerName.style.pixelTop=event.clientY
                     event.returnValue = false;
              }
       }
       return false;
}

function endDrag() {
       dragInProgress=false;
       if (navigator.appName=="Netscape") {
              correctAnswer=((document.layers['dragLayerName'].left==document.layers['dropLayerName'].left) &&
                                      (document.layers['dragLayerName'].top==document.layers['dropLayerName'].top))
       } else {
              correctAnswer=((dragLayerName.style.pixelLeft==dropLayerName.style.pixelLeft) &&
                                     (dragLayerName.style.pixelTop==dropLayerName.style.pixelTop))
              event.returnValue = false;
       }
       if (correctAnswer) {
              alert('You got it!')
       } else {
              alert('You missed - try again')
              if (returnLayerIfIncorrect) {
                     if (navigator.appName=="Netscape") {
                            document.layers['dragLayerName'].left=startPositionX
                            document.layers['dragLayerName'].top=startPositionY
                     } else {
                            dragLayerName.style.pixelLeft=startPositionX
                            dragLayerName.style.pixelTop=startPositionY
                     }
              }
       }
       return false
}

document.onmousedown=startDrag
document.onmousemove=enactDrag
document.onmouseup=endDrag

if (navigator.appName=="Netscape") {
       document.captureEvents(Event.MOUSEDOWN | Event.MOUSEMOVE | Event.MOUSEUP)
}
</SCRIPT>
</HEAD>
<BODY onLoad="initialise()" bgcolor="#003366">
<div id="dragLayerName" style="position:absolute; width:132px; height:132px; z-index:3; left: 96px; top: 103px"><img src="drag.gif" width="132" height="132"></div>
<div id="dropLayerName" style="position:absolute; width:132px; height:132px; z-index:2; left: 450px; top: 107px"><img src="drop.gif" width="132" height="132"></div>
</BODY>
</HTML>


Points to note:

For clarity, the above is only an indication of the type of structure required, and has the following limitations:

  1. There is no actual method for passing the layer name - dragLayerName and dropLayerName are fixed constants
  2. The top-left of the layer being dragged is positioned where the mouse cursor is - the offset of the mouse cursor within the layer when the button is pressed is not taken into account
  3. Likewise, there is no margin for error in the drop area - the drag layer must be positioned exactly over the drop area for the above to work

CourseBuilder has the inbuilt logic to cater for the above, automatically allowing for multiple drag objects and catering for the offsets. In addition, the amount of margin for error is set via the dialog box, and whether or not to "snap" to the target if the error is within the allowable margin.

Other attributes that can be set via the dialog box include whether or not to return the layer to the original position if the user does not get the interaction correct (i.e. the returnLayerIfIncorrect variable is not hard-coded, but is changeable by the developer by simply clicking on a checkbox within the wizard).