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\$
    – rlemon
    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\$
    – Omar
    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\$
    – Esailija
    Apr 11, 2012 at 16:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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