views:

345

answers:

3

hello there - i'm trying to have 3 levels of lists all of which are sortable & draggable into each other. Basically trying to set up an easy way to manage navigation menus with multiple levels.

Its 90% there but for some reason it wont save an item into a child list. It just seems to get the parent id of the list it came from?!

  • ie. a pink item into the 3rd(blue) level in the same green section.

However i can add an item to the same level list it cam from or to its parent.

a blue item can go to another blue item list or to the pink level?! AANd i've just noticed it does work if you drage a pink item into a pink section frm a different green section..!

http://oursite.modernactivity.co.uk/youradmin/indexNEW.php

any help appreciated! Dc.

$(function() {

    $("div.sortable").each(function(i){
        makeSortable("#"+$(this).attr("id"));   
        //$("#fdbk").append("<li>"+$(this).attr("id")+" </li>");

    });

});

function makeSortable(id) {

    $(id).sortable({
        connectWith: 'div.sortable',
        opacity: 0.9,
        distance: 15,
        placeholder: 'placeholder',
        helper:'clone',
        update : function(e, ui){
            serialize(id,'update');
            //$("#fdbk").append("<li>update from:"+$(id).attr("id")+" i am:"+$(id).attr("id")+"  </li>");
        },
        /*receive : function(e, ui){
            serialize(id,'receive');
            //$("#fdbk").append("<li>SORT from:"+$(id).attr("id")+" i am:"+$(id).attr("id")+ " i am:"+$(this).attr("id")+"  </li>");
        },
        sort : function(e, ui){
            serialize(id,'sort');
            //$("#fdbk").append("<li>SORT from:"+$(id).attr("id")+" i am:"+$(id).attr("id")+ " i am:"+$(this).attr("id")+"  </li>");
        }*/
    });

};  

function serialize(s,e) {
    var sortableLinks = $(s); 
    var parentID = sortableLinks.attr("name");
    $(sortableLinks).sortable();
    var data = $(s).sortable('serialize');

    $.ajax({
        url: "/youradmin/scripts/php/process.php",
        type: "POST",
        data: data+"&parentID="+parentID+"&reorderContent=1"            
    });
    $("#fdbk").html("");
    $("#fdbk").prepend("<li>event:"+e+"; idArray:"+data+" parent:<b>"+parentID+"</b> </li>");


};
A: 

It's messing up because you are using the same class for everything, it doesn't look if its a child or parent or what, it only sees if you drag a level 3 item to a level 1 list that the classes are the same and that it should be able to drag that item into that list. edit: I used source code from your website:

<html>
<head>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"&gt;&lt;/script&gt;
    <script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/jquery-ui.min.js"&gt;&lt;/script&gt;
<script type="text/javascript">     
    $(document).ready(function(){
        $('.level-1, .level-2, .level-3').sortable({
            update: function(e, ui) {
                update(ui.item);
            }
        });
    });  
    var id_prefix = "id_";
    function update(item) {         
        var parentID = $(item).parent().attr('id');
        var order = $('#'+parentID).sortable('serialize');
        parentID = parentID.substring(id_prefix.length);
    }
