Parent / child editing in child rows for NodeJS
Parent / child editing in child rows for NodeJS
tablo
Posts: 58Questions: 13Answers: 0
Hi all,
Could someone please help me to convert PHP into JavaScript (NodeJS)?
It is the server side script from this blog:
Parent / child editing in child rows
https://datatables.net/blog/2019-01-11#Server-side-(PHP)
PHP:
//Parent table
Editor::inst( $db, 'sites' )
->fields(
Field::inst( 'id' )->set( false ),
Field::inst( 'name' )->validator( 'Validate::notEmpty' )
)
->join(
Mjoin::inst( 'users' )
->link( 'sites.id', 'users.site' )
->fields(
Field::inst( 'id' )
)
)
->process( $_POST )
->json();
//Child table
if ( ! isset($_POST['site']) || ! is_numeric($_POST['site']) ) {
echo json_encode( [ "data" => [] ] );
}
else {
Editor::inst( $db, 'users' )
->field(
Field::inst( 'users.first_name' ),
Field::inst( 'users.last_name' ),
Field::inst( 'users.phone' ),
Field::inst( 'users.site' )
->options( 'sites', 'id', 'name' )
->validator( 'Validate::dbValues' ),
Field::inst( 'sites.name' )
)
->leftJoin( 'sites', 'sites.id', '=', 'users.site' )
->where( 'site', $_POST['site'] )
->process($_POST)
->json();
}
This is what I have done so far:
"use strict";
let db = require("./db");
let router = require("express").Router();
const {
Editor,
Field,
Validate,
Format,
Options,
Mjoin
} = require("datatables.net-editor-server");
router.all("/api/sites", async function(req, res) {
// Parent table
const editor = new Editor(db, "sites")
.debug(true)
.fields(
new Field("id").set(false),
new Field("name").validator(Validate.notEmpty())
)
.join(
new Mjoin("users")
.link('sites.id', 'users.site')
.fields(
new Field("id")
)
);
// Child table
if (condition) {
} else {
const editor = new Editor(db, "users")
.debug(true)
.fields(
new Field("users.first_name"),
new Field("users.last_name"),
new Field("users.phone"),
new Field("users.site")
.options('sites', 'id', 'name')
.validator(Validate.dbValues()),
new Field("sites.name")
)
.leftJoin( 'sites', 'sites.id', '=', 'users.site' )
.where('site', $_POST['site']);
}
await editor.process(req.body);
res.json(editor.data());
});
I have no idea how to convert the if condition...
This question has an accepted answers - jump to answer
This discussion has been closed.
Answers
I am pretty sure that if the same post variable that was passed to your php script is getting passed to your node script that you can just look on the req.body object.
Did you setup your express parser middleware?
Dave
@daduffy: Thanks for the response!
I can't...I tried to remove the if condition and run it but I got this:
Something broke!
I didn't touch this stuff. I'm just using an example and replacing things that are different.
Needs to be:
at the very least .
Which example are you using? Are you using the Editor NodeJS download package examples?
Allan
@allan: Thanks for your response!
that was easy...
How about the if condition and the rest?
No. It's something simple I created with the Generator for Editor.
Should I use something else as skeleton?
No the Generator download is a good skeleton.
Can you show me what you've got and also a debug log trace of the error.
Allan
Meanwhile I tried again with Editor-NodeJS-1.9.0 and created a new controller.
With this script:
I get this result at http://localhost:8081/api/permissions:
When I add the child table like this:
I get again "Something broke!".
So the API does not work. The main issue is the server side script. I don't understand how it should be. I think if I have it, I can go further.
Regarding the debugging.
I have ".debug(true)" but I don't see any debug info in the terminal.
How do I get "debug log trace of the error"? Do you mean this from the DataTables debugger?
It adds the SQL that is generated by the libraries into the JSON response.
If you are getting "Something broke" then it probably isn't getting as far as that...
Have you added the
permission
property to the Ajax request? Can you show me your (browser) Javascript code please?Allan
@allan: I tried again with the database and tables from Editor-Node.js-1.9.0. This is the current state:
Browser script (I just changed the API endpoints):
Controller _sites.js:
Controller _users.js:
And this is the new error I'm getting, when I try to access the APIs on:
http://localhost:8081/api/_users
or
http://localhost:8081/api/_sites
I tried to fix the new error without success...
I don't understand why the browser script has higher priority than the APIs. If the APIs are giving me an error, how should the browser script work?
Also, I had before mistakenly debug: true, inside the connection, which I changed.
I fear you've discovered a bug in the NodeJS libraries for Editor here! If using a single link for Mjoin, and you have two tables with an
id
column each it throws the error you are seeing. Its caused by this line - it needs to reference the tables as well.I'm just looking into that and will post back when committed.
Regards,
Allan
Here is the fix. If you grab the latest files from that git repo, that should fix that specific issue.
Allan
@allan: Thanks for the quick fix!
I have replaced the old files with the new files but now I'm getting a new error:
Again, the API endpoints do not work.
What a muppet - sorry! Proper fix is here.
Allan
@allan: Thanks for the new fix!
Sorry to say that but I have replaced the old files with the new files and now I'm getting a new error:
2 alert warnings:
DataTables warning: table id=sites - Requested unknown parameter 'name' for row 0, column 1. For more information about this error, please see http://datatables.net/tn/4
In the browser console:
this line shows an error in editor-demo.js:39:
and this the output from the server terminal:
After the 2 alerts the column with the numbers of users appears but not the column with the site names or the column with the "+" sign.
When I check the "DataTables debug" I see "15 tests complete. No failures or warnings found!"
I think that's progress. Can you use the upload feature in the debugger to send me some details please. Using the upload configuration option and then send me the 6 (or 7 - can't remember off the top of my head!) code.
Allan
@allan: I just uploaded the config data. Not sure if it was successfully uploaded.
I'm not sure what do you mean by that. Do you mean the table row?
<tr id="row_1" role="row" class="odd selected"><td class=" details-control"></td><td class="sorting_1"></td><td>6</td></tr>
Ah, Allan meant to use the debugger,
C
@colin : Thanks!
So, is it OK now? I had the DataTables Debugger installed as boomarklet and pressed the button to upload the configuration. If I remember correctly I saw a confirmation message but nothing else. What is the 6 or 7 code?
You should see a code, which would identify your upload, see screenshot below:
@colin : Thanks!
I've somehow missed that
I've uploaded the config data again and sent the code to @allan.
Perfect - thanks.
You have:
For the second column, but the data for the rows is structured in the JSON as:
So DataTables is correct in saying that there is no
name
property in the object. Itssites.name
that you want.Allan
Thanks!
I also had to change it accordingly in the controller:
Now I can see the data in all 3 columns of the parent table and edit the site names. So, the API of the the parent table is now reachable and seems to be working fine. However, the API of the child table still does not work!
When I press the + sign to see the data of the child table I see only "Loading".
Apart from that when I press "new" in the parent table to enter a new site the form appears but the dropdown menu does not work and also no data is being written.
The error "Uncaught ReferenceError: editor is not defined" is not gone.
I'd need a link to your page to be able to diganose that error. Likely there is a Javascript error happening in the function used to get the Ajax data. It might be the getting of the id from the host row, or something else.
Allan
I'm testing it locally. What page?
Is it not possible to test it if you have the files? I mean there are only 4 files involved:
* 1 html file which with 3 tags.
* 1 browser script which is exactly the same with the script in the PHP example.
* and 2 controller files of which the code I've already post them before.
I could send you them again files if you want.
Like I wrote many times before I'm not familiar with PHP at all. I tried to convert the controller files into JS and I'm still not sure if they are correct (OK, now the file for the parent table seems to be OK).
Can you you please check the code in the controller and verify that is correct?
I have removed the "if block" and when I try to reach the API I get this error:
This is the code of the controller:
The controller code looks okay, which is why a link to a page would be useful (you'd need to publish it somewhere for that to be possible though).
From the error generated it sounds like the client-side isn't actually sending any information to the server. At this point:
Can you add
console.log(rowData)
and tell me what the console shows it to be please?Allan
The line:
from here:
is totally missing.
and this:
outputs:
When I change to:
d.site = rowData.sites.id;
I get {site: 1} but nothing happens...
The NodeJS version of that code is just:
That's just for the case when querying the table without giving a
site
though.That sounds better. So on the server
request.body.site
is1
at that point?That should stop the undefined binding error you noted above.
Allan
It is. Yes. It did also before but it was still showing "Loading".
And this was the missing part to make it work...
Both tables (reading & writing) work fine now!!!
A last thing which I find weird. Why the API endpoint of the "users" here:
localhost:8081/api/_users
shows this:
I mean, why is "data" an empty array? Is this OK?
Because without a
site
for the child table, you don't want to display anything in the child table. Your alternative would be to check forsite
and if not present, then display the information for all rows, regardless ofsite
.Good to hear we've got it working now.
Allan
OK. Thanks!