Cannot get Editor installed

Cannot get Editor installed

Bob RundleBob Rundle Posts: 4Questions: 1Answers: 0

I cannot get the editor installed. The datatables are working. The editor is not.

Here is the template HTML...

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>{% block title %}Welcome!{% endblock %}</title>
<link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 128 128%22><text y=%221.2em%22 font-size=%2296%22>⚫️</text></svg>">
<link href="/static/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="/static/components/jquery-ui/themes/base/jquery-ui.min.css" rel="stylesheet">
<link href="/static/site/css/base.css?v=1.20220728b" rel="stylesheet">
<link href="https://cdn.datatables.net/v/bs5/dt-1.13.8/b-2.4.2/b-html5-2.4.2/r-2.5.0/rg-1.4.1/rr-1.4.1/sl-1.7.0/datatables.min.css" rel="stylesheet">
<link rel="stylesheet" href="/static/editor-dt/css/editor.dataTables.css">

</head>
<body>
    {% block body %}{% endblock %}
    <script src="/static/components/jquery/jquery.min.js"></script>
    <script src="/static/components/jquery-ui/jquery-ui.min.js"></script>
    <script src="/static/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
    <script src="/static/site/js/base.js?v=1.20220728"></script>
    <script src="/static/site/js/util.js?v=1.20230730"></script>
    <script src="https://cdn.datatables.net/v/bs5/dt-1.13.8/b-2.4.2/b-html5-2.4.2/r-2.5.0/rg-1.4.1/rr-1.4.1/sl-1.7.0/datatables.min.js"></script>
    <script src="/static/editor/js/dataTables.editor.js"></script>
</body>

</html>

After a lot of trouble I got the editor downloaded and moved from node_modules. When I try to initialize the table I get this...

base.js: in document ready
VM173:6181 Uncaught TypeError: Cannot read properties of undefined (reading 'Api')
at <anonymous>:6181:31
at <anonymous>:46:3
at <anonymous>:48:2
at b (jquery.min.js:2:866)
at Function.globalEval (jquery.min.js:2:2905)
at Object.dataFilter (jquery.min.js:2:80720)
at jquery.min.js:2:79185
at l (jquery.min.js:2:79587)
at XMLHttpRequest.<anonymous> (jquery.min.js:2:82355)
at Object.send (jquery.min.js:2:82714)

VM168:2 Uncaught ReferenceError: Editor is not defined
at HTMLDocument.<anonymous> (<anonymous>:48:29)
at e (<anonymous>:2:30038)
at t (<anonymous>:2:30340)

Here is the JS that initializes the editor...

    let contactEditor = new DataTable.Editor({
        ajax: {
            url: listGetUrl
        },
        fields: [
            {
                label: 'Contact Type',
                name: 'contactType',
                type: 'select',
                options: [
                    { label: 'Personal', value: 'personal' },
                    { label: 'Business', value: 'business' }
                ]
            }
        ],
        table: '#contact-table'
    });

There is another piece of code that initializes the data table and that part is working fine.

What am I doing wrong? I've spent the entire afternoon fighting this. I'm ready to give up and ask for my money back.

Regards,
Bob Rundle

This question has an accepted answers - jump to answer