</script>
    <style type="text/css">
        .level-2 {background-color: lime;}
        .level-3 {background-color: #ff6fcf;}
        .level-4 {background-color: #6FF;}
        div {margin: 5px 0; min-height: 5px; padding: 10px;}
    </style>

</head>
<body>
<div id="id_master" class="level-1 list"> 
<div id="id_1017" class="level-2 list">x 1017</div> 
<div id="id_1020" class="level-2 list">y 1020   
        <div id="id_1041" class="level-3 list"> z 1041
            <div id="id_1030" class="level-4">i 1030</div> 
            <div id="id_1021" class="level-4">z 1021</div> 
            <div id="id_1032" class="level-4">iii 1032</div> 
        </div>      
        <div id="id_1018" class="level-3 list"> 1 1018  
            <div id="id_1029" class="level-4">2 1029</div> 
            <div id="id_1022" class="level-4">1 1022</div> 
        </div>  
</div>
<div id="id_1042" class="level-2 list">z 1042   
    <div id="id_1033" class="level-3 list"> iv 1033</div>       
</div>  

Your php code should then look something like this

<div id="id_0" class="level-1">
    <?
        $level1 = $select->getContentAssoc("","AND content.contentType='mainsection'",""); 
        foreach($level1 as $row1){
    ?>
    <div id="id_<?=$row1['contentAssocID']?>"  class="level-2"><?=$row1['title']?>
        <?
            $level2 = $select->getContentAssoc($row1['contentAssocID'],"AND content.contentType='mainsection'",""); 
            foreach($level2 as $row2){
        ?>
        <div id="id_<?=$row2['contentAssocID']?>" class="level-3"> <?=$row2['title']?> <?=$row2['contentAssocID']?>
                    <?
                        $level3 = $select->getContentAssoc($row2['contentAssocID'],"AND content.contentType='mainsection'",""); 
                        foreach($level3 as $row3){
                    ?>
                        <div id="id_<?=$row3['contentAssocID']?>" class="level-4"><?=$row3['title']?> <?=$row3['contentAssocID']?></div>
                    <? } ?>
        </div>
        <? } ?>
    </div>
<? } ?>

Note that I removed the name attributes, what do you need them for if the name is in the id?

Cornelis
isn't that exactly the same as; $("div.sortable").each(function(i){ makeSortable("#"+$(this).attr("id")); //$("#fdbk").append("<li>"+$(this).attr("id")+" </li>"); });the list is generate from a db so i wont know the exact ID of the list, and there will be multiple levels of level-3 lists in different sections.
daniel Crabbe
The point is that you need to make different levels of sortable by using unique identifiers, if you can write unique list-items by db-input, you should be able to write unique list with their items by db-input, can you give an example of the data you pull from the database ?
Cornelis
Somehow it seems I can't add comments if there are not made any other comments, so I hope you won't overlook my edited answer
Cornelis
A: 

cheers cornelis...

each item whether child or parent gets its unique id from the db;

<div id="master" name="0" class="sortable">

<?
$level1 = $select->getContentAssoc("","AND content.contentType='mainsection'",""); 
foreach($level1 as $row1){
?>

    <div name="<?=$row1['contentAssocID']?>" id="id_<?=$row1['contentAssocID']?>"  class="sortable"><?=$row1['title']?>

            <?
            $level2 = $select->getContentAssoc($row1['contentAssocID'],"AND content.contentType='mainsection'",""); 
            foreach($level2 as $row2){
            ?>

            <div name="<?=$row2['contentAssocID']?>" id="id_<?=$row2['contentAssocID']?>" class="sortable"> <?=$row2['title']?> <?=$row2['contentAssocID']?>


                        <?
                        $level3 = $select->getContentAssoc($row2['contentAssocID'],"AND content.contentType='mainsection'",""); 
                        foreach($level3 as $row3){
                        ?>

                            <div id="id_<?=$row3['contentAssocID']?>"><?=$row3['title']?> <?=$row3['contentAssocID']?></div>


                        <? } ?>


            </div>

            <? } ?>

    </div>

<?
}
?>

kinda thought i just need to be able to grab the id of something when its dropped and then call serialise() on its parent?

daniel Crabbe
cheers! i've had a look but them ain problem with defining which class something is we'll have to add/remove the classes when an item changes from level2 to level3 etc...just looking at ui.item, ui. sender and might just try and grab the parent like that...
daniel Crabbe
A: 

this seems to work!

$(function() {

    $("div.sortable").each(function(i){
        makeSortable("#"+$(this).attr("id"));   

    });


});

function makeSortable(id) {

    $(id).sortable({
        connectWith: 'div.sortable',
        opacity: 0.9,
        distance: 15,
        placeholder: 'placeholder',
        helper:'clone',
        cursor: 'move', 
        update : function(e,ui){
            //serialize(id,e,ui);
        },

        receive:function(e,ui){
            serialize(id,e,ui);
        }
        ,
        sort : function(e, ui){
            //serialize(id,e,ui);
        },
        stop : function(e, ui){
            serializeOnStop(id,e,ui);
        }
    }).disableSelection();

};  

function serialize(s,e,ui) {
    var sortableLinks = $(s); 
    var parentID = sortableLinks.attr("name");
    $(sortableLinks).sortable();
    var data = $(s).sortable('serialize');

    $.ajax({
        url: "/youradmin/scripts/php/process.php",
        type: "POST",
        data: data+"&parentID="+parentID+"&reorderContent=1"            
    });

    $("#fdbk").prepend("<li>event:"+e.type +" data:"+data+" parentID:"+parentID+" s;"+sortableLinks.attr("id")+" </li>");

};

function serializeOnStop(s,e,ui) {
    var item = ui.item;
    var newParent = $("#"+item.attr('id')).parent('div');

    var sortableLinks = $(s); 
    var parentID = newParent.attr("id").split("_");
    $(newParent).sortable();
    var data = $(newParent).sortable('serialize');

    $.ajax({
        url: "/youradmin/scripts/php/process.php",
        type: "POST",
        data: data+"&parentID="+parentID[1]+"&reorderContent=1"            
    });

    $("#fdbk").prepend("<li>event:"+e.type +" data:"+data+" parentID:"+parentID[1]+" s;"+sortableLinks.attr("id")+" newParent:"+newParent+"  </li>");


};
daniel Crabbe