0

I'm trying to sort an array of list elements in IE8 like this:

function comparator(params) {
    var keepSelectedOnTop = params.keepSelectedOnTop;

    return function (a, b) {    // a, b are DOM objects
        a = $(a);  // wrap with jQuery
        b = $(b);

        if (keepSelectedOnTop) {
            if (a.is(".selected") && !b.is(".selected")) {
                return -1;
            } else if (!a.is(".selected") && b.is(".selected")) {
                return 1;
            }
        }

        return a.text().localeCompare(b.text());
    }
}

// ...

var items = $("ul li").detach().toArray();

items.sort(comparator(params));

This works for small lists, but when I have many elements I get an undefined is null or not an object error. When I break on the exception with the debugger b is undefined after the assignment.

Did anyone encounter this before? It works fine in other browsers and it seems perfectly valid JS.

P.S. the jQuery version is 1.7.2

  • which version of jQuery are you using? jQuery 2.0 doesn't support IE8. share the code where you're collecting DOM elements in `a` and `b` – painotpi Jun 20 '13 at 10:51
  • @badZoke the jQuery version is 1.7.2. The `a` and `b` parameters are populated during the execution of `Array.prototype.sort` which calls the comparator. –  Jun 24 '13 at 14:29
  • Could you try to debug which values the `b` has before wrapping it (before the assignment)? (You might need to rename the parameters to see it) – Bergi Jun 24 '13 at 14:41
  • You are sorting a list of jquery objects so a and b are already jquery objects. Don't know if that will help with the problem. and look at: http://www.wrichards.com/blog/2009/02/jquery-sorting-elements/ or http://stackoverflow.com/questions/1134976/how-may-i-sort-a-list-alphabetically-using-jquery or http://james.padolsey.com/javascript/sorting-elements-with-jquery/ – Jacob Jun 24 '13 at 15:17
  • @Jacob: No. jQuery collections are lists of DOM elements, not of jQuery objects. – Bergi Jun 24 '13 at 15:38
  • Before assignment `b` holds an object of type `DispHTMLLIElement` and after it's `undefined`. –  Jun 24 '13 at 15:38

2 Answers2

1

Why sort?

var items = $("ul li")
items = [].concat(items.filter(".selected").toArray()
                  ,items.filter(":not(.selected)").toArray())
Jacob
  • 1,423
  • 16
  • 29
  • The list items have to be sorted first by their selected state and then by their labels. –  Jun 24 '13 at 14:51
  • Ah, I missed the localeCompare line. What is the html, so we can test? jsfiddle? – Jacob Jun 24 '13 at 15:11
0

After several trial & error attempts it seems that changing the assignments in the comparator solves the issue, but it doesn't make sense:

function comparator(params) {
    var keepSelectedOnTop = params.keepSelectedOnTop;

    return function (aDom, bDom) {
        var a = $(aDom), b = $(bDom);  // Use different vars for the wrappers

        if (keepSelectedOnTop) {
            if (a.is(".selected") && !b.is(".selected")) {
                return -1;
            } else if (!a.is(".selected") && b.is(".selected")) {
                return 1;
            }
        }

        return a.text().localeCompare(b.text());
    }
}

For some reason the above works, but the initial version where I reassigned different values to the parameters doesn't.

  • This seems like another IE8 easter egg. Nevertheless the error doesn't reproduce after changing the assignment. –  Jun 28 '13 at 19:44