1

I currently have a series of divs that are generated by our MVC app. I am attempting to sort by a variety of 'data-' attributes. I was able to group the items by an attribute called 'data-categoryname'.

Each item also has a 'data-categorysortorder' in which I want to sort the group that gets created by the 'data-categoryname' by that sort order value.

I have a JS Fiddle started, and have the groupings grouped, I now need help sorting the groups by category name by the 'category sort order'. Any help is appreciated.

https://jsfiddle.net/c0fawcnf/9/

//CURRENTLY HAVE GROUPING BY CATEGORY ITEM NAME AND WRAPPING EACH GROUP BY CATEGORY NAME, BUT NOW NEED TO SORT EACH CATEGORY WRAPPER BY THE ITEMS 'data-categorydisplayorder'

var $item = $('.item-box'),
   items = {};

$item.each(function () {
    items[$(this).data('categoryitemname')] = '';
});

for (category in items) {
    var categoryLowerCase = category.toLowerCase();
     $item.filter('[data-categoryitemname=' + category + ']').wrapAll('<div id="' + categoryLowerCase + '" class="categoryWrapper" data-wrappercategorydisplayorder="NEED_CATEGORY_DISPLAY_VALUE_HERE_AND_SORT_BY_THIS_VALUE"></div>');
    //return list;
    $('div#' + categoryLowerCase + '').prepend('<div class="page-title"><h1>' + category.replace("-", " ") + '</h1></div>');
}


// THESE ITEMS ARE OUTPUTTED BY AN MVC APPLICATION TO THE UI - I NEED TO SORT ON THE CLIENT SIDE BASED ON PARAMETERS

<div class="item-box" data-categoryitemname="Fall" data-itemsortorder="2" data-categorydisplayorder="2">Fall Item</div>
<div class="item-box" data-categoryitemname="Fall" data-itemsortorder="0"  data-categorydisplayorder="2">Fall Item</div>
<div class="item-box" data-categoryitemname="Fall" data-itemsortorder="1"  data-categorydisplayorder="2">Fall Item</div>

<div class="item-box" data-categoryitemname="Summer" data-itemsortorder="2"  data-categorydisplayorder="1">Summer Item</div>
<div class="item-box" data-categoryitemname="Summer" data-itemsortorder="1"  data-categorydisplayorder="1">Summer Item</div>
<div class="item-box" data-categoryitemname="Summer" data-itemsortorder="0"  data-categorydisplayorder="1">Summer Item</div>

<div class="item-box" data-categoryitemname="Winter" data-itemsortorder="2"  data-categorydisplayorder="3">Winter Item</div>
<div class="item-box" data-categoryitemname="Winter" data-itemsortorder="1"  data-categorydisplayorder="3">Winter Item</div>
<div class="item-box" data-categoryitemname="Winter" data-itemsortorder="0"  data-categorydisplayorder="3">Winter Item</div>

<div class="item-box" data-categoryitemname="Spring" data-itemsortorder="1"  data-categorydisplayorder="0">Spring Item</div>
<div class="item-box" data-categoryitemname="Spring" data-itemsortorder="2"  data-categorydisplayorder="0">Spring Item</div>
<div class="item-box" data-categoryitemname="Spring" data-itemsortorder="0"  data-categorydisplayorder="0">Spring Item</div>

I did a lot of searching on how to sort items, but found many that sorted elements in known element with an ID that exists on the page already. Since I am dynamically adding the groups to the DOM then sorting after the creation of the groups, I have not really found anything on how to do that.

UPDATE: I got the sort order value to attach to the group element. but the sort function I have is still not working. I updated my JS Fiddle

https://jsfiddle.net/c0fawcnf/12/

// CURRENTLY HAVE GROUPING BY CATEGORY ITEM NAME AND WRAPPING EACH GROUP BY CATEGORY NAME, BUT NOW NEED TO SORT EACH CATEGORY WRAPPER BY THE ITEMS 'data-categorydisplayorder'

