I've been trying to implement this script which pulls values from another page and sorts them into a table alphabetically. The three values are Name - City - District. The script works perfectly. But on top of that, I would like the script to group the values by city. So instead of:
--Name -- City -- District --
Name1 -- London -- Kingsroad
Name3 -- London -- Westminster
Name4 -- Birmingham -- YardleyI'd like for it to be organized as below, with the city column spanning 2 columns.
------ Birmingham -----
Name4 -- Yardley
------ London -----
Name1 -- Kingsroad
Name3 -- Westminster
The script I've used to pull values is this:
var fhold =$("#List");
$.get("/memberlist", function(data) {
$('.mem-info',data).each(function(){
fhold.append($(this));
});
var items = fhold.children('.mem-info').get();
items.sort(function(a, b) {
return $(a).text().toUpperCase().localeCompare($(b).text().toUpperCase());
});
fhold.append(items);
});
});
Here's the HTML for the same:
<table id="List" ><tbody>
<tr> <td>Name</td> <td>City</td><td>District</td> </tr>
</tbody>
</table>
So again, so far, it works fine. But I want it to group by city. I've tried using this fix here (https://datatables.net/examples/advanced_init/row_grouping.html) but I believe it only works for static values. I've looked into grouping values dynamically but most fixes say that a click function is required.
Is there a way to do so without a click/event function? Any help would be appreciated. Much thanks!
CodePudding user response:
Use lodash's groupby method
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>
You can get a reference from following link lodash groupby-method
CodePudding user response:
You can do something like this:
var originalTable = null;
function groupBy(inx = 0) {
var table = $("#List");
if (originalTable == null) {
originalTable = table.clone();
} else {
table = $("#List").html(originalTable.html());
}
var rows = table.find("tbody tr");
table.find("tbody tr").remove();
table = $("#List");
$(`th:eq(${inx})`, table).hide();
$.each(rows, function() {
var v = $(`td:eq(${inx})`, this).text();
var l = $("td", this).length - 1;
if ($('tbody tr.' v, table).length == 0) {
$('tbody', table).append(`<tr ><td colspan="${l}">${v}</td></tr>`);
}
$(`td:eq(${inx})`, this).remove();
$('tbody tr.' v, table).after(this)
});
}
groupBy(0)
$(document).on("click", "#List thead th", function() {
groupBy($(this).index());
});
I've made it a bit more dynamic for you.
Demo
var originalTable = null;
function groupBy(inx = 0) {
var table = $("#List");
if (originalTable == null) {
originalTable = table.clone();
} else {
table = $("#List").html(originalTable.html());
}
var rows = table.find("tbody tr");
table.find("tbody tr").remove();
table = $("#List");
$(`th:eq(${inx})`, table).hide();
$.each(rows, function() {
var v = $(`td:eq(${inx})`, this).text();
var l = $("td", this).length - 1;
if ($('tbody tr.' v, table).length == 0) {
$('tbody', table).append(`<tr ><td colspan="${l}">${v}</td></tr>`);
}
$(`td:eq(${inx})`, this).remove();
$('tbody tr.' v, table).after(this)
});
}
groupBy(0)
$(document).on("click", "#List thead th", function() {
groupBy($(this).index());
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="List" >
<thead>
<tr>
<th>Name</th>
<th>City</th>
<th>District</th>
</tr>
</thead>
<tbody>
<tr>
<td>Name1</td>
<td>London</td>
<td>Kingsroad</td>
</tr>
<tr>
<td>Name3</td>
<td>London</td>
<td>Westminster</td>
</tr>
<tr>
<td>Name4</td>
<td>Birmingham</td>
<td>Yardley</td>
</tr>
</tbody>
</table>