这就是我要做的,这当然不是最干净的方式,但它应该可以工作。
这假设您正在使用自己的页面,而不是您通过对某些外部站点(例如通过 CURL)的 http 请求获取页面 html 并需要解析它的场景。DOMDocument 为后一种情况提供了很好的服务。此解决方案适用于前者,因为我假设由于您在其客户端使用 javascript,它可能是您自己的页面(除非您在页面加载后将该 javascript 注入该页面)。
首先,在每个列表项中,我会包含一个服务器端可访问的输入标签。它将用于跟踪位置和值,并在提交表单时将其传递给服务器端脚本。
<form method="POST">
<ul id="sortable">
<li class="ui-state-default">1
<input id="the_list_item_1" name="the_list_item[]" type="text" value="1_0" style="display: none;">
</li>
...
</ul>
</form>
该值是项目的实际值(示例范围为 1 - 12),其位置由下划线分隔(值 + "_" + 位置);
如果您只需要在用户完成后将列表提交给服务器进行处理,则该列表需要位于表单变量中。但是,如果您打算只使用 Ajax 将该数据获取到服务器,那么这个解决方案并不是必需的(因为您只需使用 jquery 来获取每个位置和值对并直接在您的 ajax 调用中发送它们)。
当用户拖动项目并更改列表的顺序时,您需要处理更新这些输入标签。如果您需要了解如何使用可排序事件,请参阅此处。也许,在更新时,对于每个列表项,使用新位置调用此函数:
function update_pos(value,pos)
{
$("#the_list_item_"+value).val(value+"_"+pos);
}
所以在表单提交时,我们现在在 PHP 端。
$list_items = $_POST["the_list_item"]; // This is basically an array of all the list_items, thanks to naming all the list items with "the_list_item[]", note the empty subscript (square braces).
$ordered_list_items = array(); // Let's push them into an associative array.
foreach($list_items as $li)
{
$li_split = explode("_",$li);
if(count($li_split) <= 0)
continue; // maybe you'd want to handle this situation differently, it really shouldn't happen at all though. Here, I'm just ignoring nonsensical values.
$item_id = $li_split[0];
$pos = $li_split[1];
$ordered_list_items[$item_id] = $pos;
}
// Then later you can shoot through this list and do whatever with them.
foreach($ordered_list_items as $item_id => $pos)
{
// postgres perhaps. Insert if not already there, update regardless.
pg_query("insert into the_list_item (item_id,position) select '$item_id','$pos' where '$item_id' not in (select item_id from the_list_item where '$item_id' = item_id limit 1));
pg_query("update the_list_item set position = '$pos' where item_id = '$item_id'");
}
当然,说了这么多,根据您的需要,您可能需要将这些数据重新加载到页面上。因此,循环遍历您的数据库结果(也许对于该用户),您会将每个 list_item 输出到位。
$list_items = pg_fetch_all(pg_query($sql)); // $sql needs to be the query to get the results. Probably should order by position ascending.
$lic = count($list_items);
?>
<html> and stuff
<form method="POST">
<ul id="sortable">
<?php
for($i = 0; $i < $lic; $i++)
{
$li = $list_items[$i];
echo "<li class=\"ui-state-default\">".$li["item_id"]."<input id=\"the_list_item_".$li["item_id"]."\" name=\"the_list_item[]\" type=\"text\" value=\"".$li["item_id"]."_".$li["position"]."\" style=\"display: none;\"></li>";
}
?>
</ul>
</form>