Parent child editor - child editor do not trigger update query

Parent child editor - child editor do not trigger update query

carrarachristophecarrarachristophe Posts: 113Questions: 25Answers: 2

Hello,
I am trying to implement the parent child editor but fail to update the child.

I tryied both methods:
* https://editor.datatables.net/examples/datatables/parentChild
* https://editor.datatables.net/examples/advanced/parentChild / https://datatables.net/blog/2016/parent-child-editing

For both:
1. I can see and update the parent table
2. I can see the childs of the each parent
3. BUT when I try to update a child, nothing happens. I can only see with the debug that no UPDATE query runs.

Is anyone able to locate what is missing or wrong?
I copy / pasted the code from the examples and adapted it several times, but it always leads to the same result.

Thanks and regards,
Christophe

Answers

  • carrarachristophecarrarachristophe Posts: 113Questions: 25Answers: 2

    here is my code for the fist method:

    (function($){
        
    var editor;
    
    $(document).ready(function() {
        
    // Nested editor
    const facturearticleEditor = new DataTable.Editor({
        ajax: {
            url: 'php/table.fac_facturearticles.php',
            data: function (d) {
                let selected = factureTable.row({ selected: true });
                if (selected.any()) {
                    d.facture = selected.data().fac_factures.facture_id;
                }
            }
        },
        fields: [
            {
                label: 'Facture:',
                name: 'fac_facturearticles.facture'
            },
            {
                label: 'Quantité:',
                name: 'fac_facturearticles.quantite'
            },
            {
                label: 'Article:',
                name: 'fac_facturearticles.article',
                type: 'select',
                placeholder: 'Selectionnez un article'
            },
            {
                label: 'Prix unitaire:',
                name: 'fac_facturearticles.prixunitaire'
            }
        ],
        table: '#fac_facturearticles'
    });
     
    // Main / parent / top level Editor
    let factureTable;
    const factureEditor = new DataTable.Editor({
        ajax: 'php/table.fac_factures.php',
        table: '#fac_factures',
        fields: [
            {
                "label": "Société:",
                "name": "fac_factures.facture_societe",
                type: 'select',
                placeholder: '',
                placeholderDisabled: false,
                placeholderValue: null
            },
            {
                "label": "Client:",
                "name": "fac_factures.facture_client",
                type: 'select',
                placeholder: '',
                placeholderDisabled: false,
                placeholderValue: null
            },
            {
                "label": "Statut:",
                "name": "fac_factures.facture_statut",
                type: 'select',
                placeholder: '',
                placeholderDisabled: false,
                placeholderValue: null
            },
            {
                "label": "Devise:",
                "name": "fac_factures.facture_devise",
                type: 'select',
                placeholder: '',
                placeholderDisabled: false,
                placeholderValue: null
            },
            {
                label: "Date de facture:",
                name: "fac_factures.facture_date",
                type: "datetime",
                format: "DD\/MM\/YYYY"
            },
            {
                label: "Date d'échéance:",
                name: "fac_factures.facture_duedate",
                type: "datetime",
                format: "DD\/MM\/YYYY"
            },
            {
                "label": "Ma référence:",
                "name": "fac_factures.ref"
            },
            {
                "label": "Référence client:",
                "name": "fac_factures.ref_client"
            },
            {
                label: 'Articles:',
                name: 'fac_facturearticles.facture',
                type: 'datatable',
                editor: facturearticleEditor,
                submit: false,
                optionsPair: {
                    value: 'fac_facturearticles.facturearticle_id'
                },
                config: {
                    ajax: {
                        url: 'php/table.fac_facturearticles.php',
                        type: 'post',
                        data: function (d) {
                            if (factureTable) {
                                let selected = factureTable.row({ selected: true });
                                if (selected.any()) {
                                    d.facture = selected.data().fac_factures.facture_id;
                                }
                            }
                        }
                    },
                    buttons: [
                        { extend: 'create', editor: facturearticleEditor },
                        { extend: 'edit', editor: facturearticleEditor },
                        { extend: 'remove', editor: facturearticleEditor }
                    ],
                    columns: [
                        { data: 'fac_facturearticles.facture', title: 'Facture' },
                        { data: 'fac_facturearticles.quantite', title: 'Quantité' },
                        { data: 'fac_articles.article', title: 'Article' },
                        { data: 'fac_facturearticles.prixunitaire', title: 'Prix unitaire' }
                    ]
                }
            }
        ]
    });
     
    // factures DataTable shown in the page
    factureTable = new DataTable('#fac_factures', {
        ajax: 'php/table.fac_factures.php',
        columns: [
            {"data": "fac_factures.facture_id"},
            {"data": "tms_rf_company.CompanyName"},
            {"data": "fac_clients.client"},
            {"data": "tms_sy_statut.Statut"},
            {"data": "fac_factures.facture_date"},
            {"data": "fac_factures.facture_duedate"},
            {data: null, render: function ( data, type, row ) {
                return type === 'display'? '<div title="' + data.devises.devise_en + '">' + data.devises.devise_code + '</a>' + '</div>' : data.devises.devise_code + '</a>';
            }}
        ],
        layout: {
            topStart: {
                buttons: [
                    { extend: 'create', editor: factureEditor },
                    { extend: 'edit', editor: factureEditor },
                    { extend: 'remove', editor: factureEditor }
                ]
            }
        },
        select: {
            style: 'single'
        }
    });
     
    factureEditor.on('initEdit', function () {
        // Unhide in case of being hidden by create
        factureEditor.field('fac_facturearticles.facture').show();
     
        // Get articles for the selected facture
        factureEditor
            .field('fac_facturearticles.facture')
            .dt()
            .ajax.reload(function (json) {
                // Update the options for the sub-editor. This will be automatic
                // in future versions of Editor
                facturearticleEditor.field('fac_facturearticles.facture').update(json.options['fac_facturearticles.facture']);
            });
     
        // Set the default for the "new" article facture field
        facturearticleEditor
            .field('fac_facturearticles.facture')
            .def(factureTable.row({ selected: true }).data().id);
    });
     
    // Disable the ability to create a new article on a new facture
    factureEditor.on('initCreate', function () {
        factureEditor.field('fac_facturearticles.facture').hide();
    });
    
    
    } );
    
    }(jQuery));
    
  • carrarachristophecarrarachristophe Posts: 113Questions: 25Answers: 2

    here is my code for the second method

    (function($){
        
    var editor;
    
    $(document).ready(function() {
    
        const factureEditor = new DataTable.Editor({
            ajax: 'php/table.fac_factures.php',
            fields: [
                {
                    "label": "Société:",
                    "name": "fac_factures.facture_societe",
                    type: 'select',
                    placeholder: '',
                    placeholderDisabled: false,
                    placeholderValue: null
                },
                {
                    "label": "Client:",
                    "name": "fac_factures.facture_client",
                    type: 'select',
                    placeholder: '',
                    placeholderDisabled: false,
                    placeholderValue: null
                },
                {
                    "label": "Statut:",
                    "name": "fac_factures.facture_statut",
                    type: 'select',
                    placeholder: '',
                    placeholderDisabled: false,
                    placeholderValue: null
                },
                {
                    "label": "Devise:",
                    "name": "fac_factures.facture_devise",
                    type: 'select',
                    placeholder: '',
                    placeholderDisabled: false,
                    placeholderValue: null
                },
                {
                    label: "Date de facture:",
                    name: "fac_factures.facture_date",
                    type: "datetime",
                    format: "DD\/MM\/YYYY"
                },
                {
                    label: "Date d'échéance:",
                    name: "fac_factures.facture_duedate",
                    type: "datetime",
                    format: "DD\/MM\/YYYY"
                },
                {
                    "label": "Ma référence:",
                    "name": "fac_factures.ref"
                },
                {
                    "label": "Référence client:",
                    "name": "fac_factures.ref_client"
                }
            ],
            table: '#fac_factures'
        });
    
        const factureTable = $('#fac_factures').DataTable({
            ajax: 'php/table.fac_factures.php',
            columns: [
                {"data": "fac_factures.facture_id"},
                {"data": "tms_rf_company.CompanyName"},
                {"data": "fac_clients.client"},
                {"data": "tms_sy_statut.Statut"},
                {"data": "fac_factures.facture_date"},
                {"data": "fac_factures.facture_duedate"},
                {data: null, render: function ( data, type, row ) {
                    return type === 'display'? '<div title="' + data.devises.devise_en + '">' + data.devises.devise_code + '</a>' + '</div>' : data.devises.devise_code + '</a>';
                }}
            ],
            layout: {
                topStart: {
                    buttons: [
                        { extend: 'create', editor: factureEditor },
                        { extend: 'edit', editor: factureEditor },
                        { extend: 'remove', editor: factureEditor }
                    ]
                }
            },
            order: [[ 0, 'asc' ]],
            language: {"url": "json/fr-FR.json"},
            select: {
                style: 'single'
            }
        });
    
    const facturearticleEditor = new DataTable.Editor({
        ajax: {
            url: 'php/table.fac_facturearticles.php',
            data: function (d) {
                var selected = factureTable.row({ selected: true });
                if ( selected.any() ) {
                    d.facture = selected.data().fac_factures.facture_id;
                }
            }
        },
        fields: [
            {
                label: 'Facture:',
                name: 'fac_facturearticles.facture'
            },
            {
                label: 'Quantité:',
                name: 'fac_facturearticles.quantite'
            },
            {
                label: 'Article:',
                name: 'fac_facturearticles.article',
                type: 'select',
                placeholder: 'Selectionnez un article'
            },
            {
                label: 'Prix unitaire:',
                name: 'fac_facturearticles.prixunitaire'
            }
        ],
        table: '#fac_facturearticles'
    });
    
        const facturearticleTable = $('#fac_facturearticles').DataTable({
            ajax: {
                url: 'php/table.fac_facturearticles.php',
                type: 'post',
                data: function ( d ) {
                    var selected = factureTable.row({ selected: true });
                    if ( selected.any() ) {
                        d.facture = selected.data().fac_factures.facture_id;
                    }
                }
            },
            columns: [
                { data: 'fac_facturearticles.facture' },
                { data: 'fac_facturearticles.quantite' },
                { data: 'fac_facturearticles.article' },
                { data: 'fac_facturearticles.prixunitaire' }
            ],
            layout: {
                topStart: {
                    buttons: [
                        {
                            extend: 'create',
                            editor: facturearticleEditor,
                            enabled: false,
                            init: function (dt) {
                                factureTable.on('select deselect', () => {
                                    this.enable(factureTable.rows({ selected: true }).any());
                                });
                            }
                        },
                        { extend: 'edit', editor: facturearticleEditor },
                        { extend: 'remove', editor: facturearticleEditor }
                    ]
                }
            },
            language: {"url": "json/fr-FR.json"},
            select: true
        });
    
    factureTable.on('select', function (e) {
        facturearticleTable.ajax.reload();
    
        facturearticleEditor
            .field('fac_facturearticles.facture')
            .def(factureTable.row({ selected: true }).data().fac_factures.facture_id);
    });
     
    factureTable.on('deselect', function () {
        facturearticleTable.ajax.reload();
    });
     
    facturearticleEditor.on('submitSuccess', function () {
        factureTable.ajax.reload();
    });
     
    factureEditor.on('submitSuccess', function () {
        facturearticleTable.ajax.reload();
    });
    
    } );
    
    }(jQuery));
    
  • allanallan Posts: 63,676Questions: 1Answers: 10,497 Site admin

    Hi Christophe,

    Can you link to the page you are working on so I can take a look please? You can PM it to me if you don't want to make the link public.

    Allan

  • carrarachristophecarrarachristophe Posts: 113Questions: 25Answers: 2
    edited November 16

    Hello Allan,
    I managed to fix it.
    Hard to say what the problem was because I started several times from scratch, but I think the issue was that part.

        // Set the default for the "new" article facture field
        facturearticleEditor
            .field('fac_facturearticles.facture')
            .def(factureTable.row({ selected: true }).data().**id**);
    });
    
        // Set the default for the "new" article facture field
        facturearticleEditor
            .field('fac_facturearticles.facture')
            .def(factureTable.row({ selected: true }).data().**fac_factures.facture_id**);
    });
    

    Question for you: is there a way to be able to create a child at the same time as creating the parent?

  • allanallan Posts: 63,676Questions: 1Answers: 10,497 Site admin

    Not really - not using nested Editors like that at least. The nested Editor is async to the host Editor, it submits and then returns control to the host.

    Allan

  • carrarachristophecarrarachristophe Posts: 113Questions: 25Answers: 2

    Any idea for a workaround that would work like: upon creation of the parent, the parent would close and reopen automatically?

  • allanallan Posts: 63,676Questions: 1Answers: 10,497 Site admin

    It depends on what you mean by "at the same time". Do you mean a single Ajax request?

    I had assumed that you where looking for the child row to be local (i.e. on the browser only) until the parent form is submitted. Is that what you are looking to do?

    That would be difficult to do in Editor. At least not with out a large amount of custom code for the submit handler and on the server-side.

    Allan

  • jdaughertyjdaugherty Posts: 4Questions: 2Answers: 0

    Hi @allan,

    Is https://datatables.net/forums/discussion/comment/211255 similar to this request? If you treat the child data as a json object that's modified via a nested datatable with no ajax, then you just need to handle that object on the backend. Yes?

    Are there any official examples of modifying a nested json field and submitting it along with the parent?

  • allanallan Posts: 63,676Questions: 1Answers: 10,497 Site admin

    If you treat the child data as a json object that's modified via a nested datatable with no ajax, then you just need to handle that object on the backend. Yes?

    Yes, that could be done. Setup the child DataTable as a local table. There is a limitation in datatable at the moment in that it expects the field value to be an array of scalars, rather than an array of objects, but that is a trivial change if this is needed. The reason it is setup that way is I expected the datatable to be used for left joined or Mjoined data primarily.

    However:

    Are there any official examples of modifying a nested json field and submitting it along with the parent?

    Sorry, no. That is not something that the Editor server-side libraries are designed to handle. I suspect it would be possible to do with a bunch of loops over the submitted data, but it isn't something that I have tried I'm afraid.

    Allan

Sign In or Register to comment.