Manipulating Delete's rows list

Manipulating Delete's rows list

womplifywomplify Posts: 30Questions: 3Answers: 0
edited January 2015 in Editor

I have the following issue..
I have a table of items. Some items are (or rather, should-be) "delete protected".
I am not aware of any such inherit mechanism in DataTables.. so I thought of implementing this myself.

Right now, I allow multiple rows to be selected (with tableTools:{sRowSelect: "os"}), and I have a delete button in the tableTools' section ({ sExtends: "editor_remove", editor: Lists_Editor })
This works just fine for regular rows that are allowed to be deleted.
However, if I also select a row that should not be deleted (and indeed it wont get deleted from the DB anyway), I need to remove this row from the list of items to be deleted, and when the server responds with "Success" for the items that were indeed deleted, I need only the "other" rows to be deleted.
Also, if only one row is selected, and this row is delete-protected, I need to simply abort the deletion.

I implement ajax based approach, using a function.
Am I correct? Is it the right approach? OR should I avoid using tableTools' automatic use of "editor_remove" and implement my own removal procedure?

In case I can still use "editor_remove", the way I thought of going about this is this...
in the editor, I use: {ajax: function ( method, url, data, successCallback, errorCallback ) ...}
In this function, I check else if ( data.action === 'remove' )
If it is, I then check if any of the items in the data.id array are protected.
Those that are not, if there are any, I send for deletion, with an ajax call to the server, which returns 1 on successful deletion.

