Class: cWebDragDropHelper
Properties | Events | Methods | Index of Classes
Adds drag and drop fuctionality to web controls
Hierarchy
cObject > cWebBaseObject > cWebObject > cWebDragDropHelper
Show full hierarchy and direct subclasses
- cObject
- cWebBaseObject
- cWebObject
- cWebDragDropHelper
Library: Web Application Class Library
Package: cWebDragDropHelper.pkg
Description
Adds drag and drop fuctionality to web controls.
Drag Actions
The following classes support elements being dragged for specific actions using the following constants:
cWebList: C_WebDragListRow cWebTreeView: C_WebDragTreeviewFolder, C_WebDragTreeviewItem cWebTagsForm: C_WebDragTagsFormTag
Attempting to add an unsupported drag action to a control will result in an Error.
Drop Actions
Every visual web control, including containers like cWebPanel or cWebGroup, supports the C_WebDropOnControl action. This allows the entire control to function as a drop zone.
The following classes support elements being dropped onto for specific actions using the following constants:
All web controls: C_WebDropOnControl cWebList: C_WebDropListRow cWebTreeView: C_WebDropTreeviewRoot, C_WebDropTreeviewFolder, C_WebDropTreeviewItem cWebTagsForm: C_WebDropTagsFormInput
General Use Outline
- Add a cWebDragDropHelper object to your view.
Adding a cWebDragDropHelper object to your view unlocks the drag and drop functionality. After creating the cWebDragDropHelper object, configure the allowed actions.
- Design your drag and drop paths by adding Drag Sources and Drop Targets
Next set up your drag and drop paths, as well as, configure what actions you would like to support.
Adding Drag Sources is done using RegisterDragSource. Adding Drop Targets is done using RegisterDropTarget.
To support multiple drag actions on the same control, such as being able to drag both folders and items in a treeview, you would call RegisterDragSource again on the same control passing different actions. The same applies to supporting multiple drop actions.
Note that each Drag Source in a specific helper can drop on each Drop Target added inside. Controls can also function as both a Drag Source and a Drop Target at the same time, allowing for omnidirectional drag and drop interaction.
Sample
In the example below, we allow drag actions from 5 different controls. Items dragged from these controls can be dropped onto 6 controls. Some of these controls are registered as both a Drag Source and a Drop Target.
Object oDragDropHelper is a cWebDragDropHelper
Send RegisterDragSource oAllCustomers C_WebDragListRow
Send RegisterDragSource oNiceCustomers C_WebDragListRow
Send RegisterDragSource oBadCustomers C_WebDragListRow
Send RegisterDragSource oImportantCustomers C_WebDragTagsFormTag
Send RegisterDragSource oSortedCustomers C_WebDragTreeviewItem
Send RegisterDropTarget oNiceCustomers C_WebDropListRow
Send RegisterDropTarget oBadCustomers C_WebDropListRow
Send RegisterDropTarget oImportantCustomers C_WebDropTagsFormInput
Send RegisterDropTarget oSortedCustomers C_WebDropTreeviewFolder
Send RegisterDropTarget oWebFormDrop C_WebDropOnControl
Send RegisterDropTarget oWebGroupDrop C_WebDropOnControl
- Add your business logic to be executed when a drop happens by implementing the OnDrop event
When dropping a draggable element on a valid Drop Target, a call is sent to the server with info of the dragged data and the drop position. This is passed to the OnDrop event, where business logic can be executed to interact with this data.
Sample
The sample code below moves a customer from the source control to the target control.
Procedure OnDrop Handle hoDragSource Handle hoDropTarget WebDropPosition eDropPosition
RowID riCustomer
// Determine which customer is being dragged
Get CustomerFromSource hoDragSource to riCustomer
If (not(IsNullRowID(riCustomer))) Begin
// Remove from the source (except for the oAllCustomers list)
If (hoDragSource <> oAllCustomers) Begin
Send RemoveCustomerFromSource hoDragSource riCustomer
End
// Add to the target
Send AddCustomerToTarget riCustomer hoDropTarget eDropPosition
End
End_Procedure
3a. Getting drag and drop data
Both drag and drop data are not passed directly into the OnDrop event. They are set on both the hoDragSource and hoDropTarget at an earlier stage and can be retrieved by using either DragData or DropData. The return value is inherently a Variant, but will return a specific struct based on the control it's being requested from.
Sample
The example code below illustrates how to deal with getting the Drag and Drop data from the respective controls, as well as various ways of interacting with the data per individual control.
Function CustomerFromSource Handle hoDropSource Returns RowID
If (IsObjectOfClass(hoDropSource, RefClass(cWebTagsForm))) Begin
tWebTagsFormDragData tagsDragData
Get DragData of hoDropSource to tagsDragData
Clear Customer
Move tagsDragData.data to Customer.Name
Find GE Customer.Name
If (Found and Trim(Customer.Name) = Trim(tagsDragData.data)) Begin
Function_Return (GetRowID(Customer.File_Number))
End
End
If (IsObjectOfClass(hoDropSource, RefClass(cWebList))) Begin
tWebListDragData listDragData
Get DragData of hoDropSource to listDragData
Function_Return (DeserializeRowID(listDragData.data.sRowId))
End
If (IsObjectOfClass(hoDropSource, RefClass(cWebTreeView))) Begin
tWebTreeViewDragData treeDragData
Get DragData of hoDropSource to treeDragData
Function_Return (DeserializeRowID(treeDragData.data.sId))
End
Function_Return (NullRowID())
End_Function
//
// Adds an item onto the Drop Target based on the provided RowId. Switches between the different target types.
//
Procedure AddCustomerToTarget RowID riCustomer Handle hoDropTarget WebDropPosition eDropPosition
Boolean bFound
Move (FindByRowID(RefTable(Customer), riCustomer)) to bFound
If (IsObjectOfClass(hoDropTarget, RefClass(cWebTagsForm))) Begin
// We don't use the drop data, but just for fun we load it
tWebTagsFormDropData tagsDropData
Get DropData of hoDropTarget to tagsDropData
Send AddTag of hoDropTarget (Customer.Name)
End
If (IsObjectOfClass(hoDropTarget, RefClass(cWebForm))) Begin
WebSet psValue of hoDropTarget to (Trim(Customer.Name))
End
If (IsObjectOfClass(hoDropTarget, RefClass(cWebGroup))) Begin
String sMsg
Move ('Dropped customer: "' + Trim(Customer.Name) + '" on WebGroup') to sMsg
Send ShowInfoBox sMsg
End
If (IsObjectOfClass(hoDropTarget, RefClass(cWebList))) Begin
tWebListDropData listDropData
Get DropData of hoDropTarget to listDropData
// Check if customer isn't already in the list
RowID[] riRecordsShown
WebGet prRecordsShown of hoDropTarget to riRecordsShown
If (SearchArray(riCustomer, riRecordsShown) = -1) Begin
Move riCustomer to riRecordsShown[SizeOfArray(riRecordsShown)]
WebSet prRecordsShown of hoDropTarget to riRecordsShown
// Now add it to the list
tWebRow tListRow
Get LoadGridRow of hoDropTarget to tListRow
If (eDropPosition = C_WebDropPosBefore or eDropPosition = C_WebDropPosOn) Begin
Send DataSetInsertRowBefore of hoDropTarget listDropData.data.sRowId tListRow
End
Else If (eDropPosition = C_WebDropPosAfter) Begin
Send DataSetInsertRowAfter of hoDropTarget listDropData.data.sRowId tListRow
End
Else Begin
Send DataSetAppendRow of hoDropTarget tListRow
End
End
End
If (IsObjectOfClass(hoDropTarget, RefClass(cWebTreeView))) Begin
// Figure out drop data
tWebTreeViewDropData treeDropData
Get DropData of hoDropTarget to treeDropData
// Remove to be sure we don't get duplicates
Send RemoveNode of hoDropTarget (SerializeRowID(riCustomer))
// Create new node
tWebTreeItem newItem
Move (SerializeRowID(riCustomer)) to newItem.sId
Move Customer.Name to newItem.sName
Move Customer.City to newItem.sAltText
Move False to newItem.bFolder
Move treeDropData.data.sId to newItem.sParentId // Make it a child of what we dropped it on
Send InsertNode of hoDropTarget newItem
End
End_Procedure
//
// Removes an item from the Drag Source. Switches between the different source types.
//
Procedure RemoveCustomerFromSource Handle hoDragSource RowID riCustomer
If (IsObjectOfClass(hoDragSource, RefClass(cWebTagsForm))) Begin
Boolean bFound
Move (FindByRowID(RefTable(Customer), riCustomer)) to bFound
If (bFound) Begin
Send RemoveTag of hoDragSource (Customer.Name)
End
End
If (IsObjectOfClass(hoDragSource, RefClass(cWebList))) Begin
RowID[] riRecordsShown
Integer iIndex
// Update the extra list of shown customers we keep for both weblists.
WebGet prRecordsShown of hoDragSource to riRecordsShown
Move (SearchArray(riCustomer, riRecordsShown)) to iIndex
If (iIndex <> -1) Begin
Move (RemoveFromArray(riRecordsShown, iIndex)) to riRecordsShown
WebSet prRecordsShown of hoDragSource to riRecordsShown
Send DataSetRemoveRow of hoDragSource (SerializeRowID(riCustomer))
End
End
If (IsObjectOfClass(hoDragSource, RefClass(cWebTreeView))) Begin
Send RemoveNode of hoDragSource (SerializeRowID(riCustomer))
End
End_Procedure