views:

32

answers:

1

Introduction:

Hello Everyone,

I have been looking for days for a way to extend the attached JavaScript code so that it will work as I need it to and have asked on various coding website but nobody seems to know the answer so in a last chance effort I have come here in the hopes that someone will be able to assist me.

About the script:

When ran, the script below will allow you sort (by dragging and dropping) a group of items from a list and the order of those items will then be saved to a cookie allowing you to refresh the page leaving the sort order intact.

The Problem

The problem with the attached script is that it only works for 1 list and adding an additional list to the page will not work. (the items in the other list cannot be sorted or saved in anyway).

The Request:

I would like to be able to extend the script so that it will sort more than 1 list and save the order for all of the list to a cookie (be it one cookie for all or separate cookies for each list this part does not matter) and to make things as simple as possible I should note that to I do not need to mix items between the list I just need to sort the items in each list independently and then save / restore the order of each list in a cookie.

Closing Statement:

Finally I just want to say that I am fairly new to the world of JavaScript programming so the more assistance you can provide the better but it goes without saying that any and all replies will be greatly appreciated.

Thanks, Dave

The JavaScript:

// set the list selector
var setSelector = "#list1";
// set the cookie name
var setCookieName = "listOrder";
// set the cookie expiry time (days):
var setCookieExpiry = 7;

// function that writes the list order to a cookie
function getOrder() {
    // save custom order to cookie
    $.cookie(setCookieName, $(setSelector).sortable("toArray"), { expires: setCookieExpiry, path: "/" });
}

// function that restores the list order from a cookie
function restoreOrder() {
    var list = $(setSelector);
    if (list == null) return

    // fetch the cookie value (saved order)
    var cookie = $.cookie(setCookieName);
    if (!cookie) return;

    // make array from saved order
    var IDs = cookie.split(",");

    // fetch current order
    var items = list.sortable("toArray");

    // make array from current order
    var rebuild = new Array();
    for ( var v=0, len=items.length; v<len;>
        rebuild[items[v]] = items[v];
    }

    for (var i = 0, n = IDs.length; i &lt; n; i++) {

        // item id from saved order
        var itemID = IDs[i];

        if (itemID in rebuild) {

            // select item id from current order
            var item = rebuild[itemID];

            // select the item according to current order
            var child = $("ul.ui-sortable").children("#" + item);

            // select the item according to the saved order
            var savedOrd = $("ul.ui-sortable").children("#" + itemID);

            // remove all the items
            child.remove();

            // add the items in turn according to saved order
            // we need to filter here since the "ui-sortable"
            // class is applied to all ul elements and we
            // only want the very first!  You can modify this
            // to support multiple lists - not tested!
            $("ul.ui-sortable").filter(":first").append(savedOrd);
        }
    }
}

// code executed when the document loads
$(function() {
    // here, we allow the user to sort the items
    $(setSelector).sortable({
        axis: "y",
        cursor: "move",
        update: function() { getOrder(); }
    });

    // here, we reload the saved order
    restoreOrder();
});

An Example Html Page:

<!DOCTYPE html>
<html>
 <head>
  <title></title>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"&gt;&lt;/script&gt;
    <script type="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.2/jquery-ui.min.js"&gt;&lt;/script&gt;
    <script type="text/javascript" src="jquery.cookie.js"></script>

 </head>

  <body>
   <ul id="list1">
    <li id="item-1">List Item 1</li>
    <li id="item-2">List Item 2</li>
    <li id="item-3">List Item 3</li>
    <li id="item-4">List Item 4</li>
    <li id="item-5">List Item 5</li>
    <li id="item-6">List Item 6</li>
   </ul>
  </body>
</html>
A: 

setSelector is assigned '#list1' and never changed at least in the script you posted. Also, the cookie value you use only holds the sorting order of a single list. Basically it seems your script is hardcoded to only work on one specific element; ul#list1

Try wrapping your JS code in a function like so:

function sorter(setSelector, setCookieName) {

  /* code */

  $(setSelector).sortable({ /* parameters */});

  restoreOrder();

}

Then for each list on your page call the sorter function with the desired id and cookie name as parameters:

$(document).ready(function() {
  sorter('#list1', 'listOrder-list1');
  sorter('#list2', 'listOrder-list2');
  //etc...
});

However there are some issues with your code that need fixing. For one, you are using ids where classes should be used on the li elements in the ul list. Ids are supposed to be unique within a webpage. Adding additional lists which use those same ids to specify order breaks that assumption. Change those ids to classes and replace '#' with '.' in selectors referring to them.

A bigger issue I think is the selector you are using to get the parent ul element. $("ul.ui-sortable") would grab every <ul class="ui-sortable"> element. Instead, use the already defined list variable in place of $("ul.ui-sortable")

Hope some of this helps...

MooGoo
Thanks for the response it is much more than I have been given from other sites and to be honest the script is not mine. I just found it a few days ago at this site. http://www.shopdev.co.uk/blog/sortable-lists-using-jquery-ui/ and tried to figure out how to get it to work like I wanted. I will definitely to add your suggestions if I run into any problems I hope it will be ok to ask further questions. Thanks again.
Dave Keltz
Update: I followed your instructions (including the changing of ids to classes for the li elements and changed the code to use the list variable instead of $("ul.ui-sortable") and it worked flawlessly. Thank you very much for your help and if I could I would send you some money for your help but I cannot, what I will do however is add your site (http://bigmooworld.com/) to our sites external links section on the frontpage if you would like. Right now we get around 35,000 unique hits per month so it may be better than money in the end.
Dave Keltz
Link away if you want, but my homepage is currently just a shell for some future website idea that I have not thought of yet. Currently it is just a happy frog image. You could link to http://bigmooworld.com/mblog which is a blogish page that I never post on, though I cannot guarantee it's SFWness. Or not at all, good will is payment enough for me.
MooGoo