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

MarkAndersonUKMarkAndersonUK Posts: 43Questions: 16Answers: 0

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 ;

  1. The data from the 'recruits_data' table does not populate the initial standalone fields. I have tried using both the INLINE and EDIT options.

  2. 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

  • rf1234rf1234 Posts: 2,801Questions: 85Answers: 406

    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.

  • MarkAndersonUKMarkAndersonUK Posts: 43Questions: 16Answers: 0

    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.

Sign In or Register to comment.