I am quite new to Javascript, I am working to extend pieces of code implemented by third parts and I have to fill in a table with data using DataTables.
This table is made up of 3 columns: "nested field", "subfields blacklist", "edit", and when filled in with data should look like this:
The data to be filled in columns "nested field" and "subfields blacklist" come from the columns "nested field" and "subfields" of a Postgres database table defined as:
CREATE TABLE testing_nested_field_blacklist (
id SERIAL NOT NULL UNIQUE,
nested_field varchar(100) NOT NULL UNIQUE,
subfields varchar(100)[]
);
while data from "id" column is not needed in the html table.
However, I am making some mistakes with Datatables and getting these two error popups when loading the html page (as I click "ok" on the first one, the latter pops up).
DataTables warning: table id=NestedFieldTable - Requested unknown parameter 'nested_field_name' for row 0, column 0. For more information about this error, please see http://datatables.net/tn/4
Note that at this point the table has only one row and not even the "edit" colums is populated with data (this column will be the only one to be successfully populated with data when I close the two error pop-ups).
DataTables warning: table id=NestedFieldTable - Requested unknown parameter 'nested_field_name' for row 0, column 0. For more information about this error, please see http://datatables.net/tn/4
Note that the error message is exactly the same both times.
Here is the html template:
<!-- Topbar Search -->
<form class="d-none d-sm-inline-block form-inline mr-auto ml-md-3 my-2 my-md-0 mw-100 navbar-search">
<div class="input-group">
<input type="text" class="form-control bg-light border-0 small" placeholder="Search for..." aria-label="Search" aria-describedby="basic-addon2">
<div class="input-group-append">
<button class="btn btn-primary" type="button">
<i class="fas fa-search fa-sm"></i>
</button>
</div>
</div>
</form>
<!-- Topbar Navbar -->
<ul class="navbar-nav ml-auto">
<div class="topbar-divider d-none d-sm-block"></div>
<li class="nav-item">
<a class="nav-link text-black-50" href="#" data-toggle="modal" data-target="#logoutModal">
<i class="fas fa-sign-out-alt mr-2"></i>
<span>Logout</span>
</a>
</li>
</ul>
</nav>
<!-- End of Topbar -->
<!-- Begin Page Content -->
<div class="container-fluid">
<ol class="breadcrumb shadow-lg">
<li class="breadcrumb-item">
<a href="/4testing/">Home</a>
</li>
<li class="breadcrumb-item active">Nested fields and subfields blacklists</li>
</ol>
<!-- alert messages -->
<div class="alert alert-success alert-dismissible fade show" role="alert">
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
<strong id="alert-success-title"></strong> <div id="alert-success-detail"></div>
</div>
<div class="alert alert-danger alert-dismissible fade show" role="alert">
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
<strong id="alert-danger-title"></strong> <div id="alert-danger-detail"></div>
</div>
<!-- TABELLA NESTED FIELDS -->
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary"><i class="fas fa-ban" aria-hidden="true"></i> Nested fields and subfields blacklists</h6>
</div>
<div class="card-body">
<div class="table-responsive">
<table class="table table-bordered table-hover" id="NestedFieldTable" width="100%" cellspacing="0">
</table>
</div>
</div>
</div>
Here is the Javascript to fill in the table with data:
var NestedFieldTable;
$(document).ready(function() {
// NESTED FIELD
NestedFieldTable = $('#NestedFieldTable').DataTable({
"destroy": true,
"processing":true,
"ajax": {
"url": '/getNestedFields/',
"type":"POST",
"dataSrc": "nested_field"
},
"columns": columns_nested_field,
"columnDefs": [
{"targets": -1, "data": null, "defaultContent": "<i class='fas fa-edit' aria-hidden='true' id='modifyRow' data-toggle='modal' data-target='#myModalEditNestedField' title='Clicca per modificare il nested field o la blacklist'></i><i style='margin-left:15px;' class='fas fa-trash' aria-hidden='true' id='deleteRow' data-toggle='modal' data-target='#myModalDeleteNestedField' title='click top delete nested field and blacklist'></i>", "width": "75px"},
],
"dom": "<'row'<'col-md-6 toolbar_nestedfield'><'col-md-6'fBl>>" +
"<'row'<'col-md-6'><'col-md-6'>>" +
"<'row'<'col-md-12't>><'row'<'col-md-12'pi>>",
"buttons": [
{
extend: 'collection',
text: 'Export',
autoClose: true,
buttons: [
{
text: '<i class="fas fa-print"></i> Print',
extend: 'print',
messageTop: 'Table of nested fields and subfields blacklist.',
footer: false
}
]
},
{
text: '<i class="fas fa-sync-alt"></i>',
titleAttr: 'Refresh table',
action: function ( e, dt) {
dt.ajax.reload();
set_alert_message({"title":"Refresh", "detail":"Table successfully refreshed"}, "success");
}
}
],
"language": {
"searchPlaceholder": "Search",
"search": "<div class='form-group'><div class='input-group'><div class='input-group-prepend'><span class='input-group-text'><i class='fas fa-search fa-fw'></i></span></div>_INPUT_</div></div>",
"lengthMenu": "<div class='form-group'><div class='input-group'><div class='input-group-prepend'><span class='input-group-text'><i class='fas fa-list-ul fa-fw'></i></span></div>_MENU_</div></div>",
"oPaginate": {
sNext: '<span class="pagination-default">❯</span>',
sPrevious: '<span class="pagination-default">❮</span>'
}
}
});
$(".toolbar_nestedfield").html('<button type="button" class="dt-button" title="Click to add a new nested field and blacklist" data-toggle="modal" data-target="#myModalAddNestedField"><i class="fas fa-plus"></i></button>');
...
});
And here is the javascript defining the content of the columns:
var columns_nested_field = [
// { "title":"ID", data: "nested_field_blacklist_id"},
{ "title":"Nested field", data: "nested_field_name"},
{ "title":"Subfields blacklist", data: "nested_field_blacklist"},
{ "title":"Edit", "orderable": false, "className": 'icon_dt_style'}
];
Note that the last part of html code, headed by
<!-- POPUP ADD ROW NESTED FIELD AND BLACKLIST -->
is a modal that allows the user to insert new data into the database table, and it correctly works, except for the fact that the new data is not displayed in the html table (as it is not displayed the ones already existing in the db).
What am I doing wrong? How can I fix it?
the url /getNestedFields/
in the js code made to populate the html table is bounded to class extractNestedFields
via tornado web framework in this way:
application = tornado.web.Application([
...
(r"/getNestedFields/", extractNestedFields),
...
])
where class extractNestedFields
iis defined as:
class extractNestedFields(BaseHandler):
@gen.coroutine
def post(self):
dictionary_nested_field = {}
rows = yield testing_database.get_nested_fields()
print(rows) #ok
if len(rows) > 0:
dictionary_nested_field["nested_field"] = rows
else:
dictionary_nested_field["nested_field"] = []
raise gen.Return(self.write(json.dumps(dictionary_nested_field, default=myconverter)))
and when loading the html page, the content of rows
is:
[
{'nested_field': '1', 'subfields': ['one', 'two', 'three']},
{'nested_field': '2', 'subfields': ['one', 'two', 'three', 'coming from the backend']},
{'nested_field': '3rd_nested_field', 'subfields': ['jret_subfield_1.3', 'jret_subfield_2.3', 'jret_subfield_3.3']},
{'nested_field': '5', 'subfields': ['one', 'two', 'three', 'coming from the backend']},
{'nested_field': 'jret', 'subfields': ['jret_subfield_1.1', 'jret_subfield_2.1', 'jret_subfield_3.1']}
]
that is the content of my table in the db.
SOLVED
The key data
inside each {}
element of columns_nested_field
variable
(which is necessary to define the title and the data that one wants to fill in the columns of the html table via DataTable)
has to have value equal to
the title of the columns of the db table containing the data that one wants to fill in the html table.
So, since in my case the data I want to fill in the html table comes from the columns nested_field
, subfields
of the db table testing_nested_field_blacklist
,
in the declaration of javascript variable columns_nested_field
(which is necessary to make DataTable work),
I substituted
{ "title":"Nested field", data: "nested_field_name"},
{ "title":"Subfields blacklist", data: "nested_field_blacklist"},
with
{ "title":"Nested field", data: "nested_field"},
{ "title":"Subfields blacklist", data: "subfields"},
and now the table is correctly filled in with the data.
I've just learned from this thread that the key data
I mentioned above has to have value equal to a field name/key used in the JSON object (that in my script is being generated at line
raise gen.Return(self.write(json.dumps(dictionary_nested_field, default=myconverter)))
of the post
coroutine method of instance of class extractNestedFields
, one object per row.