此帖子已更新:使用 jQuery 或 MooTools 进行拖放、排序、保存。此页面上的代码不再是最佳实践。
以下是几个月前在 Script & Style 上发表的一篇文章的转载……
我的客户喜欢能够控制他们网站的内容,所以我在他们的网站中建立了很多管理控制。我经常构建的一个管理控件是新闻控件。我允许客户添加、编辑、删除和排序新闻条目。我的客户特别喜欢对他们的文章进行排序,因为他们可以排序的方式:拖放。我是这样做的。
MySQL 表
| id | title | sort_order |
|---|---|---|
| 1 | 第一条 | 1 |
| 2 | 第二条 | 2 |
| 3 | 第三条 | 3 |
| 4 | 第四条 | 4 |
| 5 | 第五条 | 5 |
| 6 | 第六条 | 6 |
我的新闻表包含更多字段,但这些是本示例中的重要字段。
PHP/XHTML
<?php
<div id="message-box"><?php echo $message; ?> Waiting for sortation submission...</div>
<form id="dd-form" action="<?php echo $_SERVER['REQUEST_URI']; ?>" method="post">
<p><input type="checkbox" value="1" name="auto_submit" id="auto_submit" <?php if($_POST['auto_submit']) { echo 'checked="checked"'; } ?> /> <label for="auto_submit">Automatically submit on drop event</label></p>
<ul id="sortable-list">
<?php
$sort_order = array();
while($item = mysql_fetch_assoc($result))
{
echo '<li alt="',$item['id'],'">',$item['title'],'</li>';
$sort_order[] = $item['sort_order'];
}
?>
</ul>
<br />
<input type="hidden" name="sort_order" id="sort_order" value="<?php echo implode($sort_order,'|'); ?>" />
<input type="submit" name="do_submit" value="Submit Sortation" />
</form>
<?php } else { ?>
<p>Sorry! There are no items in the system.</p>
<?php } ?>
我们查询数据库以获取每条新闻。极其重要的是查询按项目的原始排序顺序对项目进行排序。我们将“rel”属性设置为文章 ID,并将列表项的文本设置为文章标题。
CSS
#sortable-list { padding:0; }
li.sortme { padding:4px 8px; color:#000; cursor:move; list-style:none; width:500px; background:#ddd; margin:10px 0; border:1px solid #999; }
#message-box { background:#fffea1; border:2px solid #fc0; padding:4px 8px; margin:0 0 14px 0; width:500px; }
我使用上面的 CSS 来格式化新闻项,以便客户知道每个新闻项都可以被拖动。没有一个 CSS 对于这个系统是必不可少的。
MooTools JavaScript
/* when the DOM is ready */
/* create sortables */
var sb = new Sortables('sortable-list', {
/* set options */
clone:true,
revert: true,
/* initialization stuff here */
initialize: function() {
},
/* once an item is selected */
onStart: function(el) {
el.setStyle('background','#add8e6');
},
/* when a drag is complete */
onComplete: function(el) {
el.setStyle('background','#ddd');
//build a string of the order
var sort_order = '';
$$('#sortable-list li').each(function(li) { sort_order = sort_order + li.get('alt') + '|'; });
$('sort_order').value = sort_order;
//autosubmit if the checkbox says to
if($('auto_submit').checked) {
//do an ajax request
var req = new Request({
url:'',
method:'post',
autoCancel:true,
data:'sort_order=' + sort_order + '&ajax=' + $('auto_submit').checked + '&do_submit=1&byajax=1',
onRequest: function() {
$('message-box').set('text','Updating the sort order in the database.');
},
onSuccess: function() {
$('message-box').set('text','Database has been updated.');
}
}).send();
}
}
});
});
我们使用 Moo 1.2 的 Sortables 插件类来选择列表中的所有元素并使它们可排序(拖放)。每次更改排序顺序时,都会使用“|”构建并重置隐藏的 sort_order 元素作为分隔符。如果选中该复选框,则会调用 ajax 来更新数据库中的排序顺序。否则,通过提交按钮提交的常规表单也会保存排序。
“Header” PHP / MySQL
/* on form submission */
if(isset($_POST['do_submit']))
{
/* split the value of the sortation */
$ids = explode('|',$_POST['sort_order']);
/* run the update query for each id */
foreach($ids as $index=>$id)
{
if($id != '')
{
$query = 'UPDATE test_table SET sort_order = '.$index.' WHERE id = '.$id;
$result = mysql_query($query,$connection) or die(mysql_error().': '.$query);
}
}
/* now what? */
if($_POST['byajax']) { die(); } else { $message = 'Sortation has been saved.'; }
}
标题是提交新排序顺序的地方。我们用“|”拆分sort_order 表单值并对每个项目执行查询以更新其订单。最后,如果 byajax 标志被发送,我们就终止 PHP 脚本——如果没有,我们继续加载页面。
热系统,对吧?拖放是迄今为止对项目列表进行排序的最快方法。你都有些什么想法呢?有任何改进的想法吗?
