abpframework / abp

Open-source web application framework for ASP.NET Core! Offers an opinionated architecture to build enterprise software solutions with best practices on top of the .NET. Provides the fundamental infrastructure, cross-cutting-concern implementations, startup templates, application modules, UI themes, tooling and documentation.
https://abp.io
GNU Lesser General Public License v3.0
12.93k stars 3.44k forks source link

DataTables RowAction button group option #2745

Closed zHaytam closed 1 year ago

zHaytam commented 4 years ago

Hello,

Currently, the rowAction is rendered as a dropdown button, which is already good but another option would be a button group, see the bootstrap doc.

I did manage to make my own, which is based on datatables-extensions.js but maybe it could be a nice addition to the framework.

Here's how it looks:
image

Thank you.

hikalkan commented 4 years ago

Thanks for the suggestion. I see that some people like this more :) I am adding your request to backlog. Can you share your solution to help others until we implement it in a built-in way.

zHaytam commented 4 years ago

My current solution overrides the fnRowCallback function so you can't have both types at the same time (for some reason, calling the existing callback function, yours, gives an error).

DataTable configuration:

var dataTable = $('#CustomersTable').DataTable(abp.libs.datatables.normalizeConfiguration({
        processing: true,
        serverSide: true,
        paging: true,
        searching: false,
        autoWidth: false,
        scrollCollapse: true,
        ajax: abp.libs.datatables.createAjax(...getList),
        columnDefs: [
            // ...
            {
                defaultContent: "",
                buttonGroup: [
                    {
                        text: l('Edit'),
                        icon: 'pen',
                        action: function (data) {
                            editModal.open({ id: data.id });
                        }
                    },
                    {
                        text: l('Delete'),
                        color: 'danger',
                        icon: 'trash',
                        confirmMessage: function (data) {
                            return l('CustomerDeletionConfirmationMessage', data.name);
                        },
                        action: function (data) {
                            service
                                .delete(data.id)
                                .then(function () {
                                    abp.notify.info(l('SuccessfullyDeleted'));
                                    dataTable.ajax.reload();
                                });
                        }
                    }
                ]
            }
        ],
        fnRowCallback: function (nRow, aData, iDisplayIndex, iDisplayIndexFull) {
            _handleButtonGroup(this, nRow, aData, iDisplayIndex, iDisplayIndexFull);
        }
    }));

Global functions:

function _handleButtonGroup(tableInstance, nRow, aData, iDisplayIndex, iDisplayIndexFull) {
    var columns;
    if (tableInstance.aoColumns) {
        columns = tableInstance.aoColumns;
    } else {
        columns = tableInstance.fnSettings().aoColumns;
    }

    if (!columns) {
        return;
    }

    var cells = $(nRow).children('td');

    for (var i = 0; i < columns.length; i++) {
        var column = columns[i];
        if (!column.buttonGroup)
            continue;

        var container = _generateButtonGroup(nRow, aData, column.buttonGroup);
        $(cells[i]).append(container);
    }
}

function _generateButtonGroup(aRow, aData, items) {
    var $container = $('<div/>')
        .addClass('btn-group');

    for (var i = 0; i < items.length; i++) {
        var item = items[i];
        var btn = $('<button/>')
            .attr('type', 'button')
            .text(item.text)
            .addClass('btn')
            .addClass('btn-sm');

        var color = item.color ? item.color : 'primary';
        btn.addClass('btn-' + color);

        if (item.icon) {
            btn.prepend($('<i/>').addClass('fa fa-' + item.icon + ' mr-1'));
        }

        _handleGroupButtonClick(btn, item, aData);
        $container.append(btn);
    }

    return $container;
}

function _handleGroupButtonClick(btn, item, aData) {
    if (!item.action)
        return;

    $(btn).click(function (e) {
        e.preventDefault();

        if (item.confirmMessage) {
            abp.message.confirm(item.confirmMessage(aData))
                .done(function (accepted) {
                    if (accepted) {
                        item.action(aData);
                    }
                });
        }
        else {
            item.action(aData);
        }
    });
}