Answers

  • allanallan Posts: 63,464Questions: 1Answers: 10,466 Site admin

    Hi Bob,

    It looks like you might just need to change the order of the scripts. The code is executed in sequence, so at the moment you are attempting to use Editor (in base.js) before actually loading DataTables or Editor. Hence the error.

    Allan

  • Bob RundleBob Rundle Posts: 4Questions: 1Answers: 0

    Thanks Allan. I tried rearranging the code., No luck. Here is the complete JS for my data table test page...

    var contactTable = null;
    
    $(function() {
    $(document).ready(function() {
        console.log('in data_tables/index.js 2222');    
    
        var listGetUrl = $('#list-get-url').val();
        var listColumns = [
            {
                className: 'cc-table-control',
                orderable: false,
                data: null,
                defaultContent: ''
            },
            { data: 'id' },
            { data: 'firstName' },
            { data: 'lastName' },
            { data: 'contactType'},
            { data: 'contactNote'},
            { data: 'phones' }
        ];
    
        var columnDefs = [
            {
                "defaultContent": "",
                "targets": "_all"
            },
            { 
                render: function(data, type, row) {
                    console.log('in render');
                    console.log(data);
                    console.log(type);
                    console.log(row);
                    if(Array.isArray(data) && data.length > 0) {
                        if(data.length == 1) {
                            return  '<div>' + data[0].phoneNumber + '</div>';
                        } else {
                            return "multiple";
                        }
                    } else {
                        return "None"
                    }
                },
                targets: "th-phone"
            }
        ];
    
        // let contactEditor = new DataTable.Editor({
        //     ajax: {
        //         url: listGetUrl
        //     },
        //     fields: [
        //         {
        //             label: 'Contact Type',
        //             name: 'contactType',
        //             type: 'select',
        //             options: [
        //                 { label: 'Personal', value: 'personal' },
        //                 { label: 'Business', value: 'business' }
        //             ]
        //         }
        //     ],
        //     table: '#contact-table'
        // });
        let contactTable = $('#contact-table').DataTable({
            ajax: {
                url: listGetUrl,
                data: {
                    phoneNumber: 123456,
                    name: 'abc'
                }
            },
           //...
            columns: listColumns,
            columnDefs: columnDefs
        });
        console.log('after datatable init');
        console.log(contactTable);
        $('#submit-edits').on('click', function(ev) {
            ev.preventDefault();
            let $form = $(this).closest('form');
            let data = $form.serialize();
            let url = $form.attr('action');
            console.log('in edit contact submit');
            console.log(data);
            console.log(url);
            $.ajax({
                url: url,
                type: 'POST',
                data: data,
                success: function(result) {
                    $('#edit-contact-modal').modal('hide');
                    contactTable.ajax.reload();
                    console.log('in edit contact success');
                    console.log(result);
                },
                error: function(result) {
                    console.log('in edit contact failure');
                    console.log(result);
                }
            })
        });
    
        $('#context-table').on('click', 'td.inline-edit', function() {
    //            contactEditor.inline(this);
        });
    
        $('#contact-table').on('click', 'td.cc-table-control', function () {
            var tr = $(this).closest('tr');
            console.log('in contact-table click on td.cc-table-control');
            console.log(contactTable);
                var row = contactTable.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(detailRowFormat(row.data())).show();
                tr.addClass('shown');
            }
            row.select();
            return false;
        });      
        function detailRowFormat(d) {
            if(Array.isArray(d.phones) && d.phones.length > 0) {
                let html = '<table cellpadding="5" cellspacing="0" border="0" style="padding-left:50px;">';
                d.phones.forEach(function(phone, index) {
                    html += '<tr><td>' + 'Phone (' + (index + 1) + '): ' + '</td>';
                    html += '<td>' + phone.phoneNumber + '</td></tr>';
                });
                html += '</table>';
                return html;
            } else {
                return "None"
            }
        }        
        contactTable.on('init.dt', function() {
            contactTable.buttons(0).text('add');
            console.log($(contactTable.buttons(0)));
            $(contactTable.buttons(0)).attr('data-bs-toggle','modal').attr('data-bs-target','#add-contact-modal');
        });
        contactTable.on('select', function(e,dt,type,indexes) {
            console.log('in select handler, type = ' + type + ', indexes = ' + JSON.stringify(indexes));
            if(indexes.length == 1) {
                dt.buttons(1).enable(true);
            }
        });
        $('#first-name').on('change', function(ev) {
            let v = $(this).val();
            console.log('in change event');
            if(!Util.isValidPersonName(v)) {
                $(this)[0].setCustomValidity('Invalid name for a person. Cannot contain numbers, most special characters and be longer than 64 characters');
            } else {
                $(this)[0].setCustomValidity('');
            }
        });
        $('#add-contact').submit(function(event) {
            event.preventDefault();
            var $form = $(this);
            if($form[0].checkValidity()) {
                var url = $('#add-contact').attr('action');
                var posting = $.post(url, {
                    firstName: $('#first-name').val(),
                    lastName: $('#last-name').val(),
                    phone: $('#phone').val(),
                    phone2: $('#phone2').val()
                });
                posting.done((data) => {
                    console.log('in done: ' + JSON.stringify(data));
                    $('#add-contact-modal').modal('hide');
                    contactTable.ajax.reload();
                })
                posting.fail(() => {
                    console.log('in fail');
                })
            }
            $form.addClass('was-validated');
        });
    });
    });
    

    Note the following:
    1. The data table part is working fine.
    2. The editor code is commented out. If I uncomment it, it throws and so the data table no longer works.
    3. Even when the editor code is commented out, I still get an error...

     VM534:6181 Uncaught TypeError: Cannot read properties of undefined (reading 'Api')
    at <anonymous>:6181:31
    at <anonymous>:46:3
    at <anonymous>:48:2
    at b (jquery.min.js:2:866)
    at Function.globalEval (jquery.min.js:2:2905)
    at Object.dataFilter (jquery.min.js:2:80720)
    at jquery.min.js:2:79185
    at l (jquery.min.js:2:79587)
    at XMLHttpRequest.<anonymous> (jquery.min.js:2:82355)
    at Object.send (jquery.min.js:2:82714)
    
    1. If I comment out this line...

          <script src="/static/editor/js/dataTables.editor.js"></script>
      

    the error goes away. So it seems there is something fundamentally wrong with dataTables.editor.js

    Here is the way my test table looks....

    What I am trying to accomplish is inline edit of type column from select and inline editor of note column.

  • allanallan Posts: 63,464Questions: 1Answers: 10,466 Site admin
    Answer ✓

    Are you able to give me a link to the page so I can trace it through and identify what the issue is please?

    Allan

  • Bob RundleBob Rundle Posts: 4Questions: 1Answers: 0

    Ok Allan. This is on me. :) I was in the process of setting up a website for you to examine when I discovered the problem. I was using the test scaffold that I used to test the original data tables implementation that I did 2 years ago. What I did not take into account is that this test scaffold has some experimental page loading logic. So when I invoked the "Data Tables" navigation item from the top of the test scaffold the experimental page loading logic loaded the data tables page with the Editor code on it.

    One of the quirks of the page loading logic is that it effectively bypasses the document ready event. So I have a feeling that the document ready event is critical to proper setup of the data table editor. Interestingly, it doesn't impact the data tables themselves.

    So my editor is now loading. It is still not working, but I think these are normal problems that I figure out on my own.

    Let me take a moment to complain about how inadequate the installation documentation and code are for the editor. I realize there are a million different possible configurations and it is very difficult to address all scenarios. Yet the way you have done it is simply inadequate. Even the example code is not helpful. I got the NodeJS example working, but when I examine the code to figure out which files to include on my web page, I discover that the example code is an unbelievably complex setup and I simply cannot figure out which files to include if, for example, I am using JQuery and Bootstrap 5.

    Anyway thanks for the help.
    Bob Rundle

  • allanallan Posts: 63,464Questions: 1Answers: 10,466 Site admin

    Hi Bob,

    I'm really sorry that the documentation haven't been good for you. The best way to make sure you get the files you need is to use the download builder. Select the parts you want (normally DataTables, Buttons, Editor and Select are the minimum if you want an editable DataTable), select the style you want and it will give you either single JS / CSS files, or npm packages to install.

    Picking the files out manually is a real pain, which is why the download builder exists. There are so many combinations, just on this software, and that isn't even considering things like experimental page loading.

    I'd welcome some feedback on what you would prefer the documentation to be shaped like. I'll never manage to get the documentation perfect for everyone, but I can try!

    Glad to hear you've got it up and running now!

    Allan

  • Bob RundleBob Rundle Posts: 4Questions: 1Answers: 0

    Yes, I have used the download builder to create my data tables includes. I didn't realize that it would work with the Editor as well. After all the download builder is a blue page and therefore I didn't think it was relevant to Editor which is only documented on red pages. So I'll try that.

    Since you brought up the download builder, let me take this opportunity to bitch about that: the download builder has no concept of upgrading. For example, what if I used download builder and then some time later wanted to add a data table feature, say row reorder. I first have to play games with the download builder to figure exactly which options I used to create the original set of includes. This is trial and error. I click and click and click until I can match the current include that I am using. Not fun. Why don't you have a field on the page where I can paste my previous download builder results and you can set the proper checks?

  • kthorngrenkthorngren Posts: 21,303Questions: 26Answers: 4,947
    edited October 7

    Open the CDN URL or the downloaded files and you will find a link to the Download Builder with the selected options to allow for adding to and updating to the latest versions.

    Kevin

  • kthorngrenkthorngren Posts: 21,303Questions: 26Answers: 4,947

    Maybe @allan can add a note to the download builder about this.

    Kevin

  • allanallan Posts: 63,464Questions: 1Answers: 10,466 Site admin

    That sounds like a good addition to the documentation - thank you Kevin and Bob. When I next deploy the site it will include the following just above where the options start:

    If you are upgrading an old version of a DataTables CDN or downloaded file created by this download builder and want to use the same build options with the latest versions, look in the JS file header and you'll find a URL that will automatically select the options needed.

    Allan

Sign In or Register to comment.