Trouble with Child Editing

Trouble with Child Editing

Hamjam31Hamjam31 Posts: 15Questions: 3Answers: 0

I am trying to integrate parent child editing into an app that I am working on. I am able to get the parent datatable to work along with parent editing. The child datatable is able to display data but the child editor is not working. I get these errors while with the child editor.
Edit - POST http://127.0.0.1:8000/dashboard/api/study/editor/?format=datatables 404 (Not Found) (XHR response shows {"data":{"detail":"Not found."},"recordsFiltered":1,"recordsTotal":1,"draw":1,"options":...)
Create - POST http://127.0.0.1:8000/dashboard/api/study/editor/?format=datatables 500 (Internal Server Error) - ValueError at /dashboard/api/study/editor/ Field 'id' expected a number but got ''.

Is there something wrong with the setup of my file?

Here is my HTML file.

{% block extra_js %}

        $(document).ready(function() {
            var InvestigatorEditor = new $.fn.dataTable.Editor( {
                ajax: "http://127.0.0.1:8000/dashboard/api/investigator/editor/?format=datatables",
                table: '#InvestigatorDataTable',
                idSrc: "id",
                fields: [ {
                    label: "Last Name:",
                    name: "last_name"
                }, {
                    label: "First Name:",
                    name: "first_name"
                }, {
                    label: "Email:",
                    name: "email"
                }, {
                    label: "Institution:",
                    name: "institution.id",
                    type: "select"
                    ///placeholder: "Select an institution"
                }] 
            });
            var InvestigatorTable = $('#InvestigatorDataTable').DataTable({
                serverSide: true,
                ajax: {
                    url: "http://127.0.0.1:8000/dashboard/api/investigator/?format=datatables",
                    type: "GET",
                },
                dom: 'Bfrtrip',
                columns: [
                    {data: null, className: 'dt-control', orderable: false, defaultContent: '', },
                    {data: "last_name", name: "last_name", },
                    {data: "first_name", name: "first_name", },
                    {data: null, render: function ( data, type, row ) {
                        return data.first_name + " " + data.last_name
                    },},
                    {data: "email", searchable: true},
                    {data: "institution.name", name: "institution.name",  },
                    ],
                columnDefs: [
                    { targets: [1, 2], visible: false},
                    { targets: '_all', visible: true }
                ],
                select: {
                    style:    'os',
                    selector: 'td:not(:first-child)'
                },
                buttons: [
                    { extend: "create", editor: InvestigatorEditor },
                    { extend: "edit", editor: InvestigatorEditor }, 
                    { extend: "remove", editor: InvestigatorEditor }
                ]
            });
            $('#InvestigatorDataTable tbody').on('click', 'td.dt-control', function () {
                var tr = $(this).closest('tr');
                var row = InvestigatorTable.row(tr);
         
                if (row.child.isShown()) {
                    // This row is already open - close it
                    row.child.hide();
                    tr.removeClass('shown');
                } else {
                    // Open this row
                    //row.child(format(row.data())).show();
                    createChild(row);
                    tr.addClass('shown');
                }
            });
            function createChild ( row ) {
                // This is the table we'll convert into a DataTable
                var table = $('<table class="display" width="100%"/>');
            
                // Display it the child row
                row.child( table ).show();

                var rowData = row.data();
                console.log(rowData);

                // Child Editor
                var StudyEditor = new $.fn.dataTable.Editor( {
                    ajax: {
                        url: "http://127.0.0.1:8000/dashboard/api/study/editor/?format=datatables",
                        data: function ( d ) {
                            d.investigator_id = rowData.id;
                        }
                    },
                    table: StudyTable, 
                    fields: [ {
                        label: "Name Short:",
                        name: "name_short"
                    }, {
                        label: "Name Full:",
                        name: "name_full"
                    }, {
                        label: "Investigator:",
                        name: "investigator.id",
                        type: "select",
                        //def: rowData.id
                    }, {
                        label: "Bhrrc Approval:",
                        name: "bhrrc_approval",
                        type: "datetime"
                    }, {
                        label: "Start Date:",
                        name: "start_date",
                        type: "datetime"
                    }, {
                        label: "End Date:",
                        name: "end_date",
                        type: "datetime"
                    }, {
                        label: "Enrollment Goal:",
                        name: "enrollment_goal"
                    }, {
                        label: "Current Enrollment:",
                        name: "current_enrollment"
                    }, {
                        label: "Status:",
                        name: "status",
                        type: "select",
                        options: [
                            "active",
                            "inactive", 
                            "completed",
                            ],
                    }, {
                        label: "Site:",
                        name: "site.id",
                        type: "select"
                    }], 
                    });
            
                // Child DataTable
                var StudyTable = table.DataTable( {
                    serverSide: true,
                    ajax: {
                        url: "http://127.0.0.1:8000/dashboard/api/study/?format=datatables",
                        data: function ( d ) {
                            d.investigator_id = rowData.id }
                    },
                    searching: false,
                    dom: 'Btri',
                    select: true,
                    columns: [
                        { title: "Study Name", data: "name_short", orderable: false },
                        { title: "End Date", data: "end_date", orderable: false },
                        { title: "ID", data: "id",},
                    ],
                    buttons: [
                        { extend: "create", editor: StudyEditor },
                        { extend: "edit", editor: StudyEditor }, 
                        { extend: "remove", editor: StudyEditor },
                    ],
                } );
            }
            function destroyChild(row) {
                var table = $("table", row.child());
                table.detach();
                table.DataTable().destroy();
             
                // And then hide the row
                row.child.hide();
            }
        });
    </script>
{% endblock %}

