Base solution for your next web application
Open Closed

Datatables Multi-Column Sorting #9041


User avatar
0
BigCDogCrew created

I'm using AspNetZero v8.6 MVC/jQuery and I'm trying to get a datatable to sort using multiple, user-selected columns.

The image below shows a table where the Name column was clicked (generating an ascending ordered list by name). Subsequently, the Code column was clicked twice while the shift key was depressed (causing the sort arrows to cycle from ascending to descending on that column).

Here is the javascript that feeds the datatable. I have collapsed the columnDef code a little to preserve length...

        var dataTable = _$addressEMailTypesTable.DataTable({
            scrollX: true,
            responsive: false,
            paging: true,
            serverSide: true,
            processing: true,
            listAction: {
                ajaxFunction: _addressEMailTypesService.getAll,
                inputFilter: function () {
                    return {
					    filter: $('#AddressEMailTypesTableFilter').val(),
					    nameFilter: $('#NameFilterId').val(),
					    codeFilter: $('#CodeFilterId').val()
                    };
                }
            },
            columnDefs: [
                {
                    width: 120,
                    targets: 0,
                    data: null,
                    orderable: false,
                    autoWidth: false,
                    defaultContent: '',
                    rowAction: {
                        cssClass: 'btn btn-brand dropdown-toggle',
                        text: '<i class="fa fa-cog"></i> ' + app.localize('Actions') + ' <span class="caret"></span>',
                        items: [
						    { text: app.localize('View'), action: function (data) { _viewAddressEMailTypeModal.open({ id: data.record.addressEMailType.id }); } },
						    { text: app.localize('Edit'), visible: function () { return _permissions.edit; }, action: function (data) { _createOrEditModal.open({ id: data.record.addressEMailType.id }); } }, 
						    { text: app.localize('Delete'), visible: function () { return _permissions.delete; }, action: function (data) { deleteAddressEMailType(data.record.addressEMailType); } }
                        ]
                    }
                },
					{ targets: 1, data: "addressEMailType.uid", name: "uid", visible: false }, 
                    { targets: 2, data: "addressEMailType.name", name: "name" },
					{ targets: 3, data: "addressEMailType.code", name: "code" },
					{ targets: 4, data: "addressEMailType.order", name: "order" },
					{ targets: 5, data: "addressEMailType.status", name: "status" }
            ]
        });

In the following code (part of the GetAll function), the input.Sorting variable contains "name asc" with no mention of the Code field. I had expected to see "name asc, code desc" in that variable.

                var pagedAndFilteredAddressEMailTypes = filteredAddressEMailTypes
                    .OrderBy(input.Sorting ?? "id asc")
                    .PageBy(input);

Because the sort arrow indicators are behaving correctly, I assume that multiple column sorting is already turned on and supported. What am I missing? Do I need to manually capture the sort information from the table and then override the "sorting" member on the listAction.inputFilter?


3 Answer(s)
  • User Avatar
    0
    maliming created
    Support Team

    hi I created an issue for this, you can follow this issue. https://github.com/aspnetzero/aspnet-zero-core/issues/3274

  • User Avatar
    0
    maliming created
    Support Team

    Exmple Multi-Column Sorting for Audit logs table.

    Web.Mvc\wwwroot\Common\Scripts\Datatables\datatables.ajax.js

    //set sorting filter
    if (requestData.order && requestData.order.length > 0) {
    	inputFilter.sorting = inputFilter.sorting ?? '';
    	for (var i = 0; i < requestData.order.length; i++) {
    		var orderingField = requestData.order[i];
    		if (i > 0) {
    			inputFilter.sorting += ',';
    		}
    		if (requestData.columns[orderingField.column].name) {
    			inputFilter.sorting += requestData.columns[orderingField.column].name + " " + orderingField.dir;
    		}
    		else if (requestData.columns[orderingField.column].data) {
    			inputFilter.sorting += requestData.columns[orderingField.column].data + " " + orderingField.dir;
    		}
    	}
    }
    

    Application.Shared\Auditing\Dto\GetAuditLogsInput.cs

    public void Normalize()
    {
    	if (Sorting.IsNullOrWhiteSpace())
    	{
    		Sorting = "ExecutionTime DESC";
    	}
    
    	var sortFields = Sorting.Split(",");
    	for (var i = 0; i < sortFields.Length; i++)
    	{
    		if (sortFields[i].IndexOf("UserName", StringComparison.OrdinalIgnoreCase) >= 0)
    		{
    			sortFields[i] = "User." + sortFields[i];
    		}
    		else
    		{
    			sortFields[i] = "AuditLog." + sortFields[i];
    		}
    	}
    
    	Sorting = string.Join(", ", sortFields);
    }
    

  • User Avatar
    0
    BigCDogCrew created

    Fantastic! Worked like a charm. Excellent documentation. Keep up the great work.