How to Implement Drag and drop of components using richfaces with background ruler/graph to get the exact co-ordinates.

Have used the following code to add(drag/drop) components to a panel

<h:panelGrid columns="4" styleClass="main-tab-panel" style="width:1000px;height: 300px ">
<!-- Draggable components which can be dragged and dropped in Drop zones -->
<rich:simpleTogglePanel switchType="client" style="height:500px" bodyClass="rich-laguna-panel-no-header">
<rich:tabPanel  selectedTab="createForm"  style="background-color:#{richSkin.tabBackgroundColor};width:110px;">
    <rich:tab id="createForm" >
      <f:facet name="label"><h:outputText value="Add Fields"/></f:facet>

         <rich:dataGrid id="srcTable"  columns="1" value="#{dragDropService.sourceComponents}" var="_srcComponent">
         <rich:column styleClass="fdAddButton">
            <a:outputPanel style="width:128px;"
                           onmouseover="this.style.cursor='move'" layout="block">
                <rich:dragSupport dragIndicator="indicator"
                                  dragType="DRAG_COMPONENT" dragValue="#{_srcComponent}">
                   <rich:dndParam id="test" name="label" value="#{_srcComponent.displayName}"  />
                </rich:dragSupport>
              <h:outputText value="#{_srcComponent.fieldName}" styleClass="fdAddButton" onmouseover="this.className='fdAddButton-act'"  onmouseout="this.className='fdAddButton'"></h:outputText>
            </a:outputPanel>
         </rich:column>
    </rich:dataGrid>
  </rich:tab>
  </rich:tabPanel>
 </rich:simpleTogglePanel>
<rich:panel id="ctrlPanel"  style="width:1000px;height:500px;">
      <f:facet name="header"><h:outputText value="Drop Zone "/></f:facet>
    <rich:separator></rich:separator>
     <rich:dropSupport acceptedTypes="DRAG_COMPONENT" dropValue="" dropListener="#{dragDropService.processDrop}" reRender="dropTable,srcTable">
     </rich:dropSupport>
     <h:panelGroup id="dropTable" binding="#{dragDropService.panelGroup}">
        </h:panelGroup>

I am trying to get the co-ordinates using the below code:

//<![CDATA[
function getOffset(){
    //parent - panel Grid
    var parent = document.getElementById('contentForm:dropTable');
    parentObject=parent.getBoundingClientRect();
    var parentTop=parentObject.top;
    var parentLeft=parentObject.left;

    var positions = new Array();
    var delimitedValues;

    var child = parent.getElementsByTagName('table');
    var name = parent.getElementsByTagName('label');


    for(i = 0 ; i <= child.length - 1; i++){

        var component = child.item(i);
        rectObject = component.getBoundingClientRect();

        var childTop=rectObject.top-parentTop;
        var childLeft=rectObject.left-parentLeft;
        var field = name.item(i).innerHTML;
        positions.push([childTop,childLeft,field]);
        delimitedValues = positions.join("|");

        alert(delimitedValues+"   delimitedValues");

    }


    document.getElementById('contentForm:childOffset').value = delimitedValues;

}

//]]>

The components are overlapping when we drag and drop. Components are not positioned side by side i.e. in multiple columns though I drag new component beside existing component. How to achieve these criteria.

1

There are 1 best solutions below

0
On BEST ANSWER

The drag'n'drop functionality of RichFaces isn't really designed for what you're trying to do but something like this might work:

<a4j:jsFunction> can be used to send data from JavaScript to your bean

<a4j:jsFunction name="setPosition">
    <a4j:actionparam assignTo="#{bean.id}" name="id"/>
    <a4j:actionparam assignTo="#{bean.top}" name="top"/>
    <a4j:actionparam assignTo="#{bean.left}" name="left"/>
</a4j:jsFunction>

and then you need to make your component draggable and call the jsFunction when you stop dragging; RF 3 uses draggable from sript.aculo.us:

new Draggable('componentId', { onEnd : function (obj, event) {
    setPosition( obj.element.id , event.y , event.x );
});

the event is standard mouseevent, so you may need a different set of coordinates, and of course you should probably use just one parameter and then parse it in the bean, you cannot directly call a bean method and use the params as arguments.