For reference here is some sample data as well

Study table

  {
            "id": 2,
            "name_full": "TMS fMRI Biomarkers",
            "name_short": "TMS MRI",
            "investigator_name": "Lim",
            "investigator": {
                "id": 1,
                "last_name": "Lim",
                "first_name": "Kelvin",
                "email": "kolim@umn.edu",
                "institution_name": "University of Minnesota",
                "institution": {
                    "id": 1,
                    "name": "University of Minnesota",
                    "dept": "Psychiatry"
                }
            },
            "bhrrc_approval": "2020-12-31",
            "start_date": "2021-01-01",
            "end_date": "2025-01-01",
            "enrollment_goal": 100,
            "current_enrollment": 25,
            "status": "active",
            "site_name": "Fairview",
            "site": {
                "id": 1,
                "lead": {
                    "id": 1,
                    "name_last": "Fenske",
                    "name_first": "Alicia",
                    "email": "blank@umn.edu",
                    "title": "Coordinator"
                },
                "name": "Fairview"
            }
        },

Investigator table

{
            "id": 1,
            "last_name": "Lim",
            "first_name": "Kelvin",
            "email": "kolim@umn.edu",
            "institution_name": "University of Minnesota",
            "institution": {
                "id": 1,
                "name": "University of Minnesota",
                "dept": "Psychiatry"
            }
        },

