Problem: Unknown button type: print at datatables.min.js:231:120

Problem: Unknown button type: print at datatables.min.js:231:120

TomBajzekTomBajzek Posts: 163Questions: 36Answers: 1

My Datatables application requires either Edit and New buttons, or just the New button, depending on the user's role. I attempted to replace the generated buttons with an anonymous function that returns one or both buttons as needed. When I run this, I get en error:

Problem: Unknown button type: print at datatables.min.js:231:120

Am I going about this the wrong way, or have I coded the function incorrectly? My editor definition is below, with the original buttons commented out and the failing replacement code immediately after that, about 135 lines into this.

The code from the debugger is 'ocufay'.

Thanks,
Tom

/*
 * Editor client script for DB table tickets
 * Created by http://editor.datatables.net/generator
 */

(function($){

    $(document).ready(function() {

        // Define the editor for IT Tickets 
        var ticketEditor = new $.fn.dataTable.Editor( {
            ajax: 'php/table.tickets.php',
            table: '#tickets',
            formOptions: {
                main: {
                    submit: 'changed'
                }
            },
            fields: [
                {
                    label:  "created",
                    name:   "tickettime",
                    type:   "readonly"
                },
                {
                    label: "updated:",
                    name: "updated",
                    type: "readonly"
                },
                {
                    label: "status:",
                    name: "status",
                    type: "select",
                    placeholder: "- Select status -",
                    options: [
                        "closed",
                        "holding",
                        "in progress",
                        "in  queue",
                        "unseen",
                        "urgent"
                    ],
                    def: "unseen"
                },
                {
                    label: "responder:",
                    name: "responder",
                    type: "select",
                    placeholder: "- Select responder -",
                    options: [
                        "CZ",
                        "ES",
                        "KD",
                        "LM",
                        "TB"
                    ]
                },
                {
                    label: "originator:",
                    name: "email"
                },
                {
                    label: "category:",
                    name: "category",
                    type: "select",
                    placeholder: "- Select category -",
                    options: [
                        "computer",
                        "disk",
                        "documentation",
                        "phone",
                        "printer/copier",
                        "network",
                        "server",
                        "software",
                        "wiring"
                    ]
                },
                {
                    label: "description:",
                    name: "description",
                    type: "textarea"
                }
            ]
        } );

        // Define the layout for the ticket table 
        var ticketTable = $('#tickets').DataTable( {
            dom: 'Bflrtip',
            order: [[3,"desc"]],
            ajax: 'php/table.tickets.php',
            columns: [
                {
                    data: "id"
                },
                {
                    data: "tickettime",
                    className: "tStamp"
                },
                {
                    data: "updated",
                    className: "tStamp"
                },
                {
                    data: "status",
                    className: " prose cFilter"
                },
                {
                    data: "responder",
                    className: " prose cFilter"
                },
                {
                    data: "email",
                    className: " prose cFilter"
                },
                {
                    data: "category",
                    className: " prose cFilter"
                },
                {
                    data: "description",
                    className: " moreF"
                }
            ],
            select: {
                style: 'single'
            },
            lengthChange: true,
            drawCallback: function(settings){
                $('.moreF').more();
            },
//          buttons: [
//              { extend: 'create', editor: ticketEditor },
//              { extend: 'edit',   editor: ticketEditor }
//          ],
            buttons: function() {
                    if ($('#itRole').attr('data-itRole') === 'tech' ||
                        $('#itRole').attr('data-itRole') === 'manager') {
                        return [
                            { extend: 'create', editor: ticketEditor },
                            { extend: 'edit',   editor: ticketEditor }
                        ];
                    } else {
                        return [
                            { extend: 'create', editor: ticketEditor }
                        ];
                    }
            },

            // Set-up column filtering for data columns
            initComplete: function () {
                this.api().columns('.cFilter').every( function () {
                    var column = this;
                    var select = $('<select><option value=""></option></select>')
                        .appendTo( $(column.header()) )
                        .on( 'change', function () {
                            var val = $.fn.dataTable.util.escapeRegex(
                                $(this).val()
                            );
                            column
                                .search( val ? '^'+val+'$' : '', true, false )
                                .draw();
                        } );
                        column
                            .cache( 'search' )
                            .sort()
                            .unique()
                            .each( function ( d ) {
                                select.append( $('<option value="'+d+'">'+d.substr(0,15)+'</option>') );
                    } );
                } );
            }
        } );
        
    

        // Define area for Ticket table buttons 
        ticketTable.buttons().container()
            .appendTo( $('.col-sm-6:eq(0)', ticketTable.table().container() ) );
    
        // Define the Editor for Notes 
        var noteEditor = new $.fn.dataTable.Editor( {
            ajax: {
                url: 'php/table.notes.php',
                data: function(d) {
                    var selected = ticketTable.row( { selected : true} );
                    if (selected.any()) {
                        d.ticket= selected.data().id;
                    }
                }
            },
            table: '#notes',
            fields: [
                {
                    label: "ticket #",
                    name: "notes.ticket_id",
                    type: "select",
                    placeholder: "Select a ticket Id"
                    
                },
                {
                    label: "commenter:",
                    name: "notes.email"
                },
                {
                    label: "content:",
                    name: "notes.content",
                    type: "textarea"
                },
                {
                    label: "resolved?:",
                    name: "notes.resolved",
                    type: "select",
                    placeholder: "yes/no",
                    options: [
                        "no",
                        "yes"
                    ],
                    default: "no"
                }
            ]
        } );

        // Define the table for displaying Notes
        // This table remains hidden unless the selected ticket has note 
        var noteTable = $('#notes').DataTable( {
            ajax: {
                url: 'php/table.notes.php',
                dom: 'Brit',
                type: "post",
                data: function(d) {
                    var selected = ticketTable.row( {selected: true} );
                    if (selected.any()) {
                        d.ticket = selected.data().id;
                        $('#noteDiv').show();   // show notes div here
                    } else {
                        $('#noteDiv').hide();   // hide notes div here if none selected
                    }   
                }
            },
            paging: false,
    //      display: "none",
        
            order: [[0,"desc"]],
            columns: [
                {
                    data: "notes.created",
                    className: "tStamp",
                    orderable: false
                },
                {
                    data: "tickets.id",
                    className: "narrow",
                    orderable: false
                },
                {
                    data: "notes.email",
                    className: "narrow",
                    orderable: false
                },
                {
                    data: "notes.resolved",
                    className: "narrow",
                    orderable: false
                },
                {
                    data: "notes.content",
                    className:" moreF",
                    orderable: false
                }
            ],
            select: true,
            lengthChange: false
        } );

        // Define Note Editor buttons (Only New button is used)
        new $.fn.dataTable.Buttons( noteTable, [
            { extend: "create", editor: noteEditor }
        ] );


        // Define container for Note Editor buttons 
            noteTable.buttons().container()
            .appendTo( $('.col-sm-6:eq(0)', noteTable.table().container() ) );

        // Select/deselect related notes when a ticket is selected      ticketTable.on( 'select', function () { 
        ticketTable.on( 'select', function () { 
            noteTable.ajax.reload();
    
            noteEditor
                .field( 'notes.ticket_id' )
                .def( ticketTable.row( { selected: true } ).data().id);
        } );

        ticketTable.on( 'deselect', function () {
            noteTable.ajax.reload();
        } );

        // Now refresh Tickets or Notes when the Other one is saved 
        noteEditor.on( 'submitSuccess', function () {
            ticketTable.ajax.reload();
        } );
    
        ticketEditor.on( 'submitSuccess', function () {
            noteTable.ajax.reload();
        } );
    
    
    } );
}(jQuery));

