Standalone fields - cannot get initial values to load and cannot save new values
Standalone fields - cannot get initial values to load and cannot save new values
HI,
I am trying hard to get the Standalone edit mode to work in my site, but am not getting very far. I hope someone who is more knowledgeable than I (this is not hard as I am a total novice) can help (@allan if you have time?) , or send me an example that I can work from to correct my mistakes.
The basic setup is I have a table that is used to store contacts (called 'recruits'), then I have a table that stores data about these contacts (called 'recruits_data'). Ideally, I want to show the 'recruits table in a datagrid, then when one row is selected, I want the standalone fields to populate with data from the 'recruits_data' table. I previously had this working flawlessly when using two datagrids (one for each table), but design requirements make using Standalone fields a much better fit for the application.
I am using Node.JS and the data is stored in mySQL.
The problems I am seeing are ;
The data from the 'recruits_data' table does not populate the initial standalone fields. I have tried using both the INLINE and EDIT options.
When saving a field, everything appears to work (no errors) but the data is not saved. I notice that the AJAX url is called correctly and the data appears correct, but the response looks like nothing occurred. See the data example below:
**Request: **
data[1][recruits_data][status]: New Recruit
action: edit
recruitID: 1
**Response : **
{"cancelled":[],"data":[],"fieldErrors":[],"debug":[]}
Here is my setup (note I use Jade/Pug, so the HTML will look a little strange, but it is fairly
easy to follow if you ignore the strangeness of the look.)
**HTML / Pug File **
extends layout
block content
#datamain.container-fluid(style='margin-top: 20px;)
.row
.col
.box.mr-1.ml-1.mt-0
table#recruits.display.compact(cellpadding='0' cellspacing='0' border='0' width='100%')
thead
tr
th.small Recruit ID
th.small NPN ID
th.small First
th.small Middle
th.small Last
.row.flex-nowrap
.col
.box.d-flex.mr-1.ml-1.mt-0
div#rd_data_div(data-editor-id='0').d-flex.flex-row
dl
dt recruitID:
dd(data-editor-field='recruits_data.recruitID')
dt Status:
dd(data-editor-field='recruits_data.status')
dd
button#rd_data_edit Edit
block append footer
(function ($) {
$(document).ready(function () {
// *** START Recruits Editor ***
var recruitEditor = new $.fn.dataTable.Editor({
ajax: '/demo/api/recruits',
table: '#recruits',
fields: [
{label: "Recruit ID:", name: "recruits.recruitID",type: "readonly"},
{label: "NPN ID:", name: "recruits.NPN"},
{label: "First Name:", name: "recruits.FirstName"},
{label: "Middle Name:", name: "recruits.MiddleName"},
{label: "Last Name:", name: "recruits.LastName"}
]
});
var recruit_table = $('#recruits').DataTable({
dom: 'Blfrtip',
ajax: {
url: '/demo/api/recruits',type: "POST"},
serverSide: true,
processing: false,
columns: [
{data: "recruits.recruitID", class: "small dt-body-center", visible: false},
{data: "recruits.NPN", class: "small dt-body-center", visible: false},
{data: "recruits.FirstName", class: "small",searchable: false},
{data: "recruits.MiddleName", class: "small",searchable: false},
{data: "recruits.LastName", class: "small",searchable: false}
]
});
// *** END Recruits Editor ***
// *** START Data Editor ***
var r_dataEditor = new $.fn.dataTable.Editor({
ajax: {
url: '/demo/api/recruits_data',
async: true,
data: function (d) {
var selected = recruit_table.row({selected: true});
if (selected.any()) {
d.recruitID = selected.data().recruits.recruitID;
}
}
},
fields: [
{label: "recruitID:", name: "recruits_data.recruitID", type: "readonly"},
{label: "Status:",name: "recruits_data.status",type: "select",placeholder: "Select the Status",options: ["New Recruit", "Not Contacted", "Contacted", "Callback", "Meeting Set", "No Show", "Agent Info Sent", "Agent Info Completed", "Contract", "Compass Agent", "Lost - Not Interested", "Lost - Not a Candidate", "Lost - Remove from Marketing"]}
]
});
$('[data-editor-field]').on( 'click', function (e) {
r_dataEditor
.inline( this, {
buttons: '_basic'
} );
} );
$('#rd_data_edit').on( 'click', function () {
r_dataEditor
.buttons( {
label: "Save",
fn: function () { this.submit(); }
} )
.edit();
} );
// *** END Data Editor ***
recruit_table.on('select', function (e) {
$("#rd_data_div").attr("data-editor-id",recruit_table.row({selected: true}).data().recruits.recruitID);
r_dataEditor
.field('recruits_data.recruitID')
.def(recruit_table.row({selected: true}).data().recruitID);
});
r_dataEditor.on('submitSuccess', function () {
recruit_table.ajax.reload();
});
});
}(jQuery));
Controller / Node.JS Route File
const router = require('express').Router();
const expressValidator = require('express-validator');
const middleware = require('./middleware.js');
let myDB = require('../recruiting');
let {
Editor,
Field,
Validate,
Format,
Options
} = require("datatables.net-editor-server");
//All routes from /LifeCases are routed here.
router.get("/", middleware.loggedIn(), (req,res) => {
res.render('demo', {showAdmin: true})
});
router.all('/api/recruits', async function(req, res) {
let editor = new Editor(myDB, 'recruits', 'recruits.recruitID')
.fields(
new Field("recruits.recruitID")
.setFormatter( Format.ifEmpty(null)),
new Field("recruits.NPN")
.setFormatter( Format.ifEmpty(null)),
new Field("recruits.FirstName")
.setFormatter( Format.ifEmpty( null )),
new Field("recruits.MiddleName")
.setFormatter( Format.ifEmpty( null )),
new Field("recruits.LastName")
.setFormatter( Format.ifEmpty( null ))
)
await editor.process(req.body);
res.json(editor.data());
});
router.all('/api/recruits_data', async function(req, res) {
if (! req.body.recruitID) {
res.json({data:[]});
return;
}
let editor = new Editor(myDB, 'recruits_data', 'recruits_data.recruitID')
.fields(
new Field("recruits_data.recruitID")
.setFormatter( Format.ifEmpty(null)),
new Field("recruits_data.status")
.setFormatter( Format.ifEmpty( 'New Recruit' )),
)
.where( function () {
this.where( 'recruits_data.recruitID', req.body.recruitID );
} )
await editor.process(req.body);
res.json(editor.data());
});
module.exports = router;
Any Help, advice, or examples would be gratefully received. I does appear that using StandAlone would be perfect for my application, so I do hope someone can point me in the correct direction here.
thanks you so much,
Answers
I didn't look at your code but I can share my experience. I never got standalone editing to work with Editor. My workaround is that I use Editor with invisible data tables that have one column and mostly just one row. Then everything works as usual even though it is a bit annoying to have that pseudo-data table stuff in the code.
Thanks @rf1234
That is funny, I was just starting to do that here. As if I create a table
with a single field, and then hide the header, make it not sortable, it looks just like a standalone field and works perfectly. It's a shame to do it that way, but it will work.
thanks for your comment.