var $item = $('.item-box'),
   items = {};

$item.each(function () {
    items[$(this).data('categoryitemname')] = '';
});

for (category in items) {
    var categoryLowerCase = category.toLowerCase();
     $item.filter('[data-categoryitemname=' + category + ']').wrapAll('<div id="' + categoryLowerCase + '" class="categoryWrapper" data-wrappercategorydisplayorder="NEED_CATEGORY_DISPLAY_VALUE_HERE_AND_SORT_BY_THIS_VALUE"></div>');
    //return list;
    $('div#' + categoryLowerCase + '').prepend('<div class="page-title"><h1>' + category.replace("-", " ") + '</h1></div>');

    // GET ITEM BOX DISPLAY ORDER PROPERTY AND ATTACH IT TO THE WRAPPER CATEGORY DISPLAY PROPERTY
    var elem = $('div#' + categoryLowerCase + ' .item-box');
    elem.parent().attr("data-wrappercategorydisplayorder", elem.data("categorydisplayorder"));
}


// ATTEMPT TO SORT - BUT NOT WORKING
$('.productCategoryWrapper').sort(sort_items).appendTo('#item-grid');

//IS THIS EVEN CORRECT?
 function sort_items(a, b) {
     console.log('we shall sort');
     return ($(b).data('wrappercategorydisplayorder')) < ($(a).data('wrappercategorydisplayorder')) ? 1 : -1;
}
4
  • Are you wanting to sort the groups by categorydisplayorder (so the output will be Spring-Summer-Fall-Winter) and also sort the items within each group by itemsortorder (the items within a group all have the same text so that bit is confusing) Commented Feb 24, 2017 at 21:44
  • Right now I am just wanting to sort the groups by 'categorydisplayorder' (so the output will be Spring-Summer-Fall-Winter). Commented Feb 24, 2017 at 21:47
  • OK - I updated your fiddle to do the sorting on items within one of the groups (before I understood exactly what you were wanting to do). In your case, you will need a container around the groups and when you create the container for each group, add a data-sortorder attribute so you can use it in a similar way. I'm about to take a break, but if you have not worked it out, I'll add an answer in an hour or so Commented Feb 24, 2017 at 22:05
  • @StephenMuecke. That is not exactly what I wanted, but sorting within the groups may be helpful in the future, but right now I need to update or sort the groups. I added an Update with an update to my Fiddle in my question where I was able to add the sort order to the group element from the children. But now I need to sort the group. So I have a function attempting to do that at this point. I will see if any of your sort code could help me with the group sorting. Commented Feb 24, 2017 at 22:11

2 Answers 2

1

I assume you will ultimately want to sort the items in each group by the data-itemsortorder value, then start by creating a function to sort all the items first by categorydisplayorder then by itemsortorder

function sort_items(a, b) {
    var ai = $(a).data('categorydisplayorder');
    var bi = $(b).data('categorydisplayorder');
    if (ai < bi) {
        return -1;
    } else if (ai > bi) {
        return 1;
    } else {
        ai = $(a).data('itemsortorder');
        bi = $(b).data('itemsortorder');
        if (ai < bi) {
            return -1;
        } else if (ai > bi) {
            return 1;
        } else {
            return 0;
        }
    }
}

and create a container element to insert the groups

<div id="container"></div>

Then the script to arrange the grouped and sorted items is

var groups = [];
var groupcontainer;
var items = $('.item-box');
var sorted = items.get().sort(sort_items); 
$.each(sorted, function (index, item) {
    var group = $(item).data('categoryitemname');
    if (groups.indexOf(group) == -1) {
        groups.push(group);
        var title = $('<div></div>').addClass('page-title').html($('<h1></h1>').text(group));
        groupcontainer = $('<div></div>').addClass('categoryWrapper');
        groupcontainer.append(title);
        $('#container').append(container);
    }
    container.append(item);
});

