I have a sort function which uses data-attributes to re-arrange the items
in the list
for each table
. The problem with my code is that if the value of the data-head
isn't the same for each list the sort breaks down and appends all of the second column items into the same list.
In this example when I click Price or Size, both types items are appended to each list even though they have a different data-status
.
How do I change the sort to only apply to each table
when the data-sort
matches the data-head
?
var keys = [...$(".table .btn")].map((i) => $(i).text());
var arr = [...$(".list .item")].map((i) => {
var data = $(i).find("[data-sort]");
var obj = {};
for (let id = 0; id < data.length; id++) {
obj[keys[id]] = data.eq(id).text();
obj.line = $(i)[0].outerHTML;
}
return obj;
});
//console.log("arr", arr);
var lastkey = -1;
$(".table .btn").on("click", function() {
var keytosort = keys[Number($(".table .btn").index(this))];
var desc = true;
if (keytosort == lastkey) {
desc = true;
lastkey = -1;
} else {
desc = false;
lastkey = keytosort;
}
arr = arr.sort((a, b) => {
if (a[keytosort].startsWith("$")) {
let an = a[keytosort].substring(1); //put off $
let bn = b[keytosort].substring(1);
return Number(an) - Number(bn);
} else {
return a[keytosort].localeCompare(b[keytosort]);
}
}); //end sort
if (desc) arr = arr.reverse();
//recreate the different items
$(".list").children().remove();
for (let i = 0; i < arr.length; i++) {
$(".list").append(arr[i].line);
}
});
.list {
display: flex;
flex-direction: column;
}
.item,
.header {
display: flex;
}
.btn {
cursor: pointer;
}
[data-sort] {
border: 1px solid;
padding: 10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="table">
<div class="header">
<div class="btn" data-head='country'>Country</div>
<div class="btn" data-head='price'>Price</div>
</div>
<div>
<div class="list">
<div class="item">
<div data-sort="country">France</div>
<div data-sort="price">$25</div>
</div>
<div class="item">
<div data-sort="country">Spain</div>
<div data-sort="price">$30</div>
</div>
</div>
</div>
</div>
<div class="table">
<div class="header">
<div class="btn" data-head='country'>Country</div>
<div class="btn" data-head='type'>Size</div>
</div>
<div>
<div class="list">
<div class="item">
<div data-sort="country">France</div>
<div data-sort="type">small</div>
</div>
<div class="item">
<div data-sort="country">spain</div>
<div data-sort="price">large</div>
</div>
</div>
</div>
</div>