Tell me more ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I'm trying to save the order of a table with jQuery UI (sortable) to a PHP array.

I have simplified it very considerably but this is the basic idea of it. I have a table with a sortable list embedded in it. The table is generated through a PHP foreach involving the multi-dimensional array that is included in another file (config.php).

config.php:

<?php
$config     = array(
    "mno" => array('item 5'),
    "abc" => array('item 1'),
    "ghi" => array('item 3'),
    "pqr" => array('item 6'),
    "jkl" => array('item 4'),
    "vwx" => array('item 8'),
    "def" => array('item 2'),
    "stu" => array('item 7'),
);
?>

table (index.html):

<table cellpadding="2" cellspacing="0" align="center" id="mytable">
    <tbody>
<?php
    $i = 0;
    include 'config.php';
    foreach($config AS $name => $value){
        $item = $value[0];
        echo '
        <tr id="'.$name.'-'.$i++.'">
            <td>'.$item.'</td>
        </tr>';
    }
?>
    </tbody>
</table>

scripts (index.html):

<!-- Add jQuery library -->
<script type="text/javascript" src="http://code.jquery.com/jquery-latest.min.js"></script>
<!-- Add jQuery UI library -->
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.10.3/jquery-ui.min.js"></script>
<script type="text/javascript">
    $(document).ready(function() {
        var fixHelper = function(e, ui) {
            ui.children().each(function() {
                $(this).width($(this).width());
            });
            return ui;
        };

        $("#mytable tbody").sortable({
            helper: fixHelper,
            opacity: 0.5,
            scroll: false,
            update: function () {
                var data = $('#mytable tbody').sortable('serialize');
                $.post("edit.php", {'neworder': data});
            }
        }).disableSelection();
    });
</script>

The sorting works fine but I don't know how to save the neworder value ($_POST['neworder']) into the array what is in config.php.

I think I must use the PHP functions uasort() (or uksort(), uksort()) with the combination of file_put_contents to save the new order in config.php.

So something like this:

<?php
if($_SERVER['REQUEST_METHOD'] == 'POST' && isset($_POST['neworder'])) {
    /* 
    Here file_put_contents in config.php the new order. So:
    $config     = array(
        "mno" => array('item 5'),
        "abc" => array('item 1'),
        "ghi" => array('item 3'),
        "pqr" => array('item 6'),
        "jkl" => array('item 4'),
        "vwx" => array('item 8'),
        "def" => array('item 2'),
        "stu" => array('item 7'),
    );

    Becomes:
    $config     = array(
        "abc" => array('item 1'),
        "def" => array('item 2'),
        "ghi" => array('item 3'),
        "jkl" => array('item 4'),
        "mno" => array('item 5'),
        "pqr" => array('item 6'),
        "stu" => array('item 7'),
        "vwx" => array('item 8'),
    );

    After this is send by Jquery UI:
    neworder:abc[]=1&def[]=6&ghi[]=2&jkl[]=4&mno[]=0&pqr[]=3&stu[]=7&vwx[]=5

    I've tried this:
        $filename = 'config.php';

        $lines = file( $filename , FILE_IGNORE_NEW_LINES );
        $linenumber = 2;
        foreach( $_POST['neworder'] AS $name => $val){
            $phost = $val[0];

            $lines[$linenumber] = ' "'.$name.'" => array(\'' . $phost . '\'),';
            $linenumber++;
        }

        file_put_contents( $filename , implode( "\n", $lines ) );

    But the '$val' is not send with Jquery only the order.

    */  
}
?>
share|improve this question
1  
Saving data into php files is a bad idea. You can store them in some json or xml format. If you need to do it on a larger scale/more frequently, you have to use a database. – user568109 Jul 7 at 10:01
@GerritHoekstra Hi I want to help you and think its not so hard but I want to know why you are doing it in this bad way? Can I change some part of it as it became better? I mean in general a tables with two or more columns that can be sorted with jui and as its sorts or as user clicks on a button the new order save? why you don't use JSON or XML format to save? and a file named JSON_Config_reader.php in witch reads that JSON file and make that array? – imsiso Jul 11 at 12:44
@GerritHoekstra - you know what. You could just put a comment for me saying 'nice try'. – imsiso Jul 17 at 0:32
add comment (requires an account with 50 reputation)

4 Answers

up vote 0 down vote accepted
+50

You are going to want to use usort with a closure (available in php 5.3+) to get the keys in the order that you need them in.

$newOrder = $_POST["neworder"];
$config_keys = array_keys($config);
usort($config_keys, function($a, $b) use($newOrder) {
      return array_search($a, $newOrder) - array_search($b, $newOrder);
});

Then you can change rewrite $config into the new order

$newConfig = array();

foreach($config_keys as $key){
    $newConfig[$key] = $config[$key];
}
$config = $newConfig;
unset($newConfig);

From here you can persist $config in whatever method makes the most sense for your use case. I would advise against using it to create a php file though, a better approach may be to use

file_put_contents($cacheFile, serialize($config));

then to retrieve

