trying to understand editor with a datatable which child records and passing the ID to the PHP
trying to understand editor with a datatable which child records and passing the ID to the PHP

I have been trying to understand what https://editor.datatables.net/examples/datatables/parentChild.html is doing, as I want the editor to contain a datatable with records belonging to the row being edited. The data table displayed in the editor form will be read-only. I am not even concerned with adding the child rows. I just want the editor to display two data tables both with records from different tables that tie back to the row being edited.
I understand in users.php it's looking at $_POST['site'])
And when present, it's used as a where clause, so only users under the site are returned.
I believe that the below function from the editor is where it sets and passes the site to users.php
config: {
ajax: {
url: '../php/users.php',
type: 'post',
data: function (d) {
if (siteTable) {
let selected = siteTable.row({ selected: true });
if (selected.any()) {
d.site = selected.data().id;
}
}
}
},
I don't understand how if (siteTable) {
is used. If I comment the if and the closing} out, there is a an error: Cannot read properties of undefined (reading 'row'), which makes me think the if (siteTable) {
is used o determine if we are actually running the code after data is loaded.
I also worked with the modifier and set up an event that fires when I edit, I can tell by the console log it's getting the correct it. But I haven't been able to get a value in the $_POST in the PHP for the child records.
here is my js file:
var usersEditor = new DataTable.Editor({
ajax: {
url: 'php/a2_residents_nesed.php'
},
fields: [
{
label: 'FullName:',
name: 'FullName'
}
]
});
//addEventListener("DOMContentLoaded", function () {
let maintable;
const addresseditor = new DataTable.Editor( {
ajax: 'php/table.a2.php',
table: '#Adresses',
idSrc: "Addresses.AddressAID",
fields: [
{
"label": "AddressNotes man:",
"name": "Addresses.addressnotes",
"type": "textarea"
},
{
"label": "AddressInactive:",
"name": "Addresses.addressinactive",
"type": "checkbox",
"separator": "",
options: [
{ label: "", value: 1 }
] ,
unselectedValue : 0
}
,{
label: 'Residents:',
name: 'Addresses.AddressAID',
type: 'datatable',
submit: false,
editor: usersEditor,
optionsPair: {
value: 'Addresses.AddressAID'
},
config: {
ajax: {
url: 'php/a2_residents_nesed.php',
type: 'post',
data: function (d) {
console.log("here");
if (maintable) {
console.log("under if");
var selected = maintable.row({ selected: true });
if (selected.any()) {
d.AddressAID = selected.data().AddressAID;
}
}
}
},
columns: [
{
data: 'view_Residents.FullName',
title: 'FullName'
}
]
}
}
] // fields: [
} ); // var editor = new DataTable.Editor( {
maintable = new DataTable('#Adresses', {
serverSide: false,
ajax: 'php/table.a2.php',
idSrc: "Addresses.AddressAID",
columns: [
{
title: 'Full Address',
defaultContent : '',
render: function(data, type, row) {
var calcAddress = "";
calcAddress= row.Addresses.streetname + " " + row.Addresses.addressnumber.toString();
if (row.Addresses.address2 != null) {
calcAddress +=" " + row.Addresses.address2
};
return calcAddress.trim();
}
} ,
{
"data": "Addresses.streetname"
//,visible: false
},
{
"data": "view_AddressNames.Names"
//,visible: true
},
{
"data": "vew_AddressPartyCount.Parties"
//,visible: true
},
{
"data": "Addresses.addressnumber"
//,visible: false
},
{
"data": "Addresses.address2"
//,visible: false
},
{
"data": "Addresses.city"
//,visible: false
},
{
"data": "Addresses.state"
//,visible: false
},
{
"data": "Addresses.ward"
},
{
"data": "Addresses.district"
},
{
"data": "Addresses.addressnotes",
className: 'limit-wrap-text' ,
render: DataTable.render.ellipsis( 50 )
},
{
"data": "Addresses.nors",
//,visible: false
},
{
"data": "Addresses.lat"
//,visible: false
},
{
"data": "Addresses.long",
//, visible: false
}
,
{
"data": "Addresses.addressinactive"
}
,{
"data": "view_Residents", render: '[, ].FullName'
}
],
select: true,
order: [[1, 'asc']],
rowId: 'Addresses.AddressAID',
stateSave: true,
paging: true,
scrollCollapse: true,
scrollY: '50vh',
lengthMenu: [10, 25, 50, 100, 500, -1],
scrollX: true,
select: {
style: 'single',
selector: 'td:not(:first-child)'
},
layout: {
topStart: {
buttons: [
{ extend: 'edit', editor: addresseditor }
]
}
} //columnDefs: [{
//targets: '_all',
//render: DataTable.render.ellipsis( 10 )
//}],
}); // maintable = new DataTable('#Adresses', {
//} // addEventListener("DOMContentLoaded", function () {
addresseditor.on('open', function (e, type) {
var modifier = addresseditor.modifier();
if (modifier) {
var data = maintable.row(modifier).data();
// console.log(" data = ", data.Addresses.AddressAID);
addresseditor.field('Addresses.AddressAID').show();
// console.log(" enabled he field");
// Get users for the selected site
// do something with `data`
}
}); // addresseditor.on('open', function (e, type) {
// // Set the default for the "new" user site field
/// usersEditor
// .field('users.site')
// .def(siteTable.row({ selected: true }).data().id);
//});
;
This question has accepted answers - jump to:
Answers
It is simply checking to see if
siteTable
has been defined or not before using it. That is required in this case as thedatatable
field type will make an Ajax request immediately when it is created (with that configuration) - which is beforesiteTable
has been defined (that happens next). Hence the error if you remove the condition.Can you give me a link to the page you are working on so I can stick a debugger on it?
Allan
I set you a private message with a link, let me know if you didn't get it
I keep hitting a wall on this and I'm hoping someone can assist as time is running short. I don't know why the: if (maintable) is not working in the below. it's my goal to habe a data table on the editor form that shows multiple reaidents for the address being updated.
Edited by Kevin: Syntax highlighting. Details on how to highlight code using markdown can be found in this guide
It's almost impossible to debug a code snippet like that without being able to step through the code. I would pus a browser breakpoint on line 12. Find
maintable
, it might be in a different scope, and see what it is.Can you post a link to your page or test case replicating the issue so we can help debug?
https://datatables.net/manual/tech-notes/10#How-to-provide-a-test-case
Kevin
https://jyorkejudge.org/a2.html
I put a debugger in and it pauses when the page first loads. When I edit select an address and click on Edit, the editor form opens but the function under data isn't executing (I've tweaked so many things I am not sure what I have and have not changed).
Many thanks for the link and sorry I wasn't able to reply earlier. I'm traveling this week and am not able to reply as quickly as I would normally like (which I realise doesn't help you - sorry).
If you have a look at the example that you originally linked to it makes use of
initEdit
to reload the child DataTables' data:In your
table.A2.js
file, you have that, but it is commented out.You need that in if you want to have the child DataTable reload when the edit view is displayed (and thus has new data with which it should update the child table with).
Allan
Not sure if it will help or not but it looks like you have a filed name mismatch. You defined this editor:
And this for the columns for that Datatable field:
I believe the
fields.name
andcolumns.data
need to match. Try this:Kevin
Thank you, it didn't seem to affect anything. So, with the debugger enabled under Configure in the data editor, shouldn't this stop every time the editor is loaded/open?
Did you make the change Allan suggested? Seems that is what you are missing to fetch the Datatable data for the field when the editor form is open.
Kevin
Thank you @allan !!! it's doing what I want it to do. I must have danced around this, but just couldn't put it together.
Another question / issue that I am hoping you can assist, after the edit form comes up, I see this error
dataTables.editor.min.js:6 Uncaught Error: Unknown field name - Addresses.AddressAID
at R.Ct [as field] (dataTables.editor.min.js:6:24286)
at table.A2.js:216:41
at HTMLTableElement.<anonymous> (datatables.min.js:20:52175)
at HTMLTableElement.i (datatables.min.js:14:36996)
at HTMLTableElement.dispatch (datatables.min.js:14:39997)
at v.handle (datatables.min.js:14:37968)
at Object.trigger (datatables.min.js:14:70063)
at HTMLTableElement.<anonymous> (datatables.min.js:14:70665)
at ce.each (datatables.min.js:14:3129)
at ce.fn.init.each (datatables.min.js:14:1594)
The line that it's pointing to is:
when i comment out the line, the error goes away. it seems to still be working, what dies that line do and why is it producing an error?
There is no field with the name
Addresses.AddressAID
in yourusersEditor
, so the error is correct. That field is defined in youraddresseditor
Editor instance.The idea of that line is to update the list of options for the field based on the Ajax response.
There is a comment in the original code that says:
I've got a feeling that I might have implemented that. I'll need to check to confirm, which I will do so early next week. If it works the way you want without that line, just leave it out
Allan
A quick update on this, I've confirmed that the
.field(...).update(...)
call isn't needed. I've removed it locally and the update will be deployed to the site soon. It was originally needed as thexhr
didn't bubble on the document for tables which weren't in the document, but I've since fixed that and forgot to update this example.Allan