帮酷LOGO
0 0 评论
文章标签:sort  
jQuerySort Demo Screen

介绍

jQuery UI 真的很容易在网页上实现可以排序的元素,并且获得排序的数据的结果。 如果有一个方法来执行单个数据库更新来记录新的元素顺序而不是遍历一系列的记录。

本文演示了如何创建可以排序元素,对事件进行排序,并通过AJAX发送数据,以及使用算法来处理数据,以确定移动哪个元素。 在那里。

方法还向你展示了配置存储元素数据和计算元素索引的方法,以便可以使用单个查询更新排序次序。

使用代码

要运行代码,需要使用带有 PHP5.4 或者正确配置的IDE的服务器,其中内置了PHP服务器( 源文件中包含NetBeans项目文件,但是你可以将代码导入到另一个IDE中)。 这不是生产准备。 把它当作你自己项目的模板。 英镑和英镑类将被你自己的应用程序类替代。

附加的代码包含一个初始化 MODULE ( index.php ),它只是为演示创建数据并将它的放入会话中。 文件 sortExample.html 为主要页面,以英镑样式进行样式设置。

重要的文件为 sortable.js SortController.php。 这些处理浏览器和服务器之间的通信。 控制器类包含处理由jQuery提供的序列化数据的逻辑,这些数据在组件被排序时提供。

首先,这个javascript函数初始化保存可以排序元素的容器( 在这种情况下,一个 div )。 加载文档时将调用它。

function initSortableContainer()
 {
 $(function()
 {
 $("#SortableElements").sortable(
 {
 cursor: "move",
 stop: handleReorderElements
 });
 });
 }

函数 handleReorderElements() 对服务器进行了AJAX调用。 initSortableContainer() 函数( 上方上方) 将'停止'事件绑定到包含可以排序元素的div,指定在排序操作完成时调用这里函数。 在 sortable("serialize") 函数的新顺序中,使用jQuery函数获取所有可以排序元素的参数/值字符串。 有关如何创建可以排序元素的id的说明,请参见 below 节,以便正确工作。

function handleReorderElements()
 {
 var url = 'controllers/SortController.php';
 var fieldData = $( "#SortableElements" ).sortable( "serialize" );
 fieldData += "&action=reorderElements";
 var posting = $.post( url, fieldData);
 posting.done( function( data)
 {
 reorderElementsResponse( data );
 });
 }

这里函数是AJAX回调处理程序。 在大多数应用程序中,除了处理错误外,你不需要做任何事情。 对于演示,控制器返回排序处理的结果。 如果没有错误,函数将在页面上显示。

function reorderElementsResponse( data )
 {
 if (data.FAIL === undefined) // Everything's cool! {
 $("#Message").html( data.resultString + data.itemIndexString );
 }
 else {
 alert( "Bad Clams!" );
 }
 }

重要:格式化HTML元素 id

必须使用公共 NAME。折线或者下划线和,号创建可以排序元素的,。 如果你查看文件 index.php,你将看到每个可以排序元素的构造都是用id='SortableElement_". $element->getId()<code> 要生成 SortableElement_1,SortableElement_2,SortableElement_3,等等 等编号的标识标记,传递给服务器的字符串将如下所示: SortableElement[]=1&SortableElement[]=2&SortableElement[]=3, 等等,实际上将由PHP解释为 array。

在英镑 SortController.php 中,我们可以使用这个 $sortIdArray = $_POST["SortableElement"];
相当轻松 !

处理数据

