拖放门户入门
编写门户网站的入门教程。
引言
本教程作为拖放功能的基础,并朝着门户网站开发的方向推进。我保持代码简短易懂,以便在任何编码环境中实现。
注意!!!:这并不是一个功能齐全的门户网站CMS,只是一个拖放Widget Zone功能的小型工作示例,旨在引导您开发自己的门户网站。
背景
我使用了许多拖放功能的工具(主要是不了解它们的内部工作原理),包括Telerik RadDock和Dropthings拖放框架,我的目标是创建类似的功能,而无需依赖服务器端框架(上述框架依赖于Microsoft Ajax扩展框架)。
最近,我找到了一个非常好的、轻量级的例子这里,并发现它是一个很好的基础,可以运行与语言无关的拖放界面,只需要对拖放脚本进行微小的更改,以返回给我所需的重要值,即(哪个小部件移动,移动到哪里,以及移动到哪个位置)。调用以下函数
<script language="javascript" type="text/javascript">
function moveWidget(elementid, parentid, index) {
window.alert("element: " + elementid + " ,parent: " +
parentid + " ,index: " + index);
}
</script>
使用代码
标头中的脚本导入对于将拖放功能分配给列和docklet非常重要,但您主要关注的是moveWidget
函数,该函数将返回给您重要的值。在.NET中,您可以使用Ajax、web方法或服务将这些值解析到服务器端
<!--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>
要定义一个列/拖放区域,请使用...
class="portal-column" id="portal-column-0"
...用不同的整数命名每个连续的列。要定义一个Widget/Docking Container,请使用...
<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>
...用不同的id命名每个块存档id。
这是一个例子。
<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>
迈向服务器端驱动的数据
下面是实体关系的LINQ to SQL图表。它仍在进行中,但我希望您了解实体的映射方式,以便小部件可以绑定到特定的区域、页面和模板,以及PortalWidget
上的sequence属性将成为关注的重点。

当发生拖放时,您可以使用Ajax、web方法或web服务来更新数据库。(请保护这些方法,因为黑客可能会用请求轰炸您的服务器。)
这是我用来使用最新位置数据更新数据库的代码片段:
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();
}
}
这是与上述图表一起使用的LINQ语句。
首先,我重新排序小部件所在的前一个区域(不包括已移动的小部件),然后遍历我的小部件移动到的区域中的小部件,并将已移动的小部件插入到正确的序列中。
已知问题和限制
在示例中进行拖放时,小部件可能会意外跳到中间列。这仅仅是因为alert,当单击时,它会突然跳到中间列,因为它标记为最后一个鼠标位置。一旦您不在标头中的moveWidget
JavaScript函数中显示alert,它就会消失。
历史
- 2009年6月5日:初始帖子