$config = unserialize(file_get_contents($cacheFile));
share|improve this answer
Thanks, I will use this. It works with this modification in jQuery UI: update: function () { var a = $('#mytable tbody').sortable('toArray'); var newOrdering = []; for (var i=0; i<a.length; i++) newOrdering[i] = a[i].substring(0, a[i].indexOf('-')); $.post("edit.php", {'neworder': newOrdering}); } – Gerrit Hoekstra Jul 14 at 10:37
add comment (requires an account with 50 reputation)

You probably want to use a database for config if you want to change it dynamically. Also, not crazy about modifying a php file where someone can inject malicious codes.

share|improve this answer
add comment (requires an account with 50 reputation)

There are so many threads that covers your problem

  1. jQuery UI Sortable, then write order into a database
  2. save jquery ui-sortable positions to DB
  3. Optimal way to save order of jQueryUI sortable list with Meteor
  4. http://dev.nirmalya.net/articles/javascript/saving-ordering-of-a-sortable-list-using-jquery-ui

I am sure you will find your answer there. All is about getting the order via

$('#mylist').sortable('toArray');

save it to database

and then get the order from database and show it properly with loop. Take a look at tutorials.

share|improve this answer
add comment (requires an account with 50 reputation)

try this.Hope to help.

First I used JSON instead of php to store data.

 

Second I used jQuery and AJAX to save new order.

If you loved this tell me and I will put comments for it.

index.php

<?php
    function JSON2Array($path){
        $data=file_get_contents($path);
        if( !($ret=json_decode($data)) ){
            $ret=array();
        }
        return $ret;
    }

    $data=JSON2Array('config.json');
?>
<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>sortable table</title>

        <style>

    .sortable { list-style-type: none; margin: 0; padding: 0; }
    .sortable li { margin: 0 5px 5px 5px; padding: 5px; font-size: 1.2em; height: 1.5em; }
    html>body .sortable li { height: 1.5em; line-height: 1.2em; }
    .ui-state-highlight { height: 1.5em; line-height: 1.2em; border:1px solid #fb3;padding:3px; background: #fec}

        .table ,.tr{
            border:1px solid;
            padding:2px;
            margin:1px;
        }

        .tr{
            background: #fff;
        }

        .td{
            padding:5px 10px;
        }

        .table{
            display:inline-block;
            width:400px;
        }
        .table .td{
            display:inline-table;
        }

        </style>

        <script type="text/javascript" src="js/jquery.js" ></script>

        <script type="text/javascript" src="js/jquery-ui.js" ></script>

        <script type="text/javascript">
    $(document).ready(function() {
        $( ".sortable" ).sortable({
            placeholder: "ui-state-highlight",
                        update:function(event,ui){
                            if($('#autosave').prop('checked')){
                                var tmp;
                                $('.sortable').each(function(){
                                    tmp=this;
                                });
                                saveOrder(tmp);
                            }
                        }
        });
        $( ".sortable" ).disableSelection();
                $('#autosave').on('change',function(){
                    if($(this).prop('checked')){
                        $('#save').prop('disabled','disabled');
                    }else{
                        $('#save').prop('disabled',false);
                    }
                });

                $('#save').on('click',function(){
                    var tmp;
                    $('.sortable').each(function(){
                        tmp=this;
                    });
                    saveOrder(tmp);
                });

                function saveOrder(mt){
                    var stringQuery='path=config.json';
                    $(mt).children('.tr').each(function(){
                        stringQuery+='&order[]='+$(this).attr('id');
                    });
 //                   stringQuery =new String(stringQuery);
 //                   stringQuery=stringQuery.substr(0,stringQuery.length-1);
                    $.post('save.php',stringQuery,function(data){
                        data=$.parseJSON(data);
                        alert(data.msg);
                    });
                }

    });
        </script>

    </head>
    <body>

<div class="table sortable">
<?php 
            $i=1;
            foreach ($data as $key=>$row){
            echo '    <div class="tr" id="'.$key.'">
        <div class="td" style="width:50px;">'.$key.'</div><div class="td" style="width:280px;">'.$row[0].'</div>
    </div>'.PHP_EOL;
            $i++;
            }
?> 
</div>
        <br/>
        <br/>
        <span class="check">Auto save<input value="1" name="autosave" id="autosave" type="checkbox"/></span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="save"><input type="button" value="save" id="save"/></span>
    </body>
</html>

config.json (contains data)

{"def":["item 2"],"abc":["item 5"],"jkl":["item 1"],"ghi":["item 4"],"mno":["item 3"]}

save.php (save new order with jQuery.post)

<?php

    function JSON2Array($path){
        $data=file_get_contents($path);
        if( !($ret=json_decode($data)) ){
            $ret=array();
        }
        return (array)$ret;
    }    

$path=$_POST['path'];
$order=$_POST['order'];

$tmpData=JSON2Array($path);

$newData=array();
foreach($order as $val){
    $newData[$val]=$tmpData[$val];
}

file_put_contents($path,json_encode($newData));
die(json_encode(array('msg'=>'saved!')));
?>

output image


Note: you should have jquery+1.6 and jquery-ui+1.10

share|improve this answer
add comment (requires an account with 50 reputation)

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.