How to edit all rows except one ?

How to edit all rows except one ?

Vincent GodéVincent Godé Posts: 12Questions: 2Answers: 0

Hello,

I would like to edit all others rows of my Datatable when I click on the checkbox of one of them.
I followed the example https://datatables.net/blog/2014-09-09.
This is my code :

            editorFiles = new $.fn.dataTable.Editor( {
                ajax: "{{ url('route_files_infos_create_read_update_delete') }}",
                table: "#dataTableFiles",
                fields: [ 
                    {
                        label: "File",
                        name: "file_tmp_id",
                        type: "upload"
                    }
                ],
            } );

           var dataTableFiles = $('#dataTableFiles').DataTable({
                dom: "Bfrtip",
                ajax: "{{ url('route_files_infos_create_read_update_delete') }}",
                columns: [
                    {
                        data: "is_selected",
                        render: function ( data, type, row ) {
                            if ( type === 'display' ) {
                                return '<input type="checkbox" class="editor-active">';
                            }
                            return data;
                        },
                        className: "dt-body-center"
                    },
                    { 
                        data: "file_tmp_id", 
                        render: function (fileId) {
                            html = '';
                            if (fileId) {
                                html = editorFiles.file('file_tmp', fileId).filename;
                            } 
                            return html;
                        }
                    }
                ],
                order: [1, 'asc'],
                select: {
                    style: 'os',
                    selector: 'td:not(:first-child)'
                },
                buttons: [
                    { extend: "create", editor: editorFiles, className: "btn btn-secondary buttons-create buttons-html5" },
                    { extend: "edit",   editor: editorFiles, className: "btn btn-secondary buttons-edit buttons-html5" },
                    { extend: "remove", editor: editorFiles, className: "btn btn-secondary buttons-remove buttons-html5" }
                ],
                serverSide: true,
                processing: true,
                rowCallback: function ( row, data ) {
                    $('input.editor-active', row).prop( 'checked', data.is_selected == 1 );
                }
            });
            $('#dataTableFiles').on('change', 'input.editor-active', function () {
               indexes = dataTableFiles.rows().indexes();
               editorFiles.edit(indexes, false);
               editorFiles.val('is_selected', 0);
               editorFiles.submit();
            });

Currently, when I click on one of the checkbox, all checkboxes are "is_selected" set to 0. And I would like set all, expect the one I clicked (I want to set it to 1).

Can you help me ?

Thanks

This question has an accepted answers - jump to answer

