The prototypes here were used for getting the feedback of other developers, during the first part (design part) of GSOC project. They are all obsolete now, and only kept as a reference example for future students .
See how some component libraries handle drag and drop (not HTML5 though):
PrimeFacesDraggable
PrimeFacesDroppable
RichFacesDnD
ADFDnD
IceFacesDnD
Name |
Required? |
Values |
Description |
---|---|---|---|
action |
required |
Comma separated set or String[] or Collection<String> of copy, copyLink, copyMove, link, linkMove, move, all. |
Allowed DnD drag action from this source |
dropTargetTypes |
optional |
Can be comma separated set or String[] or Collection<String> |
With this property, we can specify which types of drop zones we can make DnD from this source |
param |
optional |
EL and literal |
Parameter to send to server when drop operation is done. |
Name |
Required? |
Values |
Description |
---|---|---|---|
actions |
required |
Comma separated set or String[] or Collection<String> of copy, copyLink, copyMove, link, linkMove, move, all. |
Allowed DnD actions. |
dropListener |
optional |
EL |
Listener method to handle DnD operation on server side. |
rerender |
optional |
EL and literal |
same with <f:ajax> rerender attribute. |
types |
optional |
Can be comma separated set or String[] or Collection<String>. |
Used in conjunction with <fx:dragSource>'s dropTargetTypes attribute. Types of this dropTarget. |
acceptMimeTypes |
optional |
Can be comma separated set or String[] or Collection<String>. |
If this is set, only content dropped into this zone with defined mime type will be accepted and sent to server-side drop listener. |
http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd
http://html5demos.com/drag-anything
http://apirocks.com/html5/html5.html#slide13
https://developer.mozilla.org/En/DragDrop/Drag_and_Drop
https://developer.mozilla.org/En/DragDrop/DataTransfer
https://developer.mozilla.org/En/DragDrop/Recommended_Drag_Types
https://developer.mozilla.org/En/DragDrop/Drag_Operations
ondragstart, ondragend, ondragenter, ondragover, ondrop, other DnD behavioral attributes
dragStartStyle, dragStartStyleClass: CSS stuff to set when this component is being dragged
dragOverStyle, dragOverStyleClass: CSS stuff to set when something is dragged onto this component
other stuff that wrapped components don't support (not clear yet!)
<hx:panel id="draggable1" > <!-- SOME CONTENT --> <fx:dragSource action="copy" dropTargetTypes="#{someBean.optionaldropTargetTypes}" param="#{someBean.dndParamToSendToServer}"/> </hx:panel>
<div id="draggable1" draggable="true" ondragstart="return dragStart(event, 'copy', {'firstdropTargetType','seconddropTargetType'}, 'literalDndParamToSendToServer')" > <!-- RENDERED CONTENT --> </div>
<hx:panel id="draggable2" ondragstart="log('dragging');" ondragend="alert('Drag ended. May not have been dropped succesfully though!')"> <!-- SOME CONTENT --> <fx:dragSource action="move" param="anotherDndParamToSendToServer" /> </hx:panel>
<div id="draggable2" draggable="true" ondragstart="log('dragging'); return dragStart(event, 'move', null, 'secondDndValueToSendServer')" ondragend="alert('Drag ended. May not have been dropped succesfully though!')" > <!-- RENDERED CONTENT --> </div>
<hx:inputText id="draggableInputText"> <fx:dragSource action="move"/> </hx:panel>
<input type="text" id="draggableInputText" draggable="true" ondragstart="return dragStart(event, 'move')" />
<hx:panel id="dropTarget1"> <!-- SOME CONTENT --> <fx:dropTarget actions="move" dropListener="#{someBean.dropListener}" rerender="draggable1" types="firstdropTargetType"/> </hx:panel>
<div id="dropTarget1" ondragenter="dragEnter(event,{'move'},{'firstdropTargetType'}), {'text/x-myfaces-html5-dnd-source'}" ondragover="dragOver(event)" ondrop="drop(event, 'stuff necessary to trigger someBean.dropListener and rerender draggable1 using jsf.ajax.request')"> <!-- RENDERED CONTENT --> </div>
<hx:panel id="dropTarget2" ondragover="makeRedBorder();" ondragleave="clearRedBorder();" ondrop="makeGreenBorder();" > <!-- SOME CONTENT --> <fx:dropTarget actions="copy,move" dropListener="#{someBean.dropListener}" /> </hx:panel>
<div id="dropTarget2" ondragenter="dragEnter(event,{'copy','move'}), null, {'text/x-myfaces-html5-dnd-source'}" ondragover="makeRedBorder(); dragOver(event)" ondragleave="clearRedBorder();" ondrop="makeGreenBorder();drop(event)"> <!-- RENDERED CONTENT --> </div>
<hx:panel id="dropTarget3"> <!-- SOME CONTENT --> <fx:dropTarget actions="copy" dropListener="#{someBean.dropListener}" acceptMimeTypes="text/plain, URL" /> </hx:panel>
<div id="dropTarget3" ondragenter="dragEnter(event,{'copy','move'}, null, {'text/plain', 'URL'})" ondragover="dragOver(event)" ondrop="drop(event)"> <!-- RENDERED CONTENT --> </div>
And here is the script:
var paramMimeType = 'text/x-myfaces-html5-dnd-param'; var myFacesComponentSourceMimeType = 'text/x-myfaces-html5-dnd-source'; var dropTargetMimeType = 'text/x-myfaces-html5-drop-zone-type'; var myFacesComponentSourceConstant = 'org.apache.myfaces'; /* * This function is only used by MyFaces generated draggable elements, the ones that have <fx:dragSource> behavior. */ function dragStart(event, effectAllowed, paramToSendToServer, dropTargetTypes) { //set allowed effect event.dataTransfer.effectAllowed = effectAllowed; //only allow some specific event //with this, drop zone will understand that source of this dnd operation is some MyFaces component event.dataTransfer.setData(myFacesComponentSourceMimeType, myFacesComponentSourceConstant); //this will be set if we want to send an optional parameter to the server-side drop listener if(paramToSendToServer) event.dataTransfer.setData(paramMimeType, valueToSendToServer); //this will be set if we want to make the drop only into specific dropTargets with specific types if(dropTargetType) event.dataTransfer.setData(dropTargetMimeType, dropTargetTypes); //in fact, dropTargetTypes is an array. need to iterate return true; } function dragEnter(event, allowedEffects, dropTargetTypes, acceptedMimeTypes) { //check allowed mime types first var found = false; var foundTypes = acceptedMimeTypes.filter(function (mimeType) event.dataTransfer.types.contains(mimeType)); //if even one of the event mime types are not allowed, stop DnD if(foundTypes.length == 0) return true; //don't cancel the event, thus stop DnD //check allowed effect //changeIt: allowedEffects is an array in fact, so need to iterate if (event.dataTransfer.effectAllowed != allowedEffect) return true; //don't cancel the event, thus stop DnD //check drop zone type //changeIt: in fact these are arrays too. need to iterate or use contains() function if (event.dataTransfer.getData(dropTargetMimeType) != dropTargetTypes) return true; //don't cancel the event, thus stop DnD //cancel the event. this is necessary for DnD execution if (event.preventDefault) event.preventDefault(); return false; } function dragOver(event){ //don't check source, allowedEffect and dropTargetType, since they are checked at dragEnter function //show same user hint effect specified by drag source event.dataTransfer.dropEffect = event.dataTransfer.effectAllowed; //cancel the event, so effect on screen is updated if (event.preventDefault) event.preventDefault(); return false; } function drop(event, jsf_ajax_request_necessary_stuff){ //cancel the event. this is necessary for DnD execution if (event.preventDefault) event.preventDefault(); //CALL jsf.ajax.request with constructing parameters from jsf_ajax_request_necessary_stuff //this call should trigger the dropListener and make the rerender operation //need to send event mime types and values too! return false; }