3
\$\begingroup\$

You can see each list item has multiple attributes data-whatever. The user will choose from a dropdown box on how things should be sorted and the appropriate method is called. Is eval() the most appropriate choice for this or is there a better way?

$('#sort-options').change(function() {
    var sortType = $(this).val();
    var $selectedList = $($(".drop-zone.ui-tabs-selected a").attr('href')).find('.connectedSortable');
    var $listItems = $('li', $selectedList);

    //Sort
    var sortFunction = null;
    switch (sortType) {
    case 'custom': 
        $listItems.sort(sortCustom);
        break;
    case 'breed':
        $listItems.sort(sortBreed);
        break;
    case 'hatch':
        $listItems.sort(sortHatch);
        break;
    case 'laid':
        $listItems.sort(sortLaid);
        break;
    default:
        $listItems.sort(sortCustom);
    }

    //Empty UL
    $selectedList.empty();
    //Repopulate UL
    $.each($listItems, function(index, $listItem) {
        $selectedList.append($listItem);
    });
    });

    function sortCustom(a, b) {
    return $(a).attr('data-sort-order') - $(b).attr('data-sort-order');
    }

    function sortBreed(a, b) {
    return $(a).attr('data-breed') - $(b).attr('data-breed');
    }

    function sortHatch(a, b) {
    return $(a).attr('data-hatch') - $(b).attr('data-hatch');
    }

    function sortLaid(a, b) {
    return $(a).attr('data-laid') - $(b).attr('data-laid');
    }

    //Force initial sort
    $('#sort-options').trigger('change');
}
\$\endgroup\$
1
  • \$\begingroup\$ as a note, avoid calling jquery in your sort method. this will greatly slow down the sort process.... return $(a).attr('data-breed') - $(b).attr('data-breed'); can be replaced with return a.getAttribute('data-breed') - b.getAttribute('data-breed'); which is 10X faster. \$\endgroup\$ Commented Apr 11, 2012 at 14:16

2 Answers 2

1
\$\begingroup\$

If you define the sort function inline as an anonymous function, you can use a local variable to determine the attribute to sort on like this:

$('#sort-options').change(function() {
    var sortType = $(this).val(), sortAttribute;
    if (sortType == "custom") {
        sortAttribute = "data-sort-order";
    } else {
        sortAttribute = "data-" + sortType;
    }
    var $selectedList = $($(".drop-zone.ui-tabs-selected a").attr('href')).find('.connectedSortable');
    var $listItems = $('li', $selectedList);

    $listItems.sort(function(a, b) {
        return a.getAttribute(sortAttribute) - b.getAttribute(sortAttribute);
    });
}
\$\endgroup\$
2
\$\begingroup\$
function makeSorter(sortType) {
    sortType = "data-"+sortType;
    return function (a, b) {
        return $(a).attr(sortType) - $(b).attr(sortType);
    };
}

$('#sort-options').change(function () {
    var sortType = $(this).val();
    var $selectedList = $($(".drop-zone.ui-tabs-selected a").attr('href')).find('.connectedSortable');
    var $listItems = $('li', $selectedList);

    $listItems.sort(makeSorter(sortType));

Note that if val is "custom" it won't work, so I recommend replacing "custom" with "sort-order".

\$\endgroup\$
2
  • \$\begingroup\$ Ultimately used jfriend's method but this was useful to me as I didn't know you could return functions in JS. Thanks for the response! \$\endgroup\$ Commented Apr 11, 2012 at 16:44
  • \$\begingroup\$ @Omar functions behave like any other object in javascript. The only unique thing about them is that they can be called. You can return them, pass them as arguments, assign them to a variable and so on. \$\endgroup\$ Commented Apr 11, 2012 at 16:46

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.