You can get a bit closer using $.not()
$checked = $(checked);
$unchecked = $(unchecked).not($checked); // <== keeps all the checked stuff out of your not checked list
This will keep things at the front of the list, in the order they were checked. I believe this is what you are asking for, although it may not be what you end up wanting :)
Example fiddle
To me the UX is a bit of though as items with multiple categories checked don't push their way to the top of the list.
Heres a different version that uses sortData to help reorder the items. It uses the number of matching categories to bump things up in the list.
It doesn't remember the order of category selection though but thought I'd post as it may spur some other ideas.
Demo
Key changes:
Added a matchCount method that returns -1*numberOfMatches. This allows you to use the default ascending sort mode of Isotope and keeps Isotope from reversing the order of elements.
getSortData: {
matchCount: function ( $elem ) {
var count = 0;
$checkboxes.filter(':checked').each(function () {
if($elem.hasClass(this.name)) {
// Using a negative count here so we can use sort ascending
// Keeps things in a better order as isotope animates the changes
count--;
}
});
return count;
}
}
On each checkbox change, replaced the existing add/remove items with:
$container.isotope( 'updateSortData', $('.item'));
// Sort decending seems to simply reverse the sort so items reverse themselves
$container.isotope({ sortBy: 'matchCount'});//, sortAscending: false });
Update: added simple &&
logic to exclude items without ALL selected categories in .unpicked
:
Demo fiddle
Change to matchCount:
// Simple && check of all categories.
//
// Item must have all categories to be considered checked.
if((-count) && checkedItems.length === (-count)) {
$elem.removeClass('notpicked');
} else {
$elem.addClass('notpicked');
}