Click here to Skip to main content
Click here to Skip to main content

Drag Drop Portal Kickstart

, 5 Jun 2009 CPOL
Rate this:
Please Sign up or sign in to vote.
A jumpstart tutorial on writing portal websites

Introduction

This tutorial serves as a basis for drag drop functionality, with a push in the direction of portal website development. I kept the code short and simple so it can be implemented in any coding environment.

NOTE!!!: This is not a fully functional portal CMS, just a small working example of drag drop Widget Zone functionality with a push in the right direction towards developing your own portal website.

Background

I worked with many tools for drag drop functionality (mainly not understanding their inner workings) including Telerik RadDock and Dropthings drag drop framework and my aim was to create similar functionality that was not dependant on a server side framework (the above mentioned being dependant on the Microsoft Ajax extensions framework). 

Recently, I found a very good and lightweight example here and found that it was a very good basis to run language independent drag drop interface with a minor change needed to be done in the drag drop script to return me the important values needed, namely (what widget move, to where it moved and into which position it moved). Calling the following function:

<script language="javascript" type="text/javascript">
        function moveWidget(elementid, parentid, index) {
            window.alert("element: " + elementid + " ,parent: " + 
		parentid + " ,index: " + index);
        }    
</script>	

Using the Code 

The script imports in the header are very important to assign drag drop functionality to the columns and the docklets, but primarily you'll be focused on the moveWidget function that will return you the values that are important. In .NET you can use Ajax, web method or a service to parse these values to the server side:

			    <!--Drag drop Functionality Scripts -->
    <script language="javascript" type="text/javascript">
        function moveWidget(elementid, parentid, index) {
            window.alert("element: " + elementid + " ,parent: " + 
				parentid + " ,index: " + index);
        }    
    </script>
    <script type="text/javascript" src="Scripts/prototype.js"></script>
    <script type="text/javascript" 
	src="Scripts/scriptaculous.js?load=effects,dragdrop"></script>
    <script type="text/javascript" src="Scripts/portal.js"></script>
    <script type="text/javascript">
        var settings = {};
        var portal;
        function init() {
            portal = new Portal();
            portal.applySettings(settings);
        }
        try {
            Event.observe(window, 'load', init, false);
        } catch (exception) { }
</script>	

To define a column/drag drop zone, use...

class="portal-column" id="portal-column-0"
... naming each consecutive column with a different integer.

To define a Widget/Docking Container, use...

 <div class="block " id="block-archive-0">
                    <div class="handle">
                        Dock 1</div>
                    <div class="content">
                        <div>
                       
                            Dock 1 content
                            <br />
                            <br />
                            <br />
                            <br />
                        </div>
                    </div>
                </div> 

... naming each block archive id with a different id.

Here is an example:

<td style="vertical-align:top;">
            <div class="portal-column" id="portal-column-0">
            <h2>
                Column 0</h2>
            <div class="block " id="block-archive-0">
                <div class="handle">
                    Dock 1</div>
                <div class="content">
                    <div>
                   
                        Dock 1 content
                        <br />
                        <br />
                        <br />
                        <br />
                    </div>
                </div>
            </div>
            <div class="block " id="block-archive-1">
                <div class="handle">
                    Dock2</div>
                <div class="content">
                    <div>
                   
                        Dock 2 content
                        <br />
                        <br />
                        <br />
                        <br />
                    </div>
                </div>
            </div>
            <div class="block " id="block-archive-2">
                <div class="handle">
                    Dock 3</div>
                <div class="content">
                    <div>
                  
                        Dock 3 content
                        <br />
                        <br />
                        <br />
                        <br />
                    </div>
                </div>
            </div>
        </div>
    </td>
    <td style="vertical-align:top;">
        <div class="portal-column" id="portal-column-1">
            <h2>
                Column 1</h2>
        </div>
    </td>
    <td style="vertical-align:top;">
        <div class="portal-column" id="portal-column-2">
            <h2>
                Column 2</h2>
        </div>
    </td>		

