Edit data not associated with row, prevent row update

Edit data not associated with row, prevent row update

wadeparallonwadeparallon Posts: 89Questions: 10Answers: 0

I'm having trouble searching the forums for a similar issue. I feel like this would be more common than I'm finding.
But I have a row of data, and based on a bool, I'm popping up an editor on click to edit some unrelated data. This works, however, after I submit, Editor/Datatables attempts to redraw the row with the data coming back from from the unrelated Editor. I get the row mismatch error obviously. I have a super simple .NET Editor for /ComponentEditors/Approval/Editor

Preferably, I'd like it to only refresh the ONE column that I trigger the editor off of... or prevent the row updated entirely at the very least.

Editor

   const editor = new DataTable.Editor({
        ajax: '/ComponentEditors/Approval/Editor',
        idSrc: 'id',
        fields: [
            {
                label: 'Approval Date:',
                name: 'ApproveDate',
                type: 'datetime',
                keyInput: false
            },
            {
                label: 'Approval Comment:',
                name: 'ApprovalComments'
            }
        ],
        table: '#ProjectsDatatable'
    });

Datatable

  const datatable = new DataTable("#ProjectsDatatable", {
        ajax : {
            url: "/Projects/GetProjects",
            type: "GET",
            dataType: "JSON"
        },
        idSrc: 'id',
        columns: [ 
            {
                className: 'dt-control',
                orderable: false,
                data: null,
                defaultContent: '',
            },
            {
                data: "id",
                title: "ProjectId",
                searchable: false,
                visible: false
            },
            {
                data: "approveDate",
                orderable: false,
                render :function (data, type, row, meta) {
                    if(type === 'display'){
                        if(data !== null) {
                            let date = new Date(data);
                            return '<span class="d-inline-block" tabindex="0" data-bs-toggle="popover" data-bs-trigger="hover focus" ' +
                                'data-bs-title="'+ date.toLocaleDateString() +' '+ date.toLocaleTimeString() +'" data-bs-content="'+row.approvalComments+'">' +
                                    '<i class="bi bi-check-circle-fill"></i>' +
                                    '</span>';
                        } else {
                            return '<span class="d-inline-block editor-edit"><button><i class="bi bi-circle"></i></button></span>';
                        }
                    }else{
                        //we are just checking for true or false
                        return data !== null;
                    }
                },
                searchable: true
            },
...a bunch more columns

On click method

    datatable.on('click', 'span.editor-edit button', function (e) {
        editor.edit(e.target.closest('tr'), {
            title: 'Approve Project',
            buttons: [
            {
                text: 'Cancel',
                action: function () {
                    this.close();
                }
            },
            'Update'
        ]
        });
    });

This question has accepted answers - jump to:

Answers

  • allanallan Posts: 63,872Questions: 1Answers: 10,527 Site admin
    Answer ✓

    I'm popping up an editor on click to edit some unrelated data.

    Sounds like you need the standalone Editor. To enable "standalone mode", just don't pass it a table initialisation option.

    That will mean though that editor.edit(e.target.closest('tr'), { won't work since the table isn't associated with the Editor any more. You need to call field().set() to set the values (e.g. the project ID).

    Allan

  • wadeparallonwadeparallon Posts: 89Questions: 10Answers: 0

    This appears to work.

        datatable.on('click', 'span.editor-edit', function () {
            editor.edit($(this).data('id'), {
                title: 'Approve Project',
                buttons: [
                {
                    text: 'Cancel',
                    action: function () {
                        this.close();
                    }
                },
                'Update'
            ]
            });
        });
    
     } else {
                                return '<span class="d-inline-block editor-edit" data-editor-field="approveDate" data-editor-id="'+row.id+'" data-id="'+ row.id +'"><i class="bi bi-circle"></i></span>';
                            }
    
    

    Mainly pulling from:
    https://editor.datatables.net/examples/standalone/collection.html

    I'm hung reading the documentation on having it auto update the data from the row. I can't seem to hook it right. Nor am I 100% if the data is indeed being updated behind the scenes and just not reflected on the UI because I have display logic (change the open circle to filled).

    I'm attempting to redraw the single row on submitSuccess atm.

  • wadeparallonwadeparallon Posts: 89Questions: 10Answers: 0
    edited January 24

    This isn't working, but I'm putting it in here as a display of what I'm trying to do. (I get that its expecting the whole row object now)

        editor.on("submitSuccess", function( e, json, data, action ){
            let row = datatable.row(data.Id).data();
            row.ApproveDate = data.ApproveDate;
            datatable.row(data.Id).data(row).draw(); 
        });
    
  • allanallan Posts: 63,872Questions: 1Answers: 10,527 Site admin

    Do:

    editor.on("submitSuccess", function( e, json, data, action ){
        let row = datatable.row(data.Id).data();
        row.ApproveDate = data.ApproveDate;
        datatable.row(data.Id).invalidate('data').draw(); 
    });
    

    Which will instruct DataTables to clear its cache for that row and read the data source again.

    Allan

  • wadeparallonwadeparallon Posts: 89Questions: 10Answers: 0
    edited January 24

    The issue is that row is undefined. Its not getting back a row. I think because my integer is not an index.

    data object:
    {"draw":null,"data":[{"DT_RowId":"row_3082204","Id":3082204,"ApproveDate":"2025-01-09T00:00:00","ApprovalComments":"hell yea"}] ....

  • allanallan Posts: 63,872Questions: 1Answers: 10,527 Site admin
    Answer ✓

    Ah, try:

    datatable.row('#' + data.Id).invalidate('data').draw(); 
    

    Assuming that rowId is set to Id for the DataTable.

    Allan

  • wadeparallonwadeparallon Posts: 89Questions: 10Answers: 0
    edited January 24

    Nailed it. Thanks! I had idSrc set but not rowId. I get those confused sometimes.

    Edit: I saw the # in the documentation, but what wasn't clear is if I had to add that to each row or if it was auto generated. I didn't see it in the dom when looking. But I see now that when adding rowId it adds it for you.

    And in the beginning I didn't realize what "standalone" meant in regards to Datatables.

Sign In or Register to comment.