One of the most interesting features in ASP.NET are WebParts. But one of the issues right now is the cross browser compatibility.
So with the default behavior you can add a WebpartZone and then drop your UserControl on it, but then even when you have a good usability experience using IE (you can drag & drop a WebPart to a different WebPartZone easily), as soon as you open it using Firefox or any other browser and activate the design mode of the page then you just lose this feature.
In order to achieve a cross browser experience in terms of drag and drop (which seems to be one of the most exciting feature when using webparts), I did some research and found nothing but some out-of-date workarounds to deal with this issue and partially.
So we decided to extend the WebPartZone class and add some JQuery capabilities in order to achieve the desired feature.
To solve the Drag & Drop problem of the WebParts we need three JQuery plugins.
- UI Core
These plugins can be downloaded from http://www.jqueryui.com/download
The UI Core is required so the other two plugins can actually work.
Draggable plugin allows any element of the page to be dragged and droppable allows us to specify the areas were we can drop the selected element.
In order to add the drag behavior we need to add some code when the webpart is rendered. We can do this by extending the WebPartZone class.
In our example the page that inherits from WebPartZone is called ExtendedWebPartZone and it overrides the RenderBody method from the base class.
The following code can be used to extend the class:
The RenderBody method it's called every time a WebPartZone is rendered. We then iterate through the WebPart list to check if the WebPartManager is in DesignMode. If this is the case we check if this is the first WebPart in the list. If so, we call the RenderDroppableRow in order to inject a TableRow into the HtmlTextWriter, to contain the droppable class and we set the attribute wpindex so we can use it at a later stage through our Jquery code to know where the webpart was dropped.
After that we need to check again the IsDesignMode flag, draw a table and set the CSS-class attribute to “draggable”. We also need to add the attribute webPartID so we can identify the webpart dropped and generate generate the correct postback in order to persist the changes.
Once we extended the class we need to modify the aspx page containing the WebParts.
First we need to add the references to the Jquery framework and the plugins.
Next we can define some CSS style so when the DesignMode is activated the droppable areas are highlighted and when we move a webpart over a droppable zone it get's colored.
Finally we need to write some JQuery code:
Basically all this code is generic except when we create the variable webPartZoneId used to get something like this "ctl00:ContentPlaceHolder1:".
However we needed this because we are using a MasterPage, so prefix are needed for every control. This can be added dynamically.
The final step after you add the WebPartManager to the page is register the Assembly of the project that contains the ExtendedWebPartZone. For instance:
We are now ready to add our webparts to the page! You can use some code similar to this one:
And this is how the drag and drop will look like in both Firefox and IE:
You could use the same idea to add more functionality to the webpart such a custom menu or any other cool visual behavior without needing a postback.
I’m planning to improve this code to get a more generic and reusable control. I’ll post it as soon as I’m done with it, but in the meantime this post can help anyone dealing with similar issues.
Post written by Sebastian Rodriguez – .NET Web Developer at UruIT - a Nearshore .NET Software Company