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

Drag Drop Portal Kickstart

By , 5 Jun 2009
 

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)

About the Author

Chona1171
Web Developer
South Africa South Africa
Member
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,

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralQuestion [modified]memberjlines4125 May '10 - 9:53 
This code is amazing. Nice work! Is there a way to disable or hide the window alert? I dont quite understatde the don't widow alert. Can you send me some sample code please? I tried a few things but it seems like everythime I alter the window.alert function, the widgets dont function properly.
 
Thanks,
Jim

modified on Tuesday, May 25, 2010 4:49 PM

AnswerRe: QuestionmemberChona117125 May '10 - 10:32 
You can remove the window alert by taking this bit of code out of your script tag in the default.aspx file
 

------------------------------------------------
window.alert("element: " + elementid + " ,parent: " +
          parentid + " ,index: " + index);
--------------------------------------------------
 
That was placed there merely to show you what information gets parsed back to you when a drag drop is returned.
 
That code can then be replaced by logic that stored the position when the page gets refreshed.
 
You have two options wither you can store it in a cookie.
Or you can integrate it into a Content management System Logic like expressed in the article by using Ajax or a web service to parse the client info back to the server side logic.
 
I would give you a hand if need be.
 
Chona1171
Web Developer (C#), Silverlight

GeneralRe: Questionmemberjlines4126 May '10 - 4:07 
Hi, and thanks for your answer.
 
Your answer worked great thanks! Also, I would like to to use cookies. Could you be so kind to inform me how to do that?
 
Thanks,
Jim
GeneralRe: QuestionmemberChona117126 May '10 - 4:17 
Sorry i mean the portal.htm file
 
Ok i would recommend reading up on some java-script especially if you want to store it in cookies.
 
Are you using any server language or are you just beginning web development ?
 
Chona1171
Web Developer (C#), Silverlight

GeneralRe: QuestionmemberChona117126 May '10 - 4:18 
This url has a very good explanation of storing cookies http://www.w3schools.com/JS/js_cookies.asp
 
Chona1171
Web Developer (C#), Silverlight

GeneralRe: Questionmemberjlines4126 May '10 - 6:01 
One other thing I am woundering is if it is possible to modifye the red-dashed hover. I see you can change the color through css, but can you also specifye a width height or margin? Ideally what I want to do is have the dashed- red hover be the same size as the "box" being moved.
 
Thanks again,
Jim
 
Also thanks for the link is the last message will that work for php or only asp?
GeneralRe: QuestionmemberChona117126 May '10 - 8:04 
that is mostly css managed, you will have to adjust the css to do this.
 
The code i sent is javascript, though if you are coding in php i would recommend reading this http://aymanh.com/drag-drop-portal-interface-with-scriptaculous its where the original script came form and explains how to implement it in php.
 
The code example i gave is an implementation for asp.net using the C# language.   asp though similar to asp.net is not quite the same language.
 
Chona1171
Web Developer (C#), Silverlight

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

Permalink | Advertise | Privacy | Mobile
Web04 | 2.6.130516.1 | Last Updated 5 Jun 2009
Article Copyright 2009 by Chona1171
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid