Using hrefs to filter DataTables data
Using hrefs to filter DataTables data
I have a categories list and a documents table and both are populated with local JSON data. Each category item corresponds to a document (some documents have multiple categories), and I want to make it so that clicking on a category will filter its documents in the table. For now the categories are href'd but don't do anything.
Since the documents are housed in a DataTable and rendering the categories did not use DataTables, I'm not sure how I would proceed with getting both to work with one another.
I've included a JS snippet below. I haven't been able to get the table to display with JS Fiddle properly, so if you'd like to see the HTML then let me know.
JS snippet:
import $ from 'jquery';
import JSONfile from '../../../public/JSONfile.json';
import { basename } from 'path';
import dt from 'datatables.net';
var categories = '';
var tableRes = '';
export default class {
constructor() {
this.loadData();
this.loadTableData();
}
Loading the categories:
loadData() {
let res = JSONfile.d.results.filter(function(val) {
return (val.FileLeafRef.trim().length > 0);
}).map(function(obj) {
return {
"FileName": obj.FileLeafRef,
"Path": obj.EncodedAbsUrl,
"Categories": obj.ResourceType.results.map(function(val) {
return val.Label;
}).join(";")
};
});
JSONfile.d.results.filter(function(val) {
return (val.FileLeafRef.trim().length > 0);
}).map(function(obj) {
return obj.ResourceType.results.map(function(val) {
return val.Label;
})
});
Showing each Category once:
let unique = {};
let temp = JSONfile.d.results.filter(function(val) {
return (val.FileLeafRef.trim().length > 0);
}).forEach(function(obj) {
obj.ResourceType.results.forEach(function(val) {
unique[val.Label] = true;
})
});
let categories = Object.keys(unique).sort();
Turning Categories into hrefs and adds them to .indiv-label
$(".indiv-label").html(categories.join("<br>"))
.contents().each(function() {
if (this.nodeType == 3) {
let elem = $("<a>", {
href: "#" + this.nodeValue ///// ---------------------- Not sure what url to put where the # is
});
$(this).wrap(elem)
}
});
} // ------------- loadData()
Loading the table
loadTableData() {
$.noConflict();
let tableRes = JSONfile.d.results.filter(function(val) {
return (val.FileLeafRef.trim().length > 0);
}).map(function(obj) {
return {
"Path": obj.EncodedAbsUrl,
"Titles": obj.File.Name,
"Categories": obj.ResourceType.results.map(function(val) {
return val.Label;
}).join(";"),
"Blank": ''
}
});
$('#km-table-id').DataTable( {
columns: [
{ data: "Titles" },
{ data: "Categories" } // hidden col-3 categories
],
columnDefs: [
{
data: "Path",
render: function(data, type, row) {
return $('<a>')
.attr({target: "_blank", href: row.Path})
.text(data)
.wrap('<div></div>')
.parent()
.html();
},
targets: 0
},
{ searchable: true, targets: [1], visible: false },
],
data: tableRes,
language: { searchPlaceholder: "Search All Documents" },
lengthMenu: [ 10, 25, 50, 100, 250, 500 ],
order: [],
// pageLength: 500,
paging: true,
pagingType: "full_numbers",
responsive: true,
scrollCollapse: true,
scrollX: true,
scrollY: 450,
stateSave: true
});
} // ------------------ loadTableData
} // ------------- export default class
Answers
Thats a lot of code to look through. An example would be good. However it sounds like you are trying to implement a select input search, correct?
If so then this example may help you get started.
https://datatables.net/examples/api/multi_filter_select.html
This example is placing the select inputs in the footer. But you can place the categories input anywhere you want. The basic code will show you how to build the select list and how to execute the search when an option is selected.
Kevin
Hi @kthorngren ,
I have a list that's made up of JSON data---I want it so that someone clicks on a list item and the DataTable is updated to only show the documents that correspond with each list item.
For example, if I click on the list item "Fruit" the table will update to show "Apples, Bananas, Kiwis" and it will hide "Yellow Rollerskates." But if I click on "Yellow Objects" the table will show "Bananas, Yellow Rollerskates." In other words some documents are listed under multiple categories.
Based on what you're saying and the link you provided, do you think it would it be possible to convert the Select/Drop Down into a regular list (that's still populated by my JSON data), which can then be clicked on to filter the data? Thanks!
How do you want to present this list? Select (maybe select multiple), checkboxes, etc.
What does this data structure look like in your Datatable?
For example:
or:
Or something different?
You should be able to create a custom search function or maybe a Search Plugin to perform the search you want. These examples aren't exactly what you want but maybe they are enough to get you going.
They are the same search using checkboxes except one uses a function and the other is a search plugin:
Function:
http://live.datatables.net/vipifute/1/edit
Plugin:
http://live.datatables.net/rosahuka/1/edit
To create an example for us to help you with just use your fruit and color example. The example doesn't need all the complexity of your above code. It just needs to represent the data structures you have.
Kevin
Quick update: I looked at your link showing the checkboxes example, and it could work.
Hi Kevin,
The list is just an ordered list of items with each one acting as a link.
I've included a snippet of the JSON data below. Every Document/Name can have multiple Categories/Labels.
I've been able to render the Labels as a list into one div and the Names into a DataTable.