Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Migrated to Confluence 5.3

...

In DndPreferences.xsl, the following code is used to reference the Walter Zorn Javascript library as well as the DnDPreferences code to manage the windows. Note that the definitions must appear at the beginning of the body.

Code Block
borderStylesolid
titleDnDPreferences.xsl Javascript ImportsborderStylesolid
<body leftmargin="0" topmargin="0" marginheight="0" marginwidth="0">
    <xsl:attribute name="id">body-<xsl:value-of select="translate(//focusedTab//@name,$uppercase,$lowercase)"/>
    </xsl:attribute>
    <!-- this needs to be at the body start -->
    <xsl:if test="$mode = 'preferences' and @userLayoutRoot = 'root'">
        <script type="text/javascript" src="{$mediaPath}/common/scripts/wz_dragdrop.js"/>
        <script type="text/javascript" src="{$mediaPath}/common/scripts/al_dnd.js"/>
    </xsl:if>
....

The actual channel definitions are based on Nested Divs but you can change the code to meet your local theme.

Code Block
borderStylesolid
titleDnDPrefereces.xsl Channel HTMLborderStylesolid
<xsl:template match="channel">
    <div id="{concat('channelID',parent::node()/@ID,':',@ID,':',following-sibling::channel/@ID)}">
        <xsl:if test="$mode = 'preferences'">
            <xsl:attribute name="class">channel-preference</xsl:attribute>
        </xsl:if>
        <div class="channel-window-outside">
            <div class="channel-window-inside">
                <div class="channel-header">
                    <div>
                        <h1>
                            <xsl:attribute name="id">titleID<xsl:value-of select="@ID"/></xsl:attribute>
                            <xsl:value-of select="@title"/>
                        </h1>
                        <span><xsl:call-template name="channelRestrictions"/></span>
                    </div>
                 </div>
                 <div class="channel-content-border">
                     <xsl:attribute name="id">channelID<xsl:value-of select="@ID"/></xsl:attribute>
                     <div class="channel-content-body">
                         <xsl:copy-of select="."/>
                     </div>
                  </div>
                  <div class="channel-footer">
                      <img src="{$mediaPathSkin}/../backgrounds/channel-bottomleft.gif" alt="" width="10" height="10" border="0"/>
                  </div>
            </div>
        </div>
    </div>
</xsl:template>

...

The following Javascript is included at the bottom of the page after all the objects (i.e. channels) are defined:

Code Block
borderStylesolid
titleJavascript Calls to wz_dragdrop.jsborderStylesolid
<xsl:if test="$mode = 'preferences' and @userLayoutRoot = 'root'">
    <script type="text/javascript">
        SET_DHTML(CURSOR_HAND,NO_ALT,RESET_Z);
	<xsl:for-each select="/layout//channel">
            ADD_DHTML('<xsl:value-of select="concat('channelID',
                             parent::node()/@ID,':',@ID,':',following-sibling::channel/@ID)"/>');
         </xsl:for-each>
         <!-- other code appears here to add columns and tabs -->
    </script>

...

Finally, you need to write Javascript functions to capture when the object is clicked (my_PickFunc), dragged (my_DragFunc) and dropped (myDropFunc). All objects with IDs added above are available in the dd.elements array. The code for moving the channel is

Code Block
borderStylesolid
titleJavascript DnD CodeborderStylesolid
function my_DropFunc() {
    var drag = dd.elements[dd.obj.name]; // reference to dragged item
    var channels = new Array();
    for (var i = 0; i < dd.elements.length;i++) {
        var elem = dd.elements[i];
        // pick the channels that are in the same column as drop point.  dd.e is the drop event 
        if (elem.name.indexOf('channelID') == 0 && dd.e.x > elem.defx && dd.e.x < (elem.defx + elem.w)) {
            if (drag == elem && dd.e.y >= elem.defy && dd.e.y < (elem.defy + elem.h)) {
                // delete icon may have been clicked so ignore
                drag.moveTo(drag.defx, drag.defy); // put it back where it was
                return;
            } else
                channels.push(elem);
            }
        }
        channels.sort(sortY);
        // look for first channel that is below drop point
        for (var i = 0; i < channels.length;i++) {
            var elem = channels[i];
            if (dd.e.y < elem.defy) {
                // find channel that will follow dragged channel. Back up 1 if not first in column
                if (i > 0) { elem = channels[i-1]; }
                var dragids = drag.id.substring(9).split(':');
                var dropids = elem.id.substring(9).split(':');
                var nextID = dropids[1];
                makeURL('move_target',dragids[1],dropids[0],nextID);  // execute URL to move
                return;
            }
        }
    }
    // channel dropped below last channel in column
    var dragids = drag.id.substring(9).split(':');
    var last = channels[channels.length-1];
    var dropids = last.id.substring(9).split(':');
    var nextID = (dd.e.y > (last.defy + last.h))?dropids[2]: dropids[1];
    makeURL('move_target',dragids[1],dropids[0],nextID);
    return;
}

...