Moving Towards Server Side Driven Data

Below is a LINQ to SQL diagram of entity relations. It is still work in progress, but I wanted you to see how the entities should be mapped so widgets can be bound to a specific Zone, Page and Template, as well as the sequence property on the PortalWidget will be of main focus here.

Portal_Website

When a drag and drop occurs, you can use Ajax, web methods or web services to update the database. (Please secure these methods because a hacker can bomb your server with requests.)

Here's the snippet I use to update the database with the latest position data: 

public static void PerformDragDrop(Guid widgetid, 
	Guid templateid, Guid pageid, string zoneID, int seq)
{                
     LINQ.DatabaseDataContext db = 
	new WebCMS.LINQ.DatabaseDataContext(LINQ.Connection.GetDBConnectionString());
     LINQ.PortalWidget movedWidget = 
	db.PortalWidgets.SingleOrDefault(p => p.WidgetID.Equals(widgetid)
	&&p.TemplateID.Equals(templateid)&&p.PageID.Equals(pageid));

     if (movedWidget != null)
     {
          var previousZoneWidgets = from p in movedWidget.PortalZone.PortalWidgets
                                    orderby p.Sequence ascending
                                    select p;
          int counter = 0;
          foreach (LINQ.PortalWidget widget in previousZoneWidgets)
          { //Re arrange previos zone widget resided
               if (!widget.Equals(movedWidget))
               {
                   widget.Sequence = counter;
                   counter++;
               }
          }
         //========Previous zone re-arranged============//
	//========Add Widget to new Zone ==============//
          counter = 0;
          var newZoneWidgets = from p in db.PortalWidgets
                               where p.ZoneID.Equals(zoneID)
                               orderby p.Sequence ascending
                               select p;
          movedWidget.Sequence = seq;
          movedWidget.ZoneID = zoneID;
          foreach (LINQ.PortalWidget widget in newZoneWidgets)
          {
               if (widget.Sequence >= seq)
               {
                   if (widget.Sequence == seq)
                   {
                        counter = seq + 1;
                        widget.Sequence = counter;
                   }
                   else
                   {
                        widget.Sequence = counter;
                        counter++;  
                   }
               }                                             
           }
           db.SubmitChanges();                          
      }               
}

This is the LINQ statement that works with the above mentioned diagram.

First I reorder the previous Zone the widget was in excluding the widget that was moved, then I loop through the widgets in the zone my widget moved to and insert the moved widget to the correct sequence.

Known Issues and Limitations

When dragging and dropping in the example, the widget might unexpectedly jump to the middle column. This is only because of the alert and when clicked, it suddenly jumps to the middle column because that marks as the last mouse position. This will go away once you don't alert in the moveWidget JavaScript function in the header. 

History

  • 5th June, 2009: Initial post

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Chona1171
Web Developer
South Africa South Africa
Hi I am a Software Developer, I have studied, Comprehensive programming, Software Development, Business and Project Management.
 
After my First year of studies I recieved a full bursary for my second year and worked as a Junior Software Development Instructor,
I am skilled in a vast array of languages my top languages being Java (SE,ME,EE),SQL C#, VB.Net, VB 6 & Asp.Net,

Comments and Discussions

 
GeneralQuestion [modified] Pinmemberjlines4125-May-10 9:53 
AnswerRe: Question PinmemberChona117125-May-10 10:32 
GeneralRe: Question Pinmemberjlines4126-May-10 4:07 
GeneralRe: Question PinmemberChona117126-May-10 4:17 
GeneralRe: Question PinmemberChona117126-May-10 4:18 
GeneralRe: Question Pinmemberjlines4126-May-10 6:01 
GeneralRe: Question PinmemberChona117126-May-10 8:04 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web03 | 2.8.141030.1 | Last Updated 5 Jun 2009
Article Copyright 2009 by Chona1171
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid