.node() always return null

.node() always return null

HugoLHugoL Posts: 3Questions: 2Answers: 0

Hello,

I'm evaluating the Datatables on a small project and I'm stuck on trying to remove a row from a table.
When creating a table I'm adding a column with 2 buttons (Edit and Remove) and then I'm trying to remove the row using the DataTable API.

I'm creating my table like this:

<table id="organizationsTable" class="table table-striped table-bordered table-advance table-hover display responsive no-wrap">
                <thead>
                    <tr>
                        <th>Id</th>
                        <th>@L("Organization")</th>
                        <th>@L("CompanyNo")</th>
                        <th>@L("RegisteredOffice") </th>
                        <th>@L("VatNumber") </th>
                        <th>@L("EmailAddress") </th>
                        <th>@L("GridActions") </th>
                    </tr>
                </thead>
                <tbody>
                    @foreach (var organization in Model.Items)
                    {
                        <tr>
                            <td> @organization.Id</td>
                            <td> @organization.Name </td>
                            <td> @organization.CompanyNo </td>
                            <td> @organization.RegisteredOffice </td>
                            <td> @organization.VatNumber </td>
                            <td> @organization.EmailAddress </td>
                            <td></td> @*Actions column - Generated by JS*@
                        </tr>
                    }
                </tbody>
            </table>

Then on the JS I have:

$(document).ready(function () {
            var organizationsTable = $('#organizationsTable').DataTable({
                responsive: true,
                columnDefs: [ { targets: 0,visible: false, },
                    { targets: 6, data: null,
                      defaultContent: '<a href="javascript:;" class="btn btn-icon-only default tooltips btn-edit" data-container="body" data-              placement="bottom" data-original-title="Edit">'
                                    + '<i class="fa fa-edit"></i>'
                                    + '</a>'
                                    + '<a href="javascript:;" class="btn btn-icon-only default tooltips btn-delete" data-container="body" data-placement="bottom" data-original-title="Delete">'
                                    + ' <i class="fa fa-trash-o"></i> ' 
                                    + '</a>'
                }]
            });


            $('#organizationsTable tbody').on('click', '.btn-edit', function (e) {
                debugger;
                var data = organizationsTable.row($(this).parents('tr')).data();
                alert('Edit button | Id: ' + data[0]);
                
            });

            $('#organizationsTable tbody').on('click', '.btn-delete', function (e) {
                e.preventDefault();
                var data = organizationsTable.row($(this).parents('tr')).data();
                var organizationId = data[0];
                alert('Delete button | Id: ' + data[0]);  

                abp.message.confirm(
                    app.localize('AreYouSure'),
                    function (isConfirmed) {
                        if (isConfirmed) {
                            _organizationService.deleteOrganization({
                                id: organizationId
                            }).done(function () {
                                abp.notify.info(app.localize('SuccessfullyDeleted'));
                                debugger;
                                // location.reload(); // This works but it fetches the data again. I would like to remove the row.

                              // Try 1 - Doesn't work
                                organizationsTable
                                       .row($(this).parents('tr'))
                                       .remove()
                                       .draw();

                                // Try 2 - Doesn't work 
                                var row = organizationsTable.row($(this).parents('tr'));
                                var rowNode = row.node(); //rowNode is null
                                row.remove();
                                organizationsTable.draw();
                            });
                        }
                    }
                );
            });
        });

Everything works as planned, row is deleted on the database but I can't remove it from the Grid.

Any suggestion?

This question has an accepted answers - jump to answer

