Adding Communication Capabilities to Components |
You can add drag and drop functionality to your components. Drag and drop is a user interface action that involves dragging components or objects using a pointing device and dropping them over other objects on the frame, which results in some action. For example, a text entry control that contains the name of a SAS table could be dragged onto a data table component and then dropped to display the contents of the SAS table in the data table. Drag and drop also works between objects on different frames.
Components that can be dragged are called drag sites, and components that can receive a dropped object are called drop sites. When an object is dropped, data is passed to the drop site and an action occurs. The action is determined by
The data representation is the form of data that a drag site is capable of transferring or receiving. The data can be as simple as a string of text or as complex as an SCL list. SAS/AF components that are based on the SAS Component Object Model (SCOM) use
characterData |
a generic representation to indicate when a character string is passed as the data |
numericData |
a generic representation to indicate when numeric values are passed as the data |
Legacy objects support three default data representations, all of which provide data in a character string:
Additional data representations enable you to drag items from the SAS Explorer and to drop them onto a frame. These representations includeEXPLORER_DATASET_NAME for SAS tables. The data is provided in a character string that contains the two-level SAS table name, such as sasuser.fitness.
EXPLORER_CATALOG_NAME for SAS catalogs. The data is provided in a character string that contains the two-level SAS catalog name, such as sashelp.classes.
EXPLORER_ENTRY_NAME for a specific catalog entry. When the selection includes a single entry, the data is provided in a character string that contains the four-level entry name, such as work.a.a.scl. When the selection includes two or more entries, the data is provided in a list in which each item is a character string that contains the four-level entry name.
EXPLORER_MEMBER_NAME for multiple selections from a SAS library. When the selection includes a single entry, the data is provided in a character string that contains a two-level member name for catalogs or a three-level member name for SAS tables (including those of type VIEW). When the selection includes two or more members, the data is provided in a list in which each item is a character string. Note that multiple selections of SAS tables or SAS catalogs are sent in an EXPLORER_MEMBER_NAME data representation.
If you create a component based on SCOM architecture, you can define your own data representations if characterData and numericData do not meet your needs.
A data representation is essentially a "verbal contract" between two components. As a component developer, you must name the data representation. For example, the characterData representation states that whatever component uses this as its drag representation, the drag site will send a valid character value as the data. The drop site then expects to receive a character value and can react accordingly.
It is recommended that component developers fully document their data representations so that other developers can know how to use them. See How the Drag and Drop Component Works for more information about the data representation.
Drop operations define actions that are performed on the data representation:
Copy | |
Link | |
Move |
Drag and drop operations in SAS/AF software have the following limitations:
Slider and scroll bar components do not support drag and drop operations.
The behavior of drag and drop operations may vary according to the host environment.
What Happens during a Drag and Drop Action |
SAS/AF software performs several operations to enable drag and drop functionality between two components. When the object is instantiated, SAS/AF checks to see whether the object's dragEnabled or dropEnabled attributes are set to "Yes." If either of these attribute values is "Yes", then
the object is queried for its respective dragInfo or dropInfo attribute values.
For drag sites, SAS/AF reads the value or values of the dragInfo attribute's dataRepresentation and invokes the _addDragRep method to register each drag data representation that is supported by the object.
For drop sites, SAS/AF reads the value or values of the dropInfo attribute's dataRepresentation and invokes the _addDropRep method to register each drop data representation that is supported by the object.
the object is queried for its dragOperations and/or dropOperations settings.
SAS/AF permits a drop action to occur between two objects only when the two objects have a shared data representation and a shared operation. For example, consider an object named listbox1 that is enabled as a drag site using the characterData representation. A second object named listbox2 is enabled as a drop site using the characterData representation. A user can successfully complete a drag and drop action between the two objects if they share a common operation such as "Copy." Objects that do not have a matching data representation and a matching operation will not permit a drop action to occur.
When a valid drag and drop action occurs between two objects, SAS/AF takes the value of an attribute on the drag site and sets it as the value of another attribute on the drop site. Several methods are invoked automatically, passing an instance of sashelp.classes.DragAndDrop.class:
The _startDrag method is invoked on the drag site. An instance of the Drag and Drop component is created.
The _respondToDragOnto method is invoked on a drop site as the cursor passes over a valid drop site.
The _respondToDragOff method is invoked on a drop site as the cursor moves off of a valid drop site.
The _getDragData method is invoked on the drag site after the user has released the drag item on a valid drop site. The implementation of this method prepares the data that is passed between the drag site and the drop site. It also sets the values of the appropriate attributes (including attributeName and attributeValue) on an instance of the Drag and Drop component before passing the object. The default implementation of _getDragData
determines whether an attributeName is defined for the associated dragInfo data representation that was selected for the drop
retrieves the current value of the named attribute and sets its name on the drag and drop object's attributeName attribute
retrieves the current value for that attribute and sets the value of the drag and drop object's attributeValue attribute.
If no attributeName is specified as part of the dragInfo data representation, then you can override the _getDragData method to set the value of the drag and drop object's attributeValue attribute.
The _validateDropData method is invoked on the drop site to perform any validation that may be required.
The _completeDrag method is invoked on the drag site to complete any processing.
The _drop method is invoked on the drop site. The default implementation of the _drop method
retrieves the attributeName from the drop site's dropInfo attribute based on the selected data representation
sets the value of the attribute identified in attributeName using the attributeValue that was passed in the drag and drop object.
If no attributeName exists on the drop site, you can override the _drop method and implement the desired drop behavior.
Adding Drag and Drop Functionality to Your Components |
For most of your applications, you will likely find it sufficient to implement drag and drop functionality simply by setting attribute values.
You can define drag and drop properties for any component that is a subclass of the Widget class or the Frame class. To implement drag and drop, you define the drag properties of the component that you designate as a drag site, as well as the drop properties of another component that you want to behave as a drop site. A component can act as both a drag site and a drop site.
The following attributes must be defined for drag sites. You might want to review these attribute settings if you encounter problems with a drag site, or if you want more information on a drag site's behavior.
The following attributes must be defined for drop sites. You might want to review these attribute settings if you encounter problems with a drop site, or want more information on a drop site's behavior.
SAS/AF software implements the drag and drop process by automatically executing several methods. Although you can override these methods to add functionality, you cannot directly call them from an SCL program.
All drag and drop methods contain signatures that accept an object as their only argument. This object is an instance of the Drag and Drop Component (that is, sashelp.classes.DragAndDrop.class). It provides a container for the standard drag and drop information that is passed between a drag site and a drop site. The information is stored in the following attributes of the Drag and Drop component:
is the name of the attribute that is passed from the drag site to the drop site.
is the value of the attribute that is passed from the drag site. This attribute is a complex attribute whose type is sashelp.classes.type.class, which contains the following attributes:
drop: public method dndObj:input:object; if dndObj.attributeValue.type = 'Character' then do; /* Retrieve dndObj.attributeValue.characterValue, */ /* then add any other code. */ end; else if dndObj.attributeValue.type = 'Numeric' then do; /* Retrieve dndObj.attributeValue.numericValue, */ /* then add any other code. */ end; /* and so forth... */ endmethod;
is a character attribute that you can optionally set to indicate whether a drop can successfully occur. For example, you can perform validation in an override of the _validateDropData method, and you can cancel the drop action by setting this attribute to "No". You can also query this value in an override of the _completeDrag method to verify whether the drop will actually occur before performing some action on the drag site.
is the selected drag operation; corresponds to one of the operations specified in the dragOperations attribute that is set on the drag site.
is the form of the data that is passed between sites; corresponds to the particular list item in the dragInfo attribute that is set on the drag site.
indicates whether the drag started inside or outside of the current frame.
For components that are based on the SCOM architecture, the data specified in the data representation (such as characterData or EXPLORER_MEMBER_NAME) is stored in the attributeValue complex attribute of the Drag and Drop component. If one item is dragged, then the data is stored in the characterValue attribute of the attributeValue object. If two or more items are dragged, then the data is stored in the listValue attribute as separate character items.
For complete details on the Drag and Drop component, see "SAS/AF Component Reference" in the SAS/AF online Help. For information about using drag and drop functionality with legacy objects, see Using Drag and Drop Operations with Legacy Classes.
Drag and Drop Example |
To demonstrate how drag and drop functionality works, consider an example that defines two subclasses of the list box control. The first subclass defines an object that is a drag site. The second defines an object that is a drop site. (Of course, it is entirely possible to have a single object that is both a drag site and a drop site.)
To create the first list box subclass:
Using the Class Editor, create a new class whose parent is sashelp.classes.ListBox_c.class and whose description is Source List Box.
Select the Attributes node, then set the following values for attributes:
Select the dragEnabled attribute, then right-click and select Override from the pop-up menu. Set the Initial Value to Yes.
Select the dragOperations attribute, then right-click and select Override from the pop-up menu. Click the ellipsis (...) button in the Initial Value field. In the dragOperations dialog box, deselect the Enabled check box for Default Copy Operation and then select the Enabled check box for Default Move Operation. Click to return to the Class Editor.
Select the Methods node, then select the second _completeDrag method in the list (with the O:SASHELP.CLASSES.DRAGANDDROP.CLASS signature). Right-click and select Override from the pop-up menu, then select Source from the pop-up menu. Add the following SCL code to sasuser.test.SourceListBox.scl:
USECLASS sasuser.test.SourceListBox.class; /* Override of the _completeDrag method */ completeDrag: method dndobj:sashelp.classes.draganddrop.class; dcl num rc; /* If the rep is one that is not understood, call super. */ if ( upcase(dndobj.dataRepresentation) = 'CHARACTERDATA' ) then do; /* Check the status of the completeDrag attribute. */ if ( ( upcase(dndobj.completeDrag) = 'YES' ) AND ( upcase(dndobj.dataOperation) = 'MOVE' ) ) then do; /* Remove the selected item from the items list. */ if (selectedIndex ^= 0 ) then do; /* Delete the item from the items attribute. */ rc = delitem(items, selectedIndex ); /* Set the items attribute equal to itself to */ /* update this list box. */ items = items; end; end; end; else _super( dndobj ); endmethod; enduseclass;
To create the second list box subclass:
Using the Class Editor, create a new class whose parent is sashelp.classes.ListBox_c.class and whose description is Target List Box.
Select the Attributes node, then set the following values for attributes:
Select the dropEnabled attribute, then right click and select Override from the pop-up menu. Set the Initial Value to Yes.
Select the dropInfo attribute, then right click and select Override from the pop-up menu. Click the ellipsis (...) button in the Value field. In the Drop Info dialog box, click , then set the Drop Attribute to a blank value and the Drop Representation to CHARACTERDATA.
Select the dropOperations attribute, then right click and select Override from the pop-up menu. Click the ellipsis (...) button in the Value field. In the dropOperations dialog box, deselect the Enabled check box for Default Copy Operation and then select the Enabled check box for Default Move Operation.
Select the Methods node, then select the second _drop method in the list (with the O:SASHELP.CLASSES.DRAGANDDROP.CLASS signature). Right-click and select Override from the pop-up menu. Select the second _validateDropData method in the list (with the O:SASHELP.CLASSES.DRAGANDDROP.CLASS signature). Right-click and select Override from the pop-up menu, then select Source from the pop-up menu. Add the following SCL code to implement both methods in sasuser.test.TargetListBox.scl:
USECLASS sasuser.test.TargetListBox.class; /* Override of the _validateDropData method */ validateDropData: method dndobj:sashelp.classes.draganddrop.class; /* If the rep is one that is not understood, call super. */ if ( upcase(dndobj.dataRepresentation) = 'CHARACTERDATA' ) then do; /* Ensure that the type is 'Character' and that the */ /* value is not blank. If either of these checks */ /* fail, then do not let the drop happen. */ if ( ( upcase(dndobj.attributeValue.type) ^= 'CHARACTER' ) OR ^length( dndobj.attributeValue.characterValue ) ) then dndobj.completeDrag = 'No'; end; else _super( dndobj ); endmethod; /* Override of the _drop method */ drop: method dndobj:sashelp.classes.draganddrop.class; dcl num rc; /* If the rep is one that is not understood, call super. */ if ( upcase(dndobj.dataRepresentation) = 'CHARACTERDATA' ) then do; /* Ensure that the attributeValue is the correct type. */ /* If so, then insert it at the end of the items list. */ if ( upcase(dndobj.attributeValue.type) = 'CHARACTER' ) then do; dcl num rc; rc = insertc( items,dndobj.attributeValue.characterValue, -1 ); /* Set the items attribute equal to itself in order to */ /* update this list box. */ items = items; end; end; else _super( dndobj ); endmethod; enduseclass;
You could then use two classes in a frame:
In the SAS Explorer, select File New then select a FRAME entry.
In the Components window, right-click and select Add Classes to add sasuser.test.SourceListBox.class and sasuser.test.TargetListBox.class. If the Components window is not displayed when the new frame appears in the Build window, then select View Components Window to display it.
Drag an instance of the Source List Box object and drop it onto the frame, then drag an instance of the Target List Box object and drop it onto the frame.
Select Build Test to test the frame. Drag an item from the source list box and drop it onto the target list box.
Copyright © 2007 by SAS Institute Inc., Cary, NC, USA. All rights reserved.