Base solution for your next web application
Open Closed

DataTable - Showing wrong Headers when sorting the grid. #9866


User avatar
1
Leonardo.Willrich created

Prerequisites

Please answer the following questions before submitting an issue. YOU MAY DELETE THE PREREQUISITES SECTION.

  • What is your product version? - 9.0.1

  • What is your product type (Angular or MVC)? - MVC

  • What is product framework type (.net framework or .net core)? - .NET Core

  • Which theme are you using? - Metronic Default

  • What are the theme settings? The default settings, I have removed the Visual Settings from my project, then the user will not be able to change that.

Hi,

I am getting an odd behaviour from DataTables in my Settings forms. If the grid (database) has some columns and there is a long text in some of the columns, when sorting the grid it is messing the header as you can see in the picture below:

Do you guys have any idea what is wrong here?

I cannot share my project, but we can set up a remote access to my local machine if you want to!

Kind Regards,

Leonardo Willrich.


11 Answer(s)
  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi @Leonardo.Willrich

    We haven't seen this behavior before. Is it possible to share JS and CSHTML part of the datatable ?

  • User Avatar
    0
    Leonardo.Willrich created

    Hi @ismcagdas

    Yes, I can, see below:

    JS (Just the dataTable creation):

    var dataTable = _$apiariesTable.DataTable({
                scrollY: "calc(100vh - 505px)",
                scrollCollapse: false,
                paging: true,
                serverSide: true,
                processing: true,
                listAction: {
                    ajaxFunction: _apiariesService.getAll,
                    inputFilter: function () {
                        return {
    					filter: $('#ApiariesTableFilter').val(),
    					apiaryNameFilter: $('#ApiaryNameFilterId').val(),
    					minNumberOfBoxesFilter: $('#MinNumberOfBoxesFilterId').val(),
    					maxNumberOfBoxesFilter: $('#MaxNumberOfBoxesFilterId').val(),
    					apiaryStatusStatusTextFilter: $('#ApiaryStatusStatusTextFilterId').val(),
    					apiaryTypeTextFilter: $('#ApiaryTypeTextFilterId').val(),
    					geolocationGeocodedAddressFilter: $('#GeolocationGeocodedAddressFilterId').val(),
    					landOwnerNameFilter: $('#LandOwnerNameFilterId').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) {
                                        _viewApiariesModal.open({ data: data.record });
                                    }
                            },
    						{
                                text: app.localize('Edit'),
                                visible: function () {
                                    return _permissions.edit;
                                },
                                action: function (data) {
                                    _createApiaryModalManager.open({ id: data.record.apiaries.id });
                                    //_createOrEditModal.open({ id: data.record.apiaries.id });
                                }
                            }, 
    						{
                                text: app.localize('Delete'),
                                visible: function () {
                                    return _permissions.delete;
                                },
                                action: function (data) {
                                    deleteApiaries(data.record.apiaries);
                                }
                            }]
                        }
                    },					
    					{
    						targets: 1,
    						data: "apiaries.apiaryName",
    						name: "apiaryName"   
                        },                    
    					{
    						targets: 2,
                            data: "apiaries.estimatedNoOfHives",
                            name: "estimatedNoOfHives"   
    					},					
    					{
    						targets: 3,
    						data: "apiaryStatusStatusText",
    						name: "apiaryStatus.StatusText" 
                        },
                        {
    						targets: 4,
    						data: "apiaryTypeText",
    						name: "apiaryType.Type" 
    					},
    					{
    						targets: 5,
    						data: "geolocationGeocodedAddress",
    						name: "geolocation.GeocodedAddress" 
    					},					
    					{
    						targets: 6,
    						data: "landOwnerName",
    						name: "landOwner.Name" 
                        },
                        {
                            targets: 7,
                            data: "apiaries.creationTime",
                            name: "creationTime",
                            render: function (creationTime) {
                                console.log('creationTime', creationTime);
                                return app.utils.date.getUTCtoLocalDateTime(creationTime, 'ddd DD-MMM-YYYY HH:mm');
                            }
                        },
                        {
                             targets: 8,
                             data: "createdBy",
                             name: "CreatorUser.UserName"
                        }
                ]
            });
    

    CSHTML (All):

    @using ASL.iAPIS.Authorization
    @using ASL.iAPIS.Web.Areas.iAPIS.Models.Apiaries
    @using ASL.iAPIS.Web.Areas.iAPIS.Startup
    @model ApiariesViewModel
    @{
        ViewBag.CurrentPageName = iAPISPageNames.Tenant.ApiariesMaint;
    }
    @section Scripts
        {
        <link rel="stylesheet" href="/leaflet_files/screen.css" />
        <link href="~/leaflet_files/leaflet.css" rel="stylesheet" />
        <script src="~/leaflet_files/leaflet.js"></script>
        <script src="~/leaflet_files/bundle.min.js"></script>
    
    
        <script src="~/leaflet_files/dist/esri-leaflet.js"></script>
    
        <link href="~/leaflet_files/dist/esri-leaflet-geocoder.css" rel="stylesheet" />
        <script src="~/leaflet_files/dist/esri-leaflet-geocoder.js"></script>
    
    
        <script src="~/lib/kendo-ui/js/jszip.min.js" asp-append-version="true"></script>
        <script src="~/lib/kendo-ui/js/kendo.all.min.js" asp-append-version="true"></script>
        <script src="~/lib/kendo-ui/js/kendo.aspnetmvc.min.js" asp-append-version="true"></script>
    
        @*<script src="~/lib/fileuploader/file-upload-with-preview.min.js" asp-append-version="true"></script>
        <link href="~/lib/fileuploader/file-upload-with-preview.min.css" rel="stylesheet" asp-append-version="true"/>*@
    
        <link href="/leaflet_files/extramarkers/leaflet.extra-markers.min.css" rel="stylesheet" />
        <script src="~/leaflet_files/extramarkers/leaflet.extra-markers.js"></script>
    
        <script src="/leaflet_files/Leaflet.Control.Custom.js"></script>
        <script src="~/leaflet_files/leaflet-omnivore.min.js"></script>
        @*<script src='//api.tiles.mapbox.com/mapbox.js/plugins/leaflet-omnivore/v0.3.1/leaflet-omnivore.min.js'></script>*@
    
        <script abp-src="/view-resources/Areas/iAPIS/Views/Apiaries/Index.js" asp-append-version="true"></script>
    }
    <div class="content d-flex flex-column flex-column-fluid" id="kt_content">
        <div class="subheader py-2 py-lg-4 subheader-solid" id="kt_subheader" kt-hidden-height="54" style="">
            <div class="container-fluid d-flex align-items-center justify-content-between flex-wrap flex-sm-nowrap">
                <!--begin::Info-->
                <div class="col-md-6">
                    <div class="d-flex align-items-center flex-wrap mr-1">
                        <!--begin::Page Title-->
                        <h5 class="text-dark font-weight-bolder mt-2 mb-2 mr-5 font-size-h3">
                            @L("Apiaries")
                        </h5>
                        <!--end::Page Title-->
                        <div class="subheader-separator subheader-separator-ver mt-2 mb-2 mr-5 bg-gray-200"></div>
                        <span class="text-dark font-weight-normal font-sub-title mr-4">@L("ApiariesHeaderInfo")</span>
    
                    </div>
                </div>
                <div class="col-md-6 text-right">
                    <button id="ExportToExcelButton" class="btn btn-outline-success"><i class="fa fa-file-excel-o"></i> @L("ExportToExcel")</button>
                    @if (IsGranted(AppPermissions.Pages_Apiaries_Create))
                    {
                        <button id="CreateNewApiariesButton" class="btn btn-primary blue"><i class="fa fa-plus"></i> @L("CreateNewApiaries")</button>
                    }
                </div>
                <!--end::Info-->
            </div>
        </div>
    
    
    
        <div class="container-fluid">
            <div class="card card-custom gutter-b">
                <div class="card-body">
                    <div class="m-content">
                        <div class="m-portlet m-portlet--mobile">
                            <div class="m-portlet__body portlet-body-pd">
                                <div class="m-form m-form--label-align-right">
                                    <div class="row align-items-center m--margin-bottom-10">
                                        <div class="col-xl-12 pd-0">
                                            <div class="form-group m-form__group align-items-center">
                                                <div class="input-group">
                                                    <input type="text" id="ApiariesTableFilter" class="form-control m-input" placeholder="@L("SearchWithThreeDot")" value="@Model.FilterText">
                                                    <span class="input-group-btn">
                                                        <button id="GetApiariesButton" class="btn btn-primary" type="submit"><i class="flaticon-search-1"></i></button>
                                                    </span>
                                                </div>
                                            </div>
                                        </div>
                                    </div>
                                </div>
                                <div id="AdvacedAuditFiltersArea" style="display: none" class="row m--margin-bottom-10">
                                    <div class="col-md-12">
                                        <div class="m-separator m-separator--dashed"></div>
                                    </div>
    
    
                                    <div class="col-md-3">
                                        <div class="form-group">
                                            <label for="ApiaryNameFilterId">@L("ApiaryName")</label>
                                            <input type="text" class="form-control" name="apiaryNameFilter" id="ApiaryNameFilterId">
                                        </div>
                                    </div>
                                    <div class="col-md-3">
                                        <div class="form-group">
                                            <label for="MinNumberOfBoxesFilterId">@L("MinMax") @L("NumberOfBoxes")</label>
                                            <div class="input-group">
                                                <input type="number" class="form-control m-input" placeholder="@L("MinValue")" name="minNumberOfBoxesFilter" id="MinNumberOfBoxesFilterId" />
                                                <input type="number" class="form-control m-input" placeholder="@L("MaxValue")" name="maxNumberOfBoxesFilter" id="MaxNumberOfBoxesFilterId" />
                                            </div>
                                        </div>
                                    </div>
                                    <div class="col-md-3">
                                        <div class="form-group">
                                            <label for="ApiaryStatusStatusTextFilterId">(@L("ApiaryStatus")) @L("StatusText")</label>
                                            <input type="text" class="form-control" name="apiaryStatusStatusTextFilter" id="ApiaryStatusStatusTextFilterId">
                                        </div>
                                    </div>
                                    <div class="col-md-3">
                                        <div class="form-group">
                                            <label for="ApiaryTypeTextFilterId">@L("Type")</label>
                                            <input type="text" class="form-control" name="apiaryTypeTextFilter" id="ApiaryTypeTextFilterId">
                                        </div>
                                    </div>
                                    <div class="col-md-3">
                                        <div class="form-group">
                                            <label for="GeolocationGeocodedAddressFilterId">(@L("Geolocation")) @L("GeocodedAddress")</label>
                                            <input type="text" class="form-control" name="geolocationGeocodedAddressFilter" id="GeolocationGeocodedAddressFilterId">
                                        </div>
                                    </div>
                                    <div class="col-md-3">
                                        <div class="form-group">
                                            <label for="LandOwnerNameFilterId">(@L("LandOwner")) @L("Name")</label>
                                            <input type="text" class="form-control" name="landOwnerNameFilter" id="LandOwnerNameFilterId">
                                        </div>
                                    </div>
    
                                </div>
                                <div class="row m--margin-bottom-10">
                                    <div class="col-xl-12">
                                        <span id="ShowAdvancedFiltersSpan" class="text-muted clickable-item"><i class="fa fa-angle-down"></i> @L("ShowAdvancedFilters")</span>
                                        <span id="HideAdvancedFiltersSpan" class="text-muted clickable-item" style="display: none"><i class="fa fa-angle-up"></i> @L("HideAdvancedFilters")</span>
                                    </div>
                                </div>
                                <div class="row align-items-center">
                                    <table id="ApiariesTable" class="display table table-striped table-bordered table-hover dt-responsive nowrap">
                                        <thead>
                                            <tr>
                                                <th>@L("Actions")</th>
                                                <th>@L("ApiaryName")</th>
                                                <th>@L("NumberOfHives")</th>
                                                <th>@L("Status")</th>
                                                <th>@L("Type")</th>
                                                <th>@L("Location")</th>
                                                <th>@L("LandOwnerName")</th>
                                                <th>@L("CreationTime")</th>
                                                <th>@L("CreatedBy")</th>
    
                                            </tr>
                                        </thead>
                                    </table>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
    
  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi,

    Does this work if you remove the line below;

    scrollY: "calc(100vh - 505px)"

  • User Avatar
    0
    Leonardo.Willrich created

    Hi,

    Unfortunately, the same error even removing the line above.

  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi @Leonardo.Willrich

    Could you send an email to [email protected] ? We can remotely connect to your pc and help you if that's OK with you.

    Thanks,

  • User Avatar
    0
    ISTeam created

    Good to hear that someone else is also facing this kind of issues in datatables.

    In this case number of columns are less but in our case we have 17 columns and the main issue is second column 'Description' which are lengthy that makes this kind of strange appearance of datatables when we have multiple header rows like below :

    Similarly again when we use the datatable in modal there is some strange behaviour. May be because ANZ theme and customization code of "modalmanager.js" and "datatables.default.js" of "....Mvc\wwwroot\Common\Scripts" as per below:

    @ismcagdas please try to reproduce this scenario at your end by increasing number of columns and/or larger text both in case of normal page and in modal. Facing this issue since beginning but hope there would be some solution which you would post here after fixing @Leonardo 's original issue.

    Thanks.

  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi @ISTeam

    Thank you for the explanation, I will try like that and get back to you in a short time.

  • User Avatar
    0
    ISTeam created

    Thank you @ismcagdas for your response.

    Luckily I found this SO a post today and I could fix the problem little bit by setting this option for first column in the JS:

    responsivePriority: 1

    But it works only for the cshtml regular page of the website and not for the pop-up tables.

    Though using below code, I could atleast fix the overflow issue and now its showing horizontal scrollbar in pop-up. Still it is not responsive design.

    CSHTML

    ......
    <div class="row mb-4">
                            <div class="col-xl-12">
                                <span id="ShowAdvancedFiltersSpan" class="text-muted clickable-item"><i class="fa fa-angle-down"></i> @L("ShowAdvancedFilters")</span>
                                <span id="HideAdvancedFiltersSpan" class="text-muted clickable-item" style="display: none"><i class="fa fa-angle-up"></i> @L("HideAdvancedFilters")</span>
                            </div>
                        </div>
                        <div class="row">
                            <div class="col-sm-12">
                                <div class="dataTables_scroll">
                                 <!-- Code change table-responsive in div and table with required CSS classes -->
                                    <div class="dataTables_scrollBody table-responsive" style="position: relative; overflow: auto; width: 100%;">
                                        <table id="InventoriesTable" class="display table table-centered dtr-inline w-100 dataTable table-bordered table-hover dt-responsive CDTable">
                                            <thead>
                                                <tr>
                                                    <th class="kt-align-center" name="thProduct" colspan="2">@L("thProduct")</th>
                                                    <th class="kt-align-center" colspan="3">@L("thQuantity")</th>
                                                    <th class="kt-align-center text-wrap" rowspan="2">@L("thMonthsRemaining")</th>
                                                    <th class="kt-align-center" colspan="3">@L("thUsage")</th>
                                                    <th class="kt-align-center" colspan="3">@L("thOrders")</th>
                                                    <th class="kt-align-center" rowspan="2">@L("thLastReceived")</th>
                                                    <th class="kt-align-center" rowspan="2">@L("thLastUsed")</th>
                                                    <th class="kt-align-center" rowspan="2">@L("thVersion")</th>
                                                    <th class="kt-align-center" rowspan="2">@L("UOM")</th>
                                                    <th class="hostSpecificCol kt-align-center" rowspan="2">@L("InventoryType")</th>
                                                    <th class="hostSpecificCol kt-align-center" rowspan="2">@L("ClientCode")</th>
                                                </tr>
                                                <tr>
                                                    <th>@L("thItemNumber")</th>
                                                    <th>@L("thDescription")</th>
                                                    <th>@L("thOnHandQty")</th>
                                                    <th>@L("thOnOrderQty")</th>
                                                    <th>@L("thAvailableQty")</th>
                                                    <th>@L("thUsage12Months")</th>
                                                    <th>@L("thUsage24Months")</th>
                                                    <th>@L("thUsage36Months")</th>
                                                    <th>@L("thOrders12Months")</th>
                                                    <th>@L("thOrders24Months")</th>
                                                    <th>@L("thOrders36Months")</th>
                                                </tr>
                                            </thead>
                                        </table>
                                    </div>
                                </div>
                            </div>
                        </div>
    ....
    

    JavaScipt

      var dataTable = _$inventoriesTable.DataTable({
                //scrollY: '50vh',
                scrollX: true,
                paging: true,
                serverSide: true,
                processing: true,
                listAction: {
                    ajaxFunction: _inventoriesService.getAll,
                    inputFilter: function () {
                        return {
                            // .....
                            isActiveFilter: 1
                        };
                    }
                },
                columnDefs: [
                    { className: 'dt-center', targets: [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17] },
                    { className: 'text-nowrap text-left', targets: [0] },
                    { className: 'text-left', targets: [1] },
                    {
                        responsivePriority: 1,           // Code change
                        targets: 0,
                        data: "inventoryItem.itemNumber",
                        name: "itemNumber",
                        className: "text-nowrap text-left"
                    },
    

    Plus button is showing but because of two header rows on this page I still have layout issues as below :

    But the same code does not work for pop-up where I have two tabs containing datatable.

    Corresponding code : CSHTML

    ......<div class="modal-body">
        <div id="ProductionOrdersData">
            <div id="DataTabPanel" class="tabbable-line">
                <button id="ExportShipmentsButton" class="btn btn-outline-success kt-pull-right pull-right kt-padding-b-5">
                    <i class="fa fa-file-excel"></i> @L("Export")
                </button>
                <ul class="nav nav-tabs" role="tablist">
                    <li class="nav-item">
                        <a href="#DetailsTab" aria-expanded="true" class="nav-link @ViewBag.PVDetailsTabVisibility" data-toggle="tab" role="tab">
                            @L("Details")
                        </a>
                    </li>
                    <li class="nav-item">
                        <a href="#ShipmentsTab" aria-expanded="true" class="nav-link @ViewBag.PVShipmentsTabVisibility" data-toggle="tab" role="tab">
                            @L("Shipments")
                        </a>
                    </li>
                </ul>
                <div class="tab-content">
                    <div class="tab-pane @ViewBag.PVDetailsTabVisibility" id="DetailsTab">
                        <div class="row align-items-center">
                            <div class="table-responsive">
                                <table id="OrderDetailsTable" class="display table table-centered dtr-inline w-100 dataTable table-bordered table-hover dt-responsive">
                                    <thead>
                                        <tr>
                                            <th>@L("JobNo")</th>
                                        </tr>
                                    </thead>
                                </table>
                            </div>
                        </div>
                    </div>
                    <div class="tab-pane @ViewBag.PVShipmentsTabVisibility" id="ShipmentsTab">
                        <div class="row align-items-center">
                            <div class="table-responsive">
                                <table id="OrderShipmentsTable" class="display table table-centered dtr-inline w-100 dataTable table-bordered table-hover dt-responsive">
                                    <thead>
                                        <tr>
                                            <th>@L("ShipmentNo")</th>                                       
                                        </tr>
                                    </thead>
                                </table>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>......
    

    JavaScript

    this.init = function (modalManager) {
                _modalManager = modalManager;
    
                debugger;
                _$CurrentOrderNo = $('#CurrentProductionOrders').val();
    
                _$DetailsTable.DataTable({
                    serverSide: false,
                    processing: true,
                    listAction: {
                        ajaxFunction: _pvJobsService.getJobsForOrder,
                        inputFilter: function () {
                            return {
                                orderNo: _$CurrentOrderNo
                            }
                        }
                    },
                    columnDefs: [
                        {
                            responsivePriority: 1,
                            targets: 0,
                            data: 'productionJob.jobNo',
                            name: 'jobNo'
                        },
    ......
    

    Questions :

    1. First image is not responsive
    2. Second image should be responsive (and show plus button) but it is showing scrollbar!
  • User Avatar
    0
    Leonardo.Willrich created

    Hi @ismcagdas, I have sent you and email. Sorry, I haven't noticed your answer before!

  • User Avatar
    0
    ISTeam created

    Finally I found the solution for modal scrollbar (second issue in my above comment) as below after changing ANZ customized datatablese script :

    And below trigger in the modal script on tab change and similarly for resize :

    $('.nav-tabs li').click(function () {            
        $('#OrderDetailsTable').DataTable().columns.adjust().draw();
        $('#OrderShipmentsTable').DataTable().columns.adjust().draw();
    });
    
  • User Avatar
    0
    ismcagdas created
    Support Team