Refer fiddle

Sign up to request clarification or add additional context in comments.

Comments

0

SOLVED IT

The way I needed it to. In case anyone else is interested. Here is the solution.

https://jsfiddle.net/c0fawcnf/14/

HTML

  <!--THESE ITEMS ARE OUTPUTTED BY AN MVC APPLICATION TO THE UI - I NEED TO SORT ON THE CLIENT SIDE BASED ON PARAMETERS-->
<div id="item-grid">


   <div class="item-box" data-categoryitemname="Fall" data-itemsortorder="2" data-categorydisplayorder="2">Fall Item</div>
   <div class="item-box" data-categoryitemname="Fall" data-itemsortorder="0"  data-categorydisplayorder="2">Fall Item</div>
    <div class="item-box" data-categoryitemname="Fall" data-itemsortorder="1"  data-categorydisplayorder="2">Fall Item</div>

  <div class="item-box" data-categoryitemname="Summer" data-itemsortorder="2"  data-categorydisplayorder="1">Summer Item</div>
   <div class="item-box" data-categoryitemname="Summer" data-itemsortorder="1"  data-categorydisplayorder="1">Summer Item</div>
    <div class="item-box" data-categoryitemname="Summer" data-itemsortorder="0"  data-categorydisplayorder="1">Summer Item</div>

  <div class="item-box" data-categoryitemname="Winter" data-itemsortorder="2"  data-categorydisplayorder="3">Winter Item</div>
   <div class="item-box" data-categoryitemname="Winter" data-itemsortorder="1"  data-categorydisplayorder="3">Winter Item</div>
    <div class="item-box" data-categoryitemname="Winter" data-itemsortorder="0"  data-categorydisplayorder="3">Winter Item</div>

  <div class="item-box" data-categoryitemname="Spring" data-itemsortorder="1"  data-categorydisplayorder="0">Spring Item</div>
   <div class="item-box" data-categoryitemname="Spring" data-itemsortorder="2"  data-categorydisplayorder="0">Spring Item</div>
    <div class="item-box" data-categoryitemname="Spring" data-itemsortorder="0"  data-categorydisplayorder="0">Spring Item</div>

</div>

JAVASCRIPT

//CURRENTLY HAVE GROUPING BY CATEGORY ITEM NAME AND WRAPPING EACH GROUP BY CATEGORY NAME, BUT NOW NEED TO SORT EACH CATEGORY WRAPPER BY THE ITEMS 'data-categorydisplayorder'

    var $item = $('.item-box'),
       items = {};

    $item.each(function () {
        items[$(this).data('categoryitemname')] = '';
    });

    for (category in items) {
        var categoryLowerCase = category.toLowerCase();
         $item.filter('[data-categoryitemname=' + category + ']').wrapAll('<div id="' + categoryLowerCase + '" class="categoryWrapper" data-wrappercategorydisplayorder=""></div>');
        //return list;
        $('div#' + categoryLowerCase + '').prepend('<div class="page-title"><h1>' + category.replace("-", " ") + '</h1></div>');

   //GET ITEM BOX DISPLAY ORDER PROPERTY AND ATTACH IT TO THE WRAPPER CATEGORY DISPLAY PROPERTY
 var elem = $('div#' + categoryLowerCase + ' .item-box');
//Give the parent element the category display value that is on the child item.
 elem.parent().attr("data-wrappercategorydisplayorder", elem.data("categorydisplayorder"));

    }

  //SORT 
function sort_items(a, b) {
    console.log('we shall sort');
    var a1 = $(a).data('wrappercategorydisplayorder');
    var b1 = $(b).data('wrappercategorydisplayorder');
    return a1 < b1 ? -1 : 1;
}

var ff = $('.categoryWrapper').get().sort(sort_items);

$.each(ff, function(index, item){
    $(this).appendTo('#item-grid');
});

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.