具有多个列表和订单的可拖动和可放置项目

时间:2016-06-24 22:04:32

标签: javascript php jquery arrays jquery-ui

我试图找到项目的顺序,因为它们被拖到新列。一旦用AJAX拖动,我正在更新项目所在的列。我也正在使用$(this).sortable('serialize')按顺序获取所有内容。当我把它放入警报时。我遇到的问题是当我将数组发送到PHP时,其中一个项目会被删除。我猜这与我使用序列化的方式有关,但我不确定。我能得到的任何帮助将不胜感激。同事告诉我,我应该接受代码的限制并与之共存。我不同意并且知道项目所处的顺序几乎与数据所在的列一样重要。我认为我需要在javascript中使用两个不同的事件。一个用于列表之间的拖动,一个用于重新排列div中的项目。希望有人能指出我正确的方向。

我有的HTML

<div class="col-lg-12 text-center">
     <div class="col-md-3">
          <h3>Unsorted Items</h3>
           <ul id="UNSORTED" class="connectedSortable">
                <li id="item-1">Unsorted item 1 from DB</li>
                <li id="item-2">Unsorted item 2 from DB</li>
                <li id="item-3">Unsorted item 3 from DB</li>
                <li id="item-4">Unsorted item 4 from DB</li>
                <li id="item-5">Unsorted item 5 from DB</li>
           </ul>
     </div>
     <div class="col-md-3">
           <h3>ACCEPTED</h3>
           <ul id="ACCEPTED" class="connectedSortable">
                 <li id="item-6">Unsorted item 6 from DB</li>
                 <li id="item-7">Unsorted item 7 from DB</li>
                 <li id="item-8">Unsorted item 8 from DB</li>   
           </ul>
     </div>
     <div class="col-md-3">
           <h3>REJECTED</h3>
            <ul id="REJECTED" class="connectedSortable">
                <!-- empty to show drag to -->        
            </ul>
      </div>        
</div>

Javascript

<script>
    $(function() {
        $( "#UNSORTED, #ACCEPTED, #REJECTED" ).sortable({
            connectWith: ".connectedSortable",
            receive: function(event, ui) {
                // The position where the new item was dropped
                var newIndex = ui.item.index();
                var sender = ui.sender.context.id;
                var receiver = this.id;
                var idNum = ui.item.context.id;
                var display_order = $(this).sortable('serialize');

                //this alerts the correct order
                alert(display_order);

                //this when uncommented alerts what item tranfered to and from
                //alert(idNum + ' Was Transfered from "' + sender + '" to "' + receiver + '".');

                //this tell the new order of the items the item was dragged to
                //alert(receiver + ' Order is ' + $(this).sortable('serialize'));
                var action = 'update_selection';

                $.ajax({
                    url: "index.php?action=" + action + "&item=" + idNum + "&selection=" + receiver + '&item-' + display_order,
                    success:function (data) {
                        $("#results").html(data).slideDown('2000');
                    }
                });

            },
            stop: function (event, ui) {
                var sender = this.id;
                var data = $(this).sortable('serialize');

                //this when uncommented alerts new order of old list
                //alert(sender + ' Order is ' + data);

                //this was to write new order of old list unless I can figure out how to write it in the 'receive' event
                /*$.ajax({
                 data: oData,
                 type: 'POST',
                 url: '/your/url/here'
                 });*/
            }
        }).disableSelection();
    });
</script>

缩短版本的PHP

$item_id = filter_input(INPUT_GET, 'item');

/*the number after item- is dynamic from the DB and I was unable to get         serialize to work without the item- in it so now I am removing item- to get the actual DB id with preg_replace */
$item_id = preg_replace('/^item-/', '', $item_id);

$selection = filter_input(INPUT_GET, 'selection');

//can't use filter_input on an array
$display = $_GET['item'];

/*this dumps the array with an array item missing. Sometimes its the first item in the array and sometimes its not */
var_dump($display);

1 个答案:

答案 0 :(得分:0)

好吧我明白了。我需要通过POST传递AJAX而不是GET。但是,我仍然对我这样做的方式有问题,因为我不能像我那样做。我打算拥有一个只有每列显示顺序的表。但是当在项目表中已经存在项目所属的列名时,这非常愚蠢。只需将项目移动到另一列时,就可以更轻松地添加具有显示顺序的另一列。所以这是我的完整工作代码,它使用AJAX进行更新,并记住项目所在的新列中的位置。如果有人遇到这篇文章并且知道更好的方法,请分享。我喜欢从错误中吸取教训。

HTML

<div class="col-lg-12 text-center sortable">
     <div class="col-md-3">
          <h3>Unsorted Items</h3>