Answers

  • gyrocodegyrocode Posts: 126Questions: 6Answers: 30
    edited May 2017

    Most likely this is not a link node because your are referencing it in anonymous function. Try getting row before showing the confirmation.

    For example:

    var row = organizationsTable.row($(this).parents('tr'));
    
    abp.message.confirm(
       // ... skipped ...
    
       row.remove().draw();
    
       // ... skipped ...
    );
    

    See more articles about jQuery DataTables on gyrocode.com and contact us if you need help with your project.

  • HugoLHugoL Posts: 3Questions: 2Answers: 0

    Hi @gyrocode and thanks for the answer .

    The purpose of the confirm message is to ask the user if he really wants to delete the row. If I remove the row before the confirmation and the user press No then I would have to add it again.

  • HugoLHugoL Posts: 3Questions: 2Answers: 0

    Following up @gyrocode reply I made a slight change to the code in order to avoid an anonymous function.

            $('#organizationsTable tbody').on('click', '.btn-delete', function (e) {
                e.preventDefault();
                var row = organizationsTable.row($(this).parents('tr'));
                var organizationId = row.data()[0];
                
                abp.message.confirm(
                    app.localize('AreYouSure'),
                    function (isConfirmed) {
                        if (isConfirmed) {
                            _organizationService.deleteOrganization({
                                id: organizationId
                            }).done(deleteOrganizationRow(organizationId)); // callback function
                    }
                );
            });
    

    and then I created the function

     function deleteOrganizationRow(organizationId) {
                organizationsTable
                        .row('#row-' + organizationId)
                        .remove()
                        .draw(true);
    
                abp.notify.info(app.localize('SuccessfullyDeleted'));
            }
    

    I now have the id of the Organization but I'm still unable to delete the row.
    I think the reason is related with the way I'm creating the table because if I do

        organizationsTable
             .row()
             .node()
             .remove()
    

    it will remove the first row of the table.

    To create the table this is what I'm doing:

    <table id="organizationsTable" class="table table-striped table-bordered table-advance table-hover display responsive no-wrap">
                    <thead>
                        <tr DT_RowId=@organization.Id> // I tried with this and without it with no luck
                            <th>Id</th>
                            <th>@L("Organization")</th>
                            <th>@L("CompanyNo")</th>
                            <th>@L("RegisteredOffice") </th>
                            <th>@L("VatNumber") </th>
                            <th>@L("EmailAddress") </th>
                            <th>@L("GridActions") </th>
                        </tr>
                    </thead>
                    <tbody>
                        @foreach (var organization in Model.Items)
                        {
                            <tr>
                                <td> @organization.Id</td>
                                <td> @organization.Name </td>
                                <td> @organization.CompanyNo </td>
                                <td> @organization.RegisteredOffice </td>
                                <td> @organization.VatNumber </td>
                                <td> @organization.EmailAddress </td>
                                <td></td> @*Actions column - Generated by JS*@
                            </tr>
                        }
                    </tbody>
                </table>
    

    The examples to remove the rows on the documentation are done using the

    $('#example tbody').on( 'click', 'img.icon-delete', function () {
        table
            .row( $(this).parents('tr') )
            .remove()
            .draw();
    } );
    

    But how does one do this using a confirmation message first with a callback function when building a table using HTML in this case (razor syntax)?

  • allanallan Posts: 63,893Questions: 1Answers: 10,531 Site admin
    Answer ✓

    Don't use row().node().remove(). You should actually get an error message if you do that since row().node() returns a DOM element which won't have a remove() method on it.

    Use row().remove() if you want to delete a row from the DataTable - like in your very last example.

    Instead of having the click event handler immediately all row().remove() you would have it call your abp.message.confirm function and just have the callback reading the row.

    Possibly the one bit of disconnect that you've got is that you need to store either the row or the element that was clicked on before the callback function - e.g.

    $('#example tbody').on( 'click', 'img.icon-delete', function () {
      var row = table.row( $(this).parents('tr') );
    
      abp.message.confirm( ...
      // in the callback use: row.remove().draw();
    } );
    

    I think you are 95% of the way there already - hopefully that will help finish it off.

    Allan

  • HugoLHugoL Posts: 3Questions: 2Answers: 0

    Actually I was 97.5% of the way :smiley:

    When I posted the change because @gyrocode suggestion about the anonymous function I already had the var row = table.row( $(this).parents('tr') );
    but I was trying to select the row using the Id and that's why I was passing the "organizationId".

    Thank you very much for the help.
    It worked like a charm.

    Hugo

This discussion has been closed.