Answers

  • allanallan Posts: 61,822Questions: 1Answers: 10,127 Site admin

    I think the way to do this is to get the indexes as you have done, and then remove (splice()) out the index for the row that was clicked on - e.g.:

     $('#dataTableFiles').on('change', 'input.editor-active', function () {
        let indexes = dataTableFiles.rows().indexes();
        let rowIdx = dataTableFiles.row($(this).closest('tr')[0]).index();
        let pos = indexes.indexOf(rowIdx);
    
        indexes.splice(pos, 1);
    
        editorFiles.edit(indexes, false);
        editorFiles.val('is_selected', 0);
        editorFiles.submit();
     });
    

    That should do it. You probably also want to add a callback function into the submit() call to set the is_selected value to 1 for the selected row. This should be done in a callback to let the other operation complete first.

    Allan

  • Vincent GodéVincent Godé Posts: 12Questions: 2Answers: 0

    Allan,

    Thanks for your help.
    This solution seems pleasant, but unfortunately it doesn't work. The clicked row is successfully excluded from the indexes array by indexes.splice(pos, 1);, but all rows are "is_slected" set to 0 (I really don't understand why).

    I also added a callback in the submit like this :

    $('#dataTableFiles').on('change', 'input.editor-active', function () {
                    let indexes = dataTableFiles.rows().indexes();
                    let rowIdx = dataTableFiles.row($(this).closest('tr')[0]).index();
                    let pos = indexes.indexOf(rowIdx);
                    indexes.splice(pos, 1);
                    console.log(indexes);
                    editorFiles.edit(indexes, false);
                    editorFiles.val('is_selected', 0);
                    editorFiles.submit(function () {
                        editorFiles.edit($(this).closest('tr'), false);
                        editorFiles.val('is_selected', 1);
                        editorFiles.submit();
                    });
                } );
    

    But the result is still : all rows are "is_selected" set to 0 :neutral: .
    Do you see something wrong in this code ?

    Thanks a lot

  • allanallan Posts: 61,822Questions: 1Answers: 10,127 Site admin

    editorFiles.edit($(this).closest('tr'), false);

    Won't work - this is not the original element. It is probably window there Try:

     editorFiles.edit(pos, false);
    

    Allan

  • Vincent GodéVincent Godé Posts: 12Questions: 2Answers: 0
    edited February 2021

    Allan,

    Thanks for your answers, but the result still : all rows are "is_selected" set to 0.
    I tried these others things, which seems to be the same things at the end, but in any case all my rows still "is_selected" set to 0 :

    $('#dataTableFiles').on('change', 'input.editor-active', function () {
        let indexes = dataTableFiles.rows().indexes();
        let rowIdx = dataTableFiles.row($(this).closest('tr')[0]).index();
        let pos = indexes.indexOf(rowIdx);
        editorFiles.edit(indexes, false);
        editorFiles.val('is_selected', 0);
        editorFiles.submit(function () {
            editorFiles.edit(pos, false);
            editorFiles.val('is_selected', 1);
            editorFiles.submit();
        });
    } );
    
    $('#dataTableFiles').on('change', 'input.editor-active', function () {
        let indexes = dataTableFiles.rows().indexes();
        let rowIdx = dataTableFiles.row($(this).closest('tr')[0]).index();
        let pos = indexes.indexOf(rowIdx);
        indexes.splice(pos, 1);
        editorFiles.edit(indexes, false);
        editorFiles.val('is_selected', 0);
        editorFiles.submit();
    } );
    

    I also try to replace editorFiles.val('is_selected', 1); by editorFiles.set('is_selected', 1); (I don't really understand the whole difference between set() and val() :blush: ), but the result is still the same.

    Furthermore, I just discovered another thing, when I try to submit a value 0 (with editorFiles.val('is_selected', 0);), the value actually send to the database is "" (empty string). And I got the error : An SQL error occurred: SQLSTATE[HY000]: General error: 1366 Incorrect integer value: '' for column 'is_selected' at row 1. This is why my clicked row is never checked.
    I saw the error, but I don't understand why my integer zero value is transformed to empty string.

    Does it forbidden to submit an integer zero value with the https://editor.datatables.net/reference/api/val() function ?

    Thanks

  • Vincent GodéVincent Godé Posts: 12Questions: 2Answers: 0
    edited February 2021

    I just found why I got the Incorrect integer value, it was because I needed to edit my editorFiles by :

    editorFiles = new $.fn.dataTable.Editor( {
         ajax: "{{ url('route_files_infos_create_read_update_delete') }}",
         table: "#dataTableFiles",
         fields: [
              label: "Is selected",
              name: "is_selected",
              type:  "radio",
                   options: [
                        { label: 'No',  value: 0 },
                        { label: 'Yes', value: 1 },
                   ],
              def: 1
             {
                 label: "File",
                 name: "file_tmp_id",
                 type: "upload"
             }
         ],
     } );
    

    I tried this other thing, which seems always to be the same things at the end. So, the checked row is successfully checked, but all others else still unedited :

    $('#dataTableFiles').on('change', 'input.editor-active', function () {
        let indexes = dataTableFiles.rows().indexes();
        let rowIdx = dataTableFiles.row($(this).closest('tr')[0]).index();
        let pos = indexes.indexOf(rowIdx);
        editorFiles.edit(pos, false);
        editorFiles.val('is_selected', 1);
        editorFiles.submit(function () {
            editorFiles.edit(indexes, false);
            editorFiles.val('is_selected', 0);
            editorFiles.submit();
        });
    } );
    

    Seems that run successively to submit is not possible :(.
    If anyone has an idea, let me know, otherwise I think I will scrape the idea :(.

    Thanks

  • allanallan Posts: 61,822Questions: 1Answers: 10,127 Site admin
    Answer ✓

    It should be possible, however, I think I have a better solution which involves just a single submit - using the field().multiSet() method:

    $('#dataTableFiles').on('change', 'input.editor-active', function () {
        let indexes = dataTableFiles.rows().indexes();
        let rowId = dataTableFiles.row($(this).closest('tr')[0]).id();
    
        editorFiles.edit(indexes, false);
        editorFiles.val('is_selected', 0);
        editorFiles.field('is_selected').multiSet(rowId, 1);
        editorFiles.submit();
    } );
    

    That also solves any concurrency issues you might get from the two separate submit actions.

    Allan

  • Vincent GodéVincent Godé Posts: 12Questions: 2Answers: 0
    edited February 2021

    Allan,

    Thanks a lot. This last code was not working, but it lets me find the solution. So this is the solution for my expects :

    $('#dataTableFiles').on('change', 'input.editor-active', function () {
        let indexes = dataTableFiles.rows().indexes();
        let rowId = dataTableFiles.row($(this).closest('tr')[0]).id();
        editorFiles.edit(indexes, false);
        var rows = editorFiles.field('is_selected').multiGet();
        $.each(rows, function(id, val) {
            if (id == rowId) {
                editorFiles.field('is_selected').multiSet(id, 1);
            } else {
                editorFiles.field('is_selected').multiSet(id, 0);
            }
        });
        editorFiles.submit();
    });
    

    Thanks

This discussion has been closed.