<!--I am not including the PHP loop to display the list of items -->
           <ul id="UNSORTED" class="sort-list">
                <li id="item-1">Unsorted item 1 from DB</li>
                <li id="item-2">Unsorted item 2 from DB</li>
                <li id="item-3">Unsorted item 3 from DB</li>
                <li id="item-4">Unsorted item 4 from DB</li>
                <li id="item-5">Unsorted item 5 from DB</li>
           </ul>
     </div>
     <div class="col-md-3">
           <h3>ACCEPTED</h3>
           <ul id="ACCEPTED" class="sort-list">
                 <li id="item-6">Unsorted item 6 from DB</li>
                 <li id="item-7">Unsorted item 7 from DB</li>
                 <li id="item-8">Unsorted item 8 from DB</li>   
           </ul>
     </div>
     <div class="col-md-3">
           <h3>REJECTED</h3>
            <ul id="REJECTED" class="sort-list">
                <!-- empty to show drag to -->        
            </ul>
      </div>        
</div>

Javascript

<script>
    $(function(){

    /* Sort steps */
    $('.container').sortable({
        axis: "y",
        update: function (event, ui) {
            var data = $(this).sortable('toArray');
            $("#result").html("JSON:<pre>"+JSON.stringify(data)+"</pre>");
        }   
    }); 

    /* Here we will store all data */
    var myArguments = {};   

    function assembleData(object,arguments)
    {       
        var data = $(object).sortable('toArray'); // Get array data 
        var step_id = $(object).attr("id"); // Get step_id and we will use it as property name
        var arrayLength = data.length; // no need to explain

        /* Create step_id property if it does not exist */
        if(!arguments.hasOwnProperty(step_id)) 
        { 
            arguments[step_id] = new Array();
        }   

        /* Loop through all items */
        for (var i = 0; i < arrayLength; i++) 
        {
            var image_id = data[i]; 
            /* push all image_id onto property step_id (which is an array) */
            arguments[step_id].push(image_id);          
        }
        return arguments;
    }   

    /* Sort images */
    $('.sort-list').sortable({
        connectWith: '.sort-list',

                //leaves out the bootstrap class
        items : ':not(.col-md-3)',

        /* That's fired first */    
        start : function( event, ui ) {
            myArguments = {}; /* Reset the array*/  
        },      
        /* That's fired second */
        remove : function( event, ui ) {
            /* Get array of items in the list where we removed the item */          
            myArguments = assembleData(this,myArguments);
        },      
        /* That's fired thrird */       
        receive : function( event, ui ) {
            /* Get array of items where we added a new item */  
            myArguments = assembleData(this,myArguments);       
        },
        update: function(e,ui) {
            if (this === ui.item.parent()[0]) {
                 /* In case the change occures in the same container */ 
                 if (ui.sender == null) {
                    myArguments = assembleData(this,myArguments);       
                } 
            }
        },      
        /* That's fired last */         
        stop : function( event, ui ) {                  
            /* Send JSON to the server */
            var action = 'update_selection';
            var orders = JSON.stringify(myArguments);
            $.ajax({
                url: 'index.php',
                type: 'POST',
                data: {action: action, code: orders},

                //I used success function to var_dump PHP when testing
                success:function (data) {
                     $("#result").html(data).slideDown('2000');
                }
            });
        }   
    });
});
</script>

最后但并非最不重要的PHP文件。我使用MVC所以我调用动作并将我的脚本发送到正确的案例来处理PHP(以防有人读到这个不知道我会包含整个PHP文件。)

require("classes/Db.class.php");

$db = new Db();

if (isset($_POST['action'])) {
    $action = $_POST['action'];
} else if (isset($_GET['action'])) {
    $action = $_GET['action'];
} else {
    $action = 'home';
}

switch ($action) {
    case 'home':
        //gets all items and display order for those items
        $unsorted = $db->query("SELECT * FROM sorting WHERE column_name = 'UNSORTED' ORDER BY display_order");
        $accepted = $db->query("SELECT * FROM sorting WHERE column_name = 'ACCEPTED' ORDER BY display_order");
        $rejected = $db->query("SELECT * FROM sorting WHERE column_name = 'REJECTED' ORDER BY display_order");
        $possible = $db->query("SELECT * FROM sorting WHERE column_name = 'POSSIBLE' ORDER BY display_order");

        include_once('home.php');
        break;

    case 'update_selection':

        $json = filter_input(INPUT_POST, 'code'); //gets the json stringify
        $array = json_decode($json, true); //specify an associative array instead of an object from json_decode

        foreach($array as $key => $value){

            //gets column item belongs to now
            $column_name = $key;

            foreach($value as $key => $number){
                //this gets the key which we will use for ordering
                $order = $key;

                //update DB with column name item belongs to and the new order of all items in that column
                $db->query("UPDATE sorting SET column_name = :column_name, display_order = :order WHERE gun_id = :number", array("column_name"=>$column_name, "number"=>$number, "order" => $order));
            }  
        }

        break;