SortController.php 从页面接收AJAX请求。 它检索名称/值对并将它的存储在变量 $sortIdArray 中。 然后从会话中提取原始 array,并将键( 哪些是元素 id'的键提取到一个单独的array 中:

$sortList = $profile->getSortableElementList();$originalIdList = array_keys( $sortList );

接下来,调用一个函数来比较数组,确定哪个元素被移动。 函数 getArrayDiff( $originalKeys, $newKeys) 通过修改的array的原始和。的array的一个。 它比较每个原始标识和修改 Id,直到找到一个不存在的对。 其中一个可能是被移动的。 为了找出哪一个,函数从两个数组中删除原来的Id,然后再次比较两个数组。 有趣的是,移除移动的Id后,两个数组将变得相同。 因为第一次测试可能是正确的,所以删除/比较只能执行一次。 如果数组在第一次比较中不相同,那么它的他,就是移动的那个。 。当函数结束时,它返回移动的Id (。或者 -1如果没有移动标识)。 跟踪函数以查看它的工作方式,并注意下面的警告,如果两个相邻的元素被交换-。

确定移动的标识后,我们需要找出移动的位置。 初始化几个变量以处理移动到 array的开头或者结尾之后,代码循环执行修改的array,以查找移动的Id,存储下一个 Id stores Id Id Id values values。

表结构

备份一点并讨论使单个更新能够存储修改后的to订单的table 结构的时间。 秘诀是将你的索引字段( 在这种情况下,ItemIndex ) 定义为一个 DOUBLE。 ,将ItemIndex转换为 reflect previous,然后更新索引以反映新的顺序,我们可以简单地将ItemIndex更改为上一个和下一个值 between ItemIndex values。 比如,如果在记录之间移动一个带有1 和4 个记录的记录,那么我们只需要更新已经移动项的索引,就可以将该记录。 你可能会认为,你最终将失去保持索引分割的能力;。 然而,在实际中,你可以在超过精确度之前超过 1,000倍。 在现实世界中,这可能永远不会发生,但是请注意 below 关于处理可能性的注释。

将新记录插入到 table 时,需要确保将ItemIndex字段设置为大于当前最大 ItemIndex ( 和 GREATER 比 0 )的值。 类似于以下内容的内容:

public function insert( SortableElement $sortableElement )
 {
 $sql = "SELECT MAX(ItemIndex) as Result
 FROM sortable_elements
 WHERE OrganizationId =". $sortableElement->getOrganizationId();
 $itemIndex = $this->m_FSPDO->executeFunction( $sql );
 if ($itemIndex === null)
 {
 $itemIndex = 10;
 }
 $itemIndex += 10;
 $sql = "INSERT INTO sortable_elements ( OrganizationId, Status, Title, HolderId, HolderAccountType, ItemIndex)
 VALUES ( :organizationId, :status, :title, :holderId, :holderAccountType, :itemIndex)";
 $sortableElement->setId( null );
 $parameters = $sortableElement->getAllParameters( true );
 $parameters[':itemIndex'] = $itemIndex;
 $sortableElement->setId( $this->m_FSPDO->executeInsert( $sql, $parameters ) );
 }

*This 使用两步方法,但是根据你的数据库和首选项,你可以使用存储过程。


通过这种方式配置 table,只需计算前一个和下一个ItemIndexes之间的值,即可以将元素移到列表( 因此,需要在值 GREATER 处启动ItemIndex字段,而不是零) 或者列表末尾:

if ($previousKey === 0)
 {
 $itemIndex = (double)((double)(reset( $sortList )->getItemIndex()/2));
 }elseif ($nextKey === INF)
 {
 $itemIndex = (double)((double)(end( $sortList )->getItemIndex() + 10));
 }else {
 $lowIndex = (double)$sortList[(int)$previousKey]->getItemIndex();
 $highIndex = (double)$sortList[(int)$nextKey]->getItemIndex();
 $itemIndex = (double)($lowIndex + ($highIndex - $lowIndex)/2);
 }

Points of Interest

精度损失

尽管不可以能超精确地重新计算一个新索引的中间值,但是可以能。 处理条件的主要方法有两种,即避免出现错误。 第一种方法是显式检查计算值,以确定它是否等于周围值的任何一个。 如果是,你已经失去精确性,需要调用函数( 最好是一个快速的异步功能) 来重新索引相关组中的记录。 然后,如果你相信在应用程序中有可以能的话,可以创建一个时间序列任务。 具体实现超出了本文的范围。 目前:)

这里演示中使用的"movedkey"变量可能不准确

作为演示的一部分,返回的is被返回,但是你可能会注意到,当它不正确时。 只有将两个相邻的面板移动到一个较低的位置时,将两个相邻的面板Transposing正确移动的标识。 这是因为当相邻项被切换时数组是相同的。

例如如果原始为 Id。2.3。4.5和Id在'1'和'2'之间移动,则会导致以下情况:

1.3。2.5.

如果在'3'和'4'之间移动了 Id'2',则 array 将成为:

1.3。2.5

嗯。same同样的数组。


在这种情况下,当getArrayDiff函数比较数组时,它总是在第一次尝试时成功,因为它们是相邻的。 通过代码跟踪是理解正在发生的事情的最佳方式。

幸好,这并不影响排序结果。 将相邻项转换为方法将导致正确的排序顺序。 如果由于某些原因,你需要知道哪些项目被移动,这只是一个问题。 当你需要了解( jQuery处理用户界面更改) 时,不应该有很多实例,但是如果你需要,它将需要在客户端附加代码。

历史记录

版本 1.0



文章标签:sort  

Copyright © 2011 HelpLib All rights reserved.    知识分享协议 京ICP备05059198号-3  |  如果智培  |  酷兔英语