This question has accepted answers - jump to:

Answers

  • kthorngrenkthorngren Posts: 20,329Questions: 26Answers: 4,774

    Can you create two button constructor functions like you have for the noteTable table and use the if statement to select which to use?

    Kevin

  • allanallan Posts: 61,744Questions: 1Answers: 10,111 Site admin

    You should be able to yes - the buttons can be defined as a function that will be executed and resolved to configuration objects.

    What I don't understand is why Buttons is complaining about the print button, when it doesn't appear that you've referenced the print button at all in the above code. However, it might be worth trying to include the print button type and see if that helps.

    Allan

  • TomBajzekTomBajzek Posts: 163Questions: 36Answers: 1

    I've tried both of these suggestions without success. It turns out that any change I've come up with that uses anything other than the buttons[ ] array in the DataTable definition for the ticketTable fails with either the error reported here or with a similar error

    TypeError: undefined is not an object (evaluating 'b.buttons') in datatables.min.js:219:473

    I've tried the closure function that returns the desired buttons that I described above, and the button constructor recommended above by kthorngren. I've also just tried these without wrapping them in conditionals, just to see if that would work, as well as some other attempts at using the button constructor function. However, all of these attempts have failed.

    I constructed a trivial test-case using the Generator, which uses the button constructor function method, and this worked. This works, even when I use the button constructors inside a conditional, so the conditional does not seem to the be the issue. I cannot see a structural difference between that case and the cases that fail, except for a great deal of complexity in the surrounding code.

    The button array is commented out at lines 132 - 136, and the button construction function is a lines 163 - 166. (I've simplified the example by removing the conditional, which shows that the conditional is not part of the problem.)

    The debugger code for this example is ilizip.

    Here is the code:

    /*
     * Editor client script for DB table tickets
     * Created by http://editor.datatables.net/generator
     */
    
    (function($){
    
        $(document).ready(function() {
    
            // Define the editor for IT Tickets 
            var ticketEditor = new $.fn.dataTable.Editor( {
                ajax: 'php/table.tickets.php',
                table: '#tickets',
                formOptions: {
                    main: {
                        submit: 'changed'
                    }
                },
                fields: [
                    {
                        label:  "created",
                        name:   "tickettime",
                        type:   "readonly"
                    },
                    {
                        label: "updated:",
                        name: "updated",
                        type: "readonly"
                    },
                    {
                        label: "status:",
                        name: "status",
                        type: "select",
                        placeholder: "- Select status -",
                        options: [
                            "closed",
                            "holding",
                            "in progress",
                            "in  queue",
                            "unseen",
                            "urgent"
                        ],
                        def: "unseen"
                    },
                    {
                        label: "responder:",
                        name: "responder",
                        type: "select",
                        placeholder: "- Select responder -",
                        options: [
                            "CZ",
                            "ES",
                            "KD",
                            "LM",
                            "TB"
                        ]
                    },
                    {
                        label: "originator:",
                        name: "email"
                    },
                    {
                        label: "category:",
                        name: "category",
                        type: "select",
                        placeholder: "- Select category -",
                        options: [
                            "computer",
                            "disk",
                            "documentation",
                            "phone",
                            "printer/copier",
                            "network",
                            "server",
                            "software",
                            "wiring"
                        ]
                    },
                    {
                        label: "description:",
                        name: "description",
                        type: "textarea"
                    }
                ]
            } );
    
            // Define the layout for the ticket table 
            var ticketTable = $('#tickets').DataTable( {
                dom: 'Bflrtip',
                order: [[3,"desc"]],
                ajax: 'php/table.tickets.php',
                columns: [
                    {
                        data: "id"
                    },
                    {
                        data: "tickettime",
                        className: "tStamp"
                    },
                    {
                        data: "updated",
                        className: "tStamp"
                    },
                    {
                        data: "status",
                        className: " prose cFilter"
                    },
                    {
                        data: "responder",
                        className: " prose cFilter"
                    },
                    {
                        data: "email",
                        className: " prose cFilter"
                    },
                    {
                        data: "category",
                        className: " prose cFilter"
                    },
                    {
                        data: "description",
                        className: " moreF"
                    }
                ],
                select: {
                    style: 'single'
                },
                lengthChange: true,
                drawCallback: function(settings){
                    $('.moreF').more();
                },
    //          buttons: [
    //              { extend: 'create', editor: ticketEditor },
    //              { extend: 'edit',   editor: ticketEditor },
    //              { extend: 'remove', editor: ticketEditor }          
    //          ],
    
                // Set-up column filtering for data columns
                initComplete: function () {
                    this.api().columns('.cFilter').every( function () {
                        var column = this;
                        var select = $('<select><option value=""></option></select>')
                            .appendTo( $(column.header()) )
                            .on( 'change', function () {
                                var val = $.fn.dataTable.util.escapeRegex(
                                    $(this).val()
                                );
                                column
                                    .search( val ? '^'+val+'$' : '', true, false )
                                    .draw();
                            } );
                            column
                                .cache( 'search' )
                                .sort()
                                .unique()
                                .each( function ( d ) {
                                    select.append( $('<option value="'+d+'">'+d.substr(0,15)+'</option>') );
                        } );
                    } );
                }
            } );
            
            new $.fn.dataTable.Buttons( ticketTable, [
                { extend: "create", editor: ticketEditor },
                { extend: "edit", editor: ticketEditor }
            ] );
    
        
            // Define area for Ticket table buttons 
            ticketTable.buttons().container()
                .appendTo( $('.col-sm-6:eq(0)', ticketTable.table().container() ) );
        
            // Define the Editor for Notes 
            var noteEditor = new $.fn.dataTable.Editor( {
                ajax: {
                    url: 'php/table.notes.php',
                    data: function(d) {
                        var selected = ticketTable.row( { selected : true} );
                        if (selected.any()) {
                            d.ticket= selected.data().id;
                        }
                    }
                },
                table: '#notes',
                fields: [
                    {
                        label: "ticket #",
                        name: "notes.ticket_id",
                        type: "select",
                        placeholder: "Select a ticket Id"
                        
                    },
                    {
                        label: "commenter:",
                        name: "notes.email"
                    },
                    {
                        label: "content:",
                        name: "notes.content",
                        type: "textarea"
                    },
                    {
                        label: "resolved?:",
                        name: "notes.resolved",
                        type: "select",
                        placeholder: "yes/no",
                        options: [
                            "no",
                            "yes"
                        ],
                        default: "no"
                    }
                ]
            } );
    
            // Define the table for displaying Notes
            // This table remains hidden unless the selected ticket has note 
            var noteTable = $('#notes').DataTable( {
                ajax: {
                    url: 'php/table.notes.php',
                    dom: 'Brit',
                    type: "post",
                    data: function(d) {
                        var selected = ticketTable.row( {selected: true} );
                        if (selected.any()) {
                            d.ticket = selected.data().id;
                            $('#noteDiv').show();   // show notes div here
                        } else {
                            $('#noteDiv').hide();   // hide notes div here if none selected
                        }   
                    }
                },
                paging: false,
        //      display: "none",
            
                order: [[0,"desc"]],
                columns: [
                    {
                        data: "notes.created",
                        className: "tStamp",
                        orderable: false
                    },
                    {
                        data: "tickets.id",
                        className: "narrow",
                        orderable: false
                    },
                    {
                        data: "notes.email",
                        className: "narrow",
                        orderable: false
                    },
                    {
                        data: "notes.resolved",
                        className: "narrow",
                        orderable: false
                    },
                    {
                        data: "notes.content",
                        className:" moreF",
                        orderable: false
                    }
                ],
                select: true,
                lengthChange: false
            } );
    
            // Define Note Editor buttons (Only New button is used)
            new $.fn.dataTable.Buttons( noteTable, [
                { extend: "create", editor: noteEditor }
            ] );
    
    
            // Define container for Note Editor buttons 
                noteTable.buttons().container()
                .appendTo( $('.col-sm-6:eq(0)', noteTable.table().container() ) );
    
            // Select/deselect related notes when a ticket is selected      ticketTable.on( 'select', function () { 
            ticketTable.on( 'select', function () { 
                noteTable.ajax.reload();
        
                noteEditor
                    .field( 'notes.ticket_id' )
                    .def( ticketTable.row( { selected: true } ).data().id);
            } );
    
            ticketTable.on( 'deselect', function () {
                noteTable.ajax.reload();
            } );
    
            // Now refresh Tickets or Notes when the Other one is saved 
            noteEditor.on( 'submitSuccess', function () {
                ticketTable.ajax.reload();
            } );
        
            ticketEditor.on( 'submitSuccess', function () {
                noteTable.ajax.reload();
            } );
        
        
        } );
    }(jQuery));
    
    

    Thanks for looking at this,
    Tom

  • kthorngrenkthorngren Posts: 20,329Questions: 26Answers: 4,774

    Interesting. I init all my buttons using the constructor method, even with parent/child tables like yours. I wonder if the tickets table is not loaded yet thus ticketsTable undefined when the constructor executes. Wonder if putting the constructor in initComplete would help.

    KEvin

  • TomBajzekTomBajzek Posts: 163Questions: 36Answers: 1

    Thanks for the quick response. I hadn't thought of that possibility, and it seems plausible. Alas, when I tried it, it made no difference.

  • kthorngrenkthorngren Posts: 20,329Questions: 26Answers: 4,774
    edited April 2017

    Wonder if its a bug in the Buttons extension. Are you using the latest version? I think its 1.3.1.

    EDIT: Maybe remove the Editor buttons and add one of the export buttons as a test.

    Kevin

  • allanallan Posts: 61,744Questions: 1Answers: 10,111 Site admin
    Answer ✓

    If you are going for the constructor method, remove the B from:

    dom: 'Bflrtip',

    Allan

  • TomBajzekTomBajzek Posts: 163Questions: 36Answers: 1

    Allan,

    Doing this eliminates the error. Unfortunately, no buttons appear. I'm not sure what to do next.

    Also, in relation to the advice from kthorngren, how would I determine the version of buttons that I am running? I built this by doing a Generator download several weeks ago, but I didn't pay attention to the button info when I configured it.

    Thanks,
    Tom

  • allanallan Posts: 61,744Questions: 1Answers: 10,111 Site admin
    Answer ✓

    The '.col-sm-6:eq(0)' selector probably isn't finding anything. Remove the dom option entirely as it is overriding the default for the Bootstrap styling.

    Allan

  • allanallan Posts: 61,744Questions: 1Answers: 10,111 Site admin
    Answer ✓

    how would I determine the version of buttons that I am running

    $.fn.dataTable.Buttons.version on the console, or the debugger.

    Allan

  • TomBajzekTomBajzek Posts: 163Questions: 36Answers: 1

    Great! Removing the DOM-option made the buttons appear. That's what I need!

    I see that I have 1.2.4 of buttons. How would I get a newer version?

    Thanks,
    Tom

  • TomBajzekTomBajzek Posts: 163Questions: 36Answers: 1

    i think I fond the anger. I was looking in the wrong places.

This discussion has been closed.