Answers

  • allanallan Posts: 63,523Questions: 1Answers: 10,473 Site admin

    Hi,

    We probably need to sort this bit out first:

    Edit - POST http://127.0.0.1:8000/dashboard/api/study/editor/?format=datatables 404 (Not Found)

    Is there actually a controller there? Does it need an id in the URL perhaps? The fact that the server is responding with a 404 suggests that it isn't expecting that URL, so we need to know what it is expecting to be able to correct it.

    Thanks,
    Allan

  • Hamjam31Hamjam31 Posts: 15Questions: 3Answers: 0

    It looks the equivalent to a controller in Django is the views. I will post the views file but I know you're unfamiliar with python so I found another function within Django that shows valid urls.

    Views.py

    class StudyViewSet(DatatablesEditorModelViewSet):
        serializer_class = StudySerializer
        
        def get_options(self):
            return get_dashboard_options()
        
        def get_queryset(self):
            queryset = Study.objects.all()
            investigator = self.request.query_params.get('investigator_id', None)
            if investigator is not None:
                queryset = queryset.filter(investigator_id=investigator)
            return queryset
        
        class Meta:
            datatables_extra_json = ('get_options', )
    

    Urls

    /dashboard/api/site\.<format>/  dashboard.views.SiteViewSet     dashboard:site-list
    /dashboard/api/study/   dashboard.views.StudyViewSet    dashboard:Study-list
    /dashboard/api/study/<pk>/      dashboard.views.StudyViewSet    dashboard:Study-detail
    /dashboard/api/study/<pk>\.<format>/    dashboard.views.StudyViewSet    dashboard:Study-detail
    /dashboard/api/study/editor/    dashboard.views.StudyViewSet    dashboard:Study-editor
    /dashboard/api/study/editor\.<format>/  dashboard.views.StudyViewSet    dashboard:Study-editor
    /dashboard/api/study\.<format>/ dashboard.views.StudyViewSet    dashboard:Study-list
    
  • Hamjam31Hamjam31 Posts: 15Questions: 3Answers: 0

    Another interesting note is that even when I remove the filter of d.investigator_id = rowData.id, the child editor still doesn't work. In essence it should just be a separate editor, however it seems not not work while formatted as a child editor. Is there something about the child edit setup that changes the editor?

    {% block extra_js %}
            $(document).ready(function() {
                var InvestigatorEditor = new $.fn.dataTable.Editor( {
                    ajax: {
                        url: "http://127.0.0.1:8000/dashboard/api/investigator/editor/?format=datatables",
                        data: function ( d ) {
                            console.log(d) } 
                    },
                    table: '#InvestigatorDataTable',
                    idSrc: "DT_RowId",
                    fields: [ {
                        label: "Last Name:",
                        name: "last_name"
                    }, {
                        label: "First Name:",
                        name: "first_name"
                    }, {
                        label: "Email:",
                        name: "email"
                    }, {
                        label: "Institution:",
                        name: "institution.id",
                        type: "select"
                        ///placeholder: "Select an institution"
                    }] 
                });
                var InvestigatorTable = $('#InvestigatorDataTable').DataTable({
                    serverSide: true,
                    ajax: {
                        url: "http://127.0.0.1:8000/dashboard/api/investigator/?format=datatables",
                        type: "GET",
                    },
                    dom: 'Bfrtrip',
                    columns: [
                        {data: null, className: 'dt-control', orderable: false, defaultContent: '', },
                        {data: "last_name", name: "last_name", },
                        {data: "first_name", name: "first_name", },
                        {data: null, render: function ( data, type, row ) {
                            return data.first_name + " " + data.last_name
                        },},
                        {data: "email", searchable: true},
                        {data: "institution.name", name: "institution.name",  },
                        ],
                    columnDefs: [
                        { targets: [1, 2], visible: false},
                        { targets: '_all', visible: true }
                    ],
                    select: {
                        style:    'os',
                        selector: 'td:not(:first-child)'
                    },
                    buttons: [
                        { extend: "create", editor: InvestigatorEditor },
                        { extend: "edit", editor: InvestigatorEditor }, 
                        { extend: "remove", editor: InvestigatorEditor }
                    ]
                });
                $('#InvestigatorDataTable tbody').on('click', 'td.dt-control', function () {
                    var tr = $(this).closest('tr');
                    var row = InvestigatorTable.row(tr);
             
                    if (row.child.isShown()) {
                        // This row is already open - close it
                        row.child.hide();
                        tr.removeClass('shown');
                    } else {
                        // Open this row
                        //row.child(format(row.data())).show();
                        createChild(row);
                        tr.addClass('shown');
                    }
                });
                function createChild ( row ) {
                    // This is the table we'll convert into a DataTable
                    var table = $('<table class="display" width="100%"/>');
                
                    // Display it the child row
                    row.child( table ).show();
    
                    var rowData = row.data();
                    console.log(rowData);
    
                    // Child Editor
                    var StudyEditor = new $.fn.dataTable.Editor( {
                        ajax: {
                            url: "http://127.0.0.1:8000/dashboard/api/study/editor/?format=datatables",
                        },
                        table: StudyTable,
                        idSrc: "id", 
                        fields: [ {
                            label: "Name Short:",
                            name: "name_short"
                        }, {
                            label: "Name Full:",
                            name: "name_full"
                        }, {
                            label: "Investigator:",
                            name: "investigator.id",
                            type: "select",
                            //def: rowData.id
                        }, {
                            label: "Bhrrc Approval:",
                            name: "bhrrc_approval",
                            type: "datetime"
                        }, {
                            label: "Start Date:",
                            name: "start_date",
                            type: "datetime"
                        }, {
                            label: "End Date:",
                            name: "end_date",
                            type: "datetime"
                        }, {
                            label: "Enrollment Goal:",
                            name: "enrollment_goal"
                        }, {
                            label: "Current Enrollment:",
                            name: "current_enrollment"
                        }, {
                            label: "Status:",
                            name: "status",
                            type: "select",
                            options: [
                                "active",
                                "inactive", 
                                "completed",
                                ],
                        }, {
                            label: "Site:",
                            name: "site.id",
                            type: "select"
                        }], 
                        });
                
                    // Child DataTable
                    var StudyTable = table.DataTable( {
                        serverSide: false,
                        ajax: {
                            url: "http://127.0.0.1:8000/dashboard/api/study/?format=datatables",
                        },
                        searching: false,
                        dom: 'Btri',
                        select: true,
                        columns: [
                            { title: "Study Name", data: "name_short", orderable: false },
                            { title: "End Date", data: "end_date", orderable: false },
                            { title: "Pk ID", data: "id",},
                            { data: "investigator.last_name", name: "investigator.last_name"},
                            { data: "bhrrc_approval", },
                            { data: "start_date", },
                            { data: "end_date", },
                            { data: "enrollment_goal", },
                            { data: "current_enrollment",},
                            { data: "status", },
                            { data: "site.name", name: "site.name", },
                        ],
                        columnDefs: [
                            { targets: [0, 1, 2, ], visible: true},
                            { targets: '_all', visible: false },
                        ], 
                        buttons: [
                            { extend: "create", editor: StudyEditor },
                            { extend: "edit", editor: StudyEditor }, 
                            { extend: "remove", editor: StudyEditor },
                        ],
                    } );
    
                    var pk = StudyTable.rows( ).data();
                    console.log(pk);
                }
                function destroyChild(row) {
                    var table = $("table", row.child());
                    table.detach();
                    table.DataTable().destroy();
                 
                    // And then hide the row
                    row.child.hide();
                }
            });
        </script>
    {% endblock %}
    
  • allanallan Posts: 63,523Questions: 1Answers: 10,473 Site admin

    It looks okay to me scanning over it.

    The only thing I can see, and I don't know if this makes a difference or not, as I'm not familiar with this type of router is:

    /dashboard/api/study/editor.<format>

    http://127.0.0.1:8000/dashboard/api/study/editor/?format=datatables

    Does the \ after editor make any difference? I fear you'll need to ask on StackOverflow or similar for this one. All I can really say is that if the server is returning 404, then the URL Editor is requesting is either wrong, or the router hasn't been setup for that URL at the server-side.

    Allan

Sign In or Register to comment.