HOWEVER, this only ensures that I don't try to delete the protected rows. The problem is that upon a successful deletion, it "looks" as if the protected row was deleted, as it hides it, even though I didn't send it to the server.
Changing the content of data.id and removing from it the id, does NOT have any affect, and the protected row still gets removed from the table (until the next page refresh shows it again, as it is still in the DB).
I also thought of trying to remove the protected row/s from the list of items to be deleted, by using the : on("initRemove", function(e, node, data )... event. But here as well, I can see which rows are about to be deleted, but I can't manipulate the list.

Any ideas what I can do? How can I manipulate the deletion list? Or are there better ways to protect rows from being deleted?

Replies

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

    I would suggest not using editor_remove - or rather, you could, but replace the default fnClick method with your own that will loop over the selected rows (which you can get using the TableTools API) and decide which ones you want to pass to Editor to delete. When you have those items use the remove() method to delete them.

    I think trying to manipulate the default button is going to get really messy - it will be much cleaner just to use the API!

    Allan

  • womplifywomplify Posts: 30Questions: 3Answers: 0

    there is no way to "deselect" a row (remove from the deletion list), just prior to editor_remove's being called? I guess that is a general question - how do I "select" and "deselect" a row from the tabletool's selection set, via the API? Manipulating the "active" class, doesn't seem to be "it"

  • womplifywomplify Posts: 30Questions: 3Answers: 0

    I actually found out how.. realizing it was part of TableTools..

            Lists_Editor.on("initRemove", function(e, node, data ){
                node.forEach(function(nodeInstance) {
                    var row = Lists_DataTable.DataTable().row($(nodeInstance));
                    if (row.data().isProtected== 1) {
                        TableTools.fnGetInstance('lists').fnDeselect(nodeInstance);
                    }
                });
            });
    

    HOWEVER, while it DOES delselect the protected row, it does NOT have effect on the delete list. fnGetSelected() does NOT include the deleted for, but the list of items to be deleted still includes it, later on in the actual deletion event. Is that how it is supposed to be? Wouldn't it be nice if initRemove actually allowed manipulating the list?

  • womplifywomplify Posts: 30Questions: 3Answers: 0

    To explain my motive, btw, I am trying to avoid not using the default button, because it is more elegant using a default mechanism, and not having to create a custom button that I also have to write the behavior of, for enabling/disabling based on whether or not there are selected rows.

  • womplifywomplify Posts: 30Questions: 3Answers: 0
    edited January 2015

    and while at it, I think I found a bug.. or maybe I just don't understand the documentation..
    preOpen event claims to be cancellable.
    https://editor.datatables.net/reference/event/preOpen
    However, when I return false, it does NOT cancel the remove form's open, but rather just goes ahead and shows it.

            Lists_Editor.on("preOpen", function(e){
                if (e.target.s.action === "remove")
                {
                    console.log("cancelling");
                    return(false);
                }
            });
    

    The above code DOES show "cancelling" printed out in the log. So I do indeed return false. But as I said, it still opens the form.

    Am I missing something?

  • womplifywomplify Posts: 30Questions: 3Answers: 0
    edited January 2015

    I ended up doing this...

                initComplete: function(e, settings, json){
                    Lists_TableTools = TableTools.fnGetInstance('lists');
                    
                    $("#ToolTables_lists_2").off('click').click(function(){
                        var Dropped = false;
                        Lists_TableTools.fnGetSelected().forEach(function(nodeInstance) {
                            var row = Lists_DataTable.DataTable().row($(nodeInstance));
                            if (row.data().isDefault == 1) {Lists_TableTools.fnDeselect(nodeInstance); Dropped = true;}
                        });
    
                        if (Dropped)
                        {
                            if (Lists_TableTools.fnGetSelected().length > 0)
                            {
                                $.smallBoxCountdown({
                                    title     : "Default List Delete Not Allowed",
                                    content   : "You can't delete a default list. Will delete only non-Default lists...",
                                    color     : "#c69021",
                                    iconSmall : "fa fa-2x fa-shield bounce animated",
                                    timeout   : 15*1000,
                                });
                                var Buttons = TableTools.BUTTONS.editor_remove.formButtons;
                                Buttons[0].label = Lists_Editor.i18n.remove.submit;
                                Lists_Editor
                                    .title(Lists_Editor.i18n.remove.title)
                                    .message(Lists_Editor.i18n.remove.confirm[Lists_TableTools.fnGetSelected().length==1?'1':'_'].replace('%d',Lists_TableTools.fnGetSelected().length))
                                    .buttons(Buttons)
                                    .remove(Lists_TableTools.fnGetSelected());
                            }
                            else
                            {
                                $.smallBoxCountdown({
                                    title     : "Default List Delete Not Allowed",
                                    content   : "You can't delete a default list. Deletion aborted.",
                                    color     : "#C46A68",
                                    iconSmall : "fa fa-2x fa-shield bounce animated",
                                    timeout   : 15*1000,
                                });
                            }
                        }
                    });
                },
    

    The important parts are..
    1. Built-in button behavior override..

    $("#ToolTables_lists_2").off('click').click(function()...
    

    where I disable the built-in click event for the delete button, and replace it with my own. That way I can have the built-in delete button behavior already set..

    1. TableTools built-in selection process..
    Lists_TableTools.fnGetSelected().forEach(function(nodeInstance) {
        var row = Lists_DataTable.DataTable().row($(nodeInstance));
        if (row.data().isDefault == 1) {Lists_TableTools.fnDeselect(nodeInstance); Dropped = true;}
    });
    

    Where this code removes all protected rows (in my case, those with isDefault value of 1) from the TableTools' selection, so I don't have to manage my own selection.

    1. delete's default settings
    var Buttons = TableTools.BUTTONS.editor_remove.formButtons;
    Buttons[0].label = Lists_Editor.i18n.remove.submit;
    Lists_Editor
        .title(Lists_Editor.i18n.remove.title)
        .message(Lists_Editor.i18n.remove.confirm[Lists_TableTools.fnGetSelected().length==1?'1':'_'].replace('%d',Lists_TableTools.fnGetSelected().length))
        .buttons(Buttons)
        .remove(Lists_TableTools.fnGetSelected());
    

    Using my Lists_Editor's i18n records and TableTools.BUTTONS.editor_remove.formButtons I don't have to redefine the buttons for the form. That saves me headache regarding the formatting of the for.
    Note that I have to use TableTools.BUTTONS.editor_remove.formButtons, for the tools' remove form buttons, but then override the label from my i18n record (as the one built in comes without a pre-set label), and then also have to set the message and do a js .replace call to change the '%d' part of the string with the actual row count for deletion.

    So... this is the least elegant of the implementation.
    I wish I could just call

    Lists_Editor`.remove(Lists_TableTools.fnGetSelected());
    

    where it would handle on its own title, message and buttons part of the formatting, like the TableTool's default delete button does. That way I wouldn't have to mess about with i18n, buttons or singular/plural conditional formatting myself.
    ** IS There a way to do that somehow? **

    OR

    as I originally hoped, if there was a way to just manipulate the selection before the button is clicked and rely on the inherit functionality of the default button.
    Any help improving the above will be greatly appreciated.

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

    To explain my motive, btw, I am trying to avoid not using the default button, because it is more elegant using a default mechanism

    In some cases that might be true, but I think in this case, where you are trying to do something outside the bounds of what the default button was designed to do, it would be more elegant to create a little custom button. It is designed to be extensible for this reason - the default buttons are only meant to cover the most common cases!

    What you could do is basically copy the code for Editor's editor_remove button to create your new button - add the modification needed to pass in only the rows to be deleted to remove() and call it done.

    The other option would be to add another option to the button which would provide the ability to filter the list of selected rows before it get passed to remove(), although that would involve altering the library code.

    Allan

This discussion has been closed.