Hi Ali, +1 on putting this on a cwiki space - it will be more readable!
Regards, Jakob 2010/5/28 Matthias Wessendorf <[email protected]> > Hi Ali, > > a very few comments, after a first quick look: > => I think I prefer dropTarger over 'dropZone' > > -Another example may be dropping files from your desktop, but what to > do with them? We'll have <hx:inputFileUpload> for DnD file uploading. > => that's an interesting idea, IMO worth to investigate here > => exactly sure yet about the mimetype things... > > * <hx:panel> > => please no dependency to Tomahawk ;-) > > For the JS, I think we should do some namespacing ;-) > (yeah I saw your comment) > > Question: Do you mind to publish all the documentation to the new cwiki > space? > I think that will be easier for "future" overhauls of these > pages/prototypes. > > -Matthias > > > On Fri, May 28, 2010 at 3:16 PM, Ali Ok <[email protected]> wrote: > > Hi all, > > > > I've prepared DnD related protoypes. We'll have <fx:dragSource> > > <fx:dropZone> behaviors and <hx:Panel> for wrapping non-draggable > components > > (like h:panelGrid). > > > > Since these are complex enough for prototyping, I passed drag image > > concept. We can think about it later. > > > > Don't care about namespace and syntax of Javascript please. Those will be > > extracted into some .js file. > > > > Here is what other component libraries handle this: > > > > http://www.primefaces.org:8080/prime-showcase/ui/draggableBasic.jsf > > > > http://www.primefaces.org:8080/prime-showcase/ui/droppableBarca.jsf > > > > http://component-showcase.icefaces.org/component-showcase/showcase.iface > > > > > http://download.oracle.com/docs/cd/E15523_01/apirefs.1111/e12419/toc.htm#DragDrop > > > > http://livedemo.exadel.com/richfaces-demo/richfaces/dragSupport.jsf > > > > > > > > =============================== > > > > ==========<fx:dragSource>====== > > > > =============================== > > > > REFS: > > > > [0] > > http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd > > > > [1] > > > http://www.whatwg.org/specs/web-apps/current-work/multipage/elements.html#embedding-custom-non-visible-data > > > > [2] https://developer.mozilla.org/En/DragDrop/Drag_and_Drop > > > > [3] https://developer.mozilla.org/En/DragDrop/DataTransfer > > > > [4] > > https://developer.mozilla.org/En/DragDrop/Recommended_Drag_Types > > > > [5] > https://developer.mozilla.org/En/DragDrop/Drag_Operations > > > > > > > > EXTENDS: > > > > ClientBehavior > > > > ATTRIBUTES: > > > > action (required): Allowed DnD drag action from this source. > Can > > be comma separated set or String[] or Collection<String> of copy, > copyLink, > > copyMove, link, linkMove, move, all. > > > > dropZoneTypes (optional): With this property, we can specify > > which types of drop zones we can make DnD from this source. Can be comma > > separated set or String[] or Collection<String> > > > > param(optional): Parameter to be sent to server when drop > > operation is done. > > > > NOTES: > > > > May use "custom non-visible data" [1], "data-*" when at least > > one browser starts supporting it > > > > > > > > =============================== > > > > ==========<fx:dropZone>======== > > > > =============================== > > > > REFS: > > > > [0] > > http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#dnd > > > > [1] > > > http://www.whatwg.org/specs/web-apps/current-work/multipage/elements.html#embedding-custom-non-visible-data > > > > [2] http://html5demos.com/drag-anything > > > > [3] http://apirocks.com/html5/html5.html#slide13 > > > > [4] https://developer.mozilla.org/En/DragDrop/Drag_and_Drop > > > > [5] https://developer.mozilla.org/En/DragDrop/DataTransfer > > > > [6] > > https://developer.mozilla.org/En/DragDrop/Recommended_Drag_Types > > > > [7] > https://developer.mozilla.org/En/DragDrop/Drag_Operations > > > > > > > > EXTENDS: > > > > AjaxBehavior > > > > > > > > ATTRIBUTES: > > > > actions (required): Allowed DnD actions. Can be comma > separated > > set or String[] or Collection<String> of copy, copyLink, copyMove, link, > > linkMove, move, all. > > > > If action of dragEvent are not one of these, DnD will > > stop. > > > > dropListener (required): Listener method to handle DnD > operation > > on server side. > > > > rerender (optional): same with <f:ajax> rerender attribute. > > > > types (optional): Used in conjunction with <fx:dragSource>'s > > dropZoneTypes attribute. Types of this dropZone. > > > > Can be comma separated set or String[] or > > Collection<String>. > > > > acceptMimeTypes: If this is set, only content dropped into > this > > zone with defined mime type will be accepted and sent to server-side drop > > listener. > > > > HTML5 DnD allows us to drop anything into drop zone[2]: > > files from desktop, images on some other document[3], etc. So this > property > > is a filter. > > > > If value is "*" any content dropped into this zone will > be > > accepted. All type info and data of dropped stuff will be sent to > > dropListener. > > > > For example, if this is true and we drag&drop some > image > > on any Html page(even not generated by JSF), dropListener will be > triggered > > with the following data: > > > > content-type / value > > > > ------------ > > -------------------------------- > > > > text/uri-list / > > http://example.org/someImage.png > > > > Text / > > http://example.org/someImage.png > > > > text/plain / > > http://example.org/someImage.png > > > > URL / > > http://example.org/someImage.png > > > > > > > > Another example may be dropping files from your > desktop, > > but what to do with them? We'll have <hx:inputFileUpload> for DnD file > > uploading. > > > > So better not to accept files, or even they're > accepted, > > we'd better not to send their information to server. > > > > Mime type can be something like > > "text/x-myfaces-html5-dnd-source" for MyFaces generated components. > > > > Default to "text/x-myfaces-html5-dnd-source", thus only > > MyFaces generated components can be dropped into this zone. > > > > NOTES: > > > > > > > > =============================== > > > > ==========<hx:panel>======== > > > > =============================== > > > > REFS: > > > > > > > > EXTENDS: > > > > <t:div> or something (I don't think a dependency to Tomahawk > is > > good. So, need to rewrite that stuff or copy them, preferably with > > maven-dependency-plugin) > > > > > > > > ATTRIBUTES: > > > > 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!) > > > > > > > > NOTES: > > > > This is just like <t:div> or <rich:panel>. For example DnD > does > > not work with components that dont support "dragstart" clientbehavior > event. > > > > That is why <hx:panel> is necessary. We can wrap those > > components (ie. h:inputText, h:panelGrid) with <hx:panel>. > > > > > > > > <!-- - - - - - - - - -usage: <fx:dragSource> with dropZoneType - - > - - > > - - - - - - - - - - - - - - - - - - --> > > > > <hx:panel id="draggable1" > > > > > <!-- SOME CONTENT --> > > > > <fx:dragSource action="copy" > > dropZoneTypes="#{someBean.optionalDropZoneTypes}" > > > > param="#{someBean.dndParamToSendToServer}"/> > > > > </hx:panel> > > > > > > > > <!-- expected HTML5 code--> > > > > <div id="draggable1" draggable="true" > > > > ondragstart="return dragStart(event, 'copy', > > {'firstDropZoneType','secondDropZoneType'}, > > 'literalDndParamToSendToServer')" > > > > > > > > > <!-- RENDERED CONTENT --> > > > > </div> > > > > > > > > > > > > <!-- - - - - - - - - -usage: <fx:dragSource> with event handler > chains > > - - - - - - - - - - - - - - - - - - - - - - --> > > > > <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> > > > > > > > > <!-- expected HTML5 code--> > > > > <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> > > > > > > > > <!-- - - - - - - - - -usage: <fx:dragSource> within <hx:inputText> > > (allowed with HTML5, doesn't make sense though) - - - - - - - - - - - - > - - > > - - - - - - - - --> > > > > <hx:inputText id="draggableInputText"> > > > > <fx:dragSource action="move"/> > > > > </hx:panel> > > > > > > > > <input type="text" id="draggableInputText" draggable="true" > > > > ondragstart="return dragStart(event, 'move')" /> > > > > > > > > > > > > > > > > <!-- - - - - - - - - -usage: <fx:dropZone> with type and rerender - > - > > - - - - - - - - - - - - - - - - - - - - --> > > > > <hx:panel id="dropZone1"> > > > > <!-- SOME CONTENT --> > > > > <fx:dropZone actions="move" > > dropListener="#{someBean.dropListener}" > > > > rerender="draggable1" types="firstDropZoneType"/> > > > > </hx:panel> > > > > > > > > <div id="dropZone1" > > > > ondragenter="dragEnter(event,{'move'},{'firstDropZoneType'}), > > {'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> > > > > > > > > > > > > > > > > <!-- - - - - - - - - -usage: <fx:dropZone> with handler chaining - > - - > > - - - - - - - - - - - - - - - - - - - --> > > > > <hx:panel id="dropZone2" > > > > ondragover="makeRedBorder();" > > > > ondragleave="clearRedBorder();" > > > > ondrop="makeGreenBorder();" > > > > > > > > > <!-- SOME CONTENT --> > > > > <fx:dropZone actions="copy,move" > > dropListener="#{someBean.dropListener}" /> > > > > </hx:panel> > > > > > > > > <div id="dropZone2" > > > > 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> > > > > > > > > > > > > > > > > <!-- - - - - - - - - -usage: <fx:dropZone> that accepts some > specified > > mime typed content - - - - - - - - - - - - - - - - - - - - - - --> > > > > <hx:panel id="dropZone3"> > > > > <!-- SOME CONTENT --> > > > > <fx:dropZone actions="copy" > > dropListener="#{someBean.dropListener}" acceptMimeTypes="text/plain, URL" > /> > > > > </hx:panel> > > > > > > > > <div id="dropZone3" > > > > ondragenter="dragEnter(event,{'copy','move'}, null, > > {'text/plain', 'URL'})" > > > > ondragover="dragOver(event)" > > > > ondrop="drop(event)"> > > > > <!-- RENDERED CONTENT --> > > > > </div> > > > > > > > > <script><!-- > > > > > > > > var paramMimeType = 'text/x-myfaces-html5-dnd-param'; > > > > var myFacesComponentSourceMimeType = 'text/x-myfaces-html5-dnd-source'; > > > > var dropZoneMimeType = '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, > dropZoneTypes) > > { > > > > > > > > //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 > > dropzones with specific types > > > > if(dropZoneType) > > > > event.dataTransfer.setData(dropZoneMimeType, dropZoneTypes); > > //in fact, dropZoneTypes is an array. need to iterate > > > > > > > > return true; > > > > } > > > > > > > > function dragEnter(event, allowedEffects, dropZoneTypes, > 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(dropZoneMimeType) != dropZoneTypes) > > > > 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 dropZoneType, 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(); > > > > -- > Matthias Wessendorf > > blog: http://matthiaswessendorf.wordpress.com/ > sessions: http://www.slideshare.net/mwessendorf > twitter: http://twitter.com/mwessendorf > -- Jakob Korherr blog: http://www.jakobk.com twitter: http://twitter.com/jakobkorherr work: http://www.irian.at
