I would like to build a generic CSV viewer with DataTables.
"generic" means that it should be capable to read any CSV acquired externally and represent into a Jquery DataTables
I'm starting from a JSON structure (obtained after CSV parsing) and defining this table:
Name | Surname | Age |
---|---|---|
Stefano | Rxxxx | 45 |
Test | Dummy | 50 |
I would then like to show as Jquery DataTables (https://datatables.net/) but it's not clear why I cannot reach my goal:
$(function() {
data = [
{"Name":"Stefano","Surname":"Rxxxx","Age":"45"},
{"Name":"Test","Surname":"Dummy","Age":"50"}
]
columns = [];
$.each(data[0], function(k, v) {
$('#example > thead > tr').append("<td>" k "</td>");
columns.push(k);
});
console.log(columns);
$('#example').DataTable({
data: data,
columns: columns
});
});
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.12.1/css/jquery.dataTables.min.css"/>
<script src="https://code.jquery.com/jquery-3.6.1.js"></script>
<script src="https://cdn.datatables.net/1.12.1/js/jquery.dataTables.min.js"></script>
<table id='example' class='display'>
<thead><tr></tr></thead>
</table>
On consolle I have:
- a WARNING
jquery.min.js:2 jQuery.Deferred exception: Cannot use 'in' operator to search for 'length' in Name TypeError: Cannot use 'in' operator to search for 'length' in Name
- an ERROR
jquery.min.js:2 Uncaught TypeError: Cannot use 'in' operator to search for 'length' in Name
...but it's not clear to me what's wrong or missing in my code to translate a JSON table into a JQUERY DataTables.
Any help is appreciated.
CodePudding user response:
Your columns structure is not a valid DataTables structure for columns. It needs (in your case) to define the title
and the data
options each column needs to use.
If you change your JavaScript to build that structure, you can use columns: columns successfully (no other changes needed).
You can re-arrange your logic which builds columns
as follows:
$.each(data[0], function(k, v) {
columns.push({ title: k, data: k });
});
This builds the following output:
[ { title: 'Name', data: 'Name' }, { title: 'Surname', data: 'Surname' }, { title: 'Age', data: 'Age' } ]
Demo:
$(function() {
data = [{
"Name": "Stefano",
"Surname": "Rxxxx",
"Age": "45"
},
{
"Name": "Test",
"Surname": "Dummy",
"Age": "50"
}
]
columns = [];
$.each(data[0], function(k, v) {
columns.push({
title: k,
data: k
});
});
$('#example').DataTable({
data: data,
columns: columns
//columns: [ { title: 'Name', data: 'Name' }, { title: 'Surname', data: 'Surname' }, { title: 'Age', data: 'Age' } ]
});
});
.display {
margin-top: 20px;
}
<head>
<meta charset="UTF-8">
<title>Demo</title>
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.12.1/css/jquery.dataTables.min.css" />
<script src="https://code.jquery.com/jquery-3.6.1.js"></script>
<script src="https://cdn.datatables.net/1.12.1/js/jquery.dataTables.min.js"></script>
</head>
<body>
<table id='example' class='display'></table>
</body>
CodePudding user response:
You can map the first object's keys to get your columns, and you can map the data to get an array of arrays, which is what DataTables expects.
$(function() {
const data = [{
"Name": "Stefano",
"Surname": "Rxxxx",
"Age": "45"
},
{
"Name": "Test",
"Surname": "Dummy",
"Age": "50"
}
];
// get the first object's keys and dump them into an array of objects
const columns = Object.keys(data[0]).map(i => ({title: i}));
// get the values from each data object and add it to a new array of arrays
const formattedData = data.map(i => Object.values(i));
$('#example').DataTable({
data: formattedData,
columns: columns
});
});
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.12.1/css/jquery.dataTables.min.css" />
<table id='example' class='display'></table>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.datatables.net/1.12.1/js/jquery.dataTables.min.js"></script>