使用带有引导选项卡的固定列的数据表问题

Posted

技术标签:

【中文标题】使用带有引导选项卡的固定列的数据表问题【英文标题】:Datatables issue using fixedColumns with Bootstrap tabs 【发布时间】:2019-07-28 14:39:07 【问题描述】:

我有一个包含两个引导选项卡的页面,每个选项卡包含一个数据表。只有在我将 fixedColumns 集成到两个数据表中之后,才开始出现以下行为。

在页面加载时,第一个表格正确显示,并且 fixedColumns 正常工作。当我单击表 2 的选项卡时,会显示该表,但是应该在表下方的页面内容显示在表的顶部,并且 fixedColumns 不起作用。


表 1:

表 2:


Link to the snippet,虽然我很难让它渲染任何东西。

Javascript:

$(function () 
dataRetrievalpromise()
    .then(function (result) 
        generateTabsPromise(result)
            .then(function (result) 
                console.log(result);
                createTablehtmlPromise(result)
                    .then(function (result) 
                        createTableColumnsAndDataPromise(result);
                    );
            );
    );

//Below works only when debugging/using breakpoints
$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) 
    //$('.dTable:visible').each(function (e) 

    //    $(this).DataTable().columns.adjust().responsive.recalc();

    //);
    $.fn.dataTable.tables( visible: true, api: true )
    .columns.adjust()
    .fixedColumns().relayout()
    .responsive.recalc();
    //.fixedHeader.adjust();
    //.columns.adjust().redraw()
);
);


var generateTabsPromise = function (trainerJson) 
var promise = new Promise(function (resolve, reject) 
    var result = ;
    var tabInfo = [];
    var allMonthsFromJson = Object.getOwnPropertyNames(trainerJson);
    var tabHTML = '';
    for (var i = 0; i < allMonthsFromJson.length; i++) 
        tabInfo.push(allMonthsFromJson[i]);
    
    for (var i = 0; i < tabInfo.length; i++) 
        //Make first tab active
        if (i == 0) 
            tabHTML += '<li class="active"><a href="' + '#tab-' + tabInfo[i] + '" data-toggle="tab"> ' + tabInfo[i] + '</a></li>';
        
        else 
            tabHTML += '<li><a href="' + '#tab-' + tabInfo[i] + '" data-toggle="tab"> ' + tabInfo[i] + '</a></li>';
        
    
    $(".nav-tabs").html(tabHTML);
    result =  firstTab: tabInfo[0], jsonData: trainerJson, allMonthsInJson: allMonthsFromJson ;
    resolve(result);
);
return promise;
;


function createTableHTMLPromise(generateTabsResult) 
var promise = new Promise(function (resolve, reject) 
    var tableHTML = '';
    for (var i = 0; i < generateTabsResult.allMonthsInJson.length; i++) 
        if (i === 0) 
            tableHTML += '<div class="tab-pane active" id="' + 'tab-' + generateTabsResult.allMonthsInJson[i] + '">';
            tableHTML += '<table class="table dTable" id="' + 'table-' + generateTabsResult.allMonthsInJson[i] + '" cellspacing="0" >' + '</table>';
            tableHTML += '</div>';
        
        else 
            tableHTML += '<div class="tab-pane" id="' + 'tab-' + generateTabsResult.allMonthsInJson[i] + '">';
            tableHTML += '<table class="table dTable" id="' + 'table-' + generateTabsResult.allMonthsInJson[i] + '" cellspacing="0" >' + '</table>';
            tableHTML += '</div>';
        
    
    $(".tab-content").html(tableHTML);
    result =  allMonthsInJson: generateTabsResult.allMonthsInJson, jsonData: generateTabsResult.jsonData ;
    resolve(result);
);
return promise;



function createTableColumnsAndDataPromise(createTableHTMLResult) 
var promise = new Promise(function (resolve, reject) 
    var result = ;
    var columnResult = [];
    for (var i = 0; i < createTableHTMLResult.allMonthsInJson.length; i++) 

        var month = createTableHTMLResult.jsonData[createTableHTMLResult.allMonthsInJson[i]].metaData.month;
        var numDays = createTableHTMLResult.jsonData[createTableHTMLResult.allMonthsInJson[i]].metaData.numDays;
        var year = createTableHTMLResult.jsonData[createTableHTMLResult.allMonthsInJson[i]].metaData.year;
        var tabName = createTableHTMLResult.allMonthsInJson[i];

        columnResult.push( "data": "managerName", title: "managerName", "name": "managerName", "defaultContent": "" );
        columnResult.push( "data": "employeeName", title: "employeeName", "name": "employeeName", "defaultContent": "" );

        for (var j = 0; j < numDays; j++) 
            if (j + 1 < 10) 
                columnResult.push( "data": month + "-0" + String(j + 1) + "-" + year, title: month + "-" + String(j + 1) + "-" + year, "name": month + "-" + String(j + 1) + "-" + year, "defaultContent": "" );
            
            else 
                columnResult.push( "data": month + "-" + String(j + 1) + "-" + year, title: month + "-" + String(j + 1) + "-" + year, "name": month + "-" + String(j + 1) + "-" + year, "defaultContent": "" );
            
        
        initiateTable(columnResult, createTableHTMLResult.jsonData[tabName].data, tabName);
        columnResult = [];
        tabName = "";
    
    resolve(result);
);
return promise;



function initiateTable(columnArray, tableData, tab) 
//console.log("initiateTable called: " + tab);
var table = $("#table-" + tab).DataTable(
    data: tableData,
    "columns": columnArray,
    "scrollX": true,
    scrollCollapse: true,
    "paging": false,
    "searching": false,
    "fixedColumns": 
        leftColumns: 2
    
);


var dataRetrievalpromise = function () 
var jsonData = ;
var promise = new Promise(function (resolve, reject) 
    //console.log('first method completed ');
    resolve(jsonData = 
        "Jan-2019": 
            "metaData": 
                "month": "Jan",
                "numDays": 31,
                "year": "2019"
            ,
            "data": [
                
                    "managerName": "Person 1",
                    "employeeName": "Employee 1",
                    "Jan-01-2019": "<span style='background-color:green;'>Event 1</span>",
                    "Jan-03-2019": "Event #3"
                ,
                
                    "managerName": "Person 1",
                    "employeeName": "Employee 2",
                    "Jan-02-2019": "Event #2"
                ,
                
                    "managerName": "Person 1",
                    "employeeName": "Employee 3",
                    "Jan-01-2019": "Event #1"
                
            ]
        ,
        "Feb-2019": 
            "metaData": 
                "month": "Feb",
                "numDays": 28,
                "year": "2019"
            ,
            "data": [
                
                    "managerName": "Person 1",
                    "employeeName": "Employee 1",
                    "Feb-01-2019": "<span style='background-color:green;'>Event 1</span>",
                    "Feb-03-2019": "Event #3"
                ,
                
                    "managerName": "Person 1",
                    "employeeName": "Employee 2",
                    "Feb-06-2019": "Event #2"
                ,
                
                    "managerName": "Person 1",
                    "employeeName": "Employee 3",
                    "Feb-01-2019": "Event #1"
                
            ]
        
    );
);
return promise;
;

HTML:

<link href="~/Content/bootstrap.css" rel="stylesheet" />
<link href="~/Content/dataTables.bootstrap.css" rel="stylesheet" />
<link href="~/Content/fixedColumns.bootstrap.css" rel="stylesheet" />
<script src="~/Scripts/jquery-3.3.1.min.js"></script>
<div class="container">
    <div role="tabpanel">
       <ul class="nav nav-tabs"></ul>
       <div class="tab-content"></div>
    </div>
</div>
<script src="~/Scripts/bootstrap337.min.js"></script>
<script src="~/Scripts/jquery.dataTables.js"></script>
<script src="~/Scripts/dataTables.bootstrap.js"></script>
<script src="~/Scripts/dataTables.responsive.js"></script>
<script src="~/Scripts/dataTables.fixedColumns.js"></script>
<script src="~/Scripts/test2.js"></script>

【问题讨论】:

【参考方案1】:

一切似乎都很好。唯一的问题是,选项卡更改的以下事件侦听器不像您在评论中提到的那样工作。

//Below works only when debugging/using breakpoints
$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) 
  $.fn.dataTable.tables( visible: true, api: true )
    .columns.adjust()
    .fixedColumns().relayout()
    .responsive.recalc();
  );
);

这是因为您正在动态呈现 html 内容,而此时 a[data-toggle="tab"] 元素不可用。最好在渲染选项卡和表格后放置该代码。

dataRetrievalpromise().then(function (result) 
  generateTabsPromise(result).then(function (result) 
    createTableHTMLPromise(result).then(function (result) 
      createTableColumnsAndDataPromise(result);
      $('a[data-toggle="tab"]').on('shown.bs.tab', function (e) 
        $.fn.dataTable.tables( visible: true, api: true )
          .columns.adjust()
          .fixedColumns().relayout()
          .responsive.recalc();
      );
    );
  );
);

Demo

【讨论】:

非常感谢 Prashant 的解释,它奏效了。问题已解决。

以上是关于使用带有引导选项卡的固定列的数据表问题的主要内容,如果未能解决你的问题,请参考以下文章

响应式数据表和引导选项卡的问题

Jinja2 和 Flask:引导选项卡仅显示第一个选项卡的内容,而不显示其余选项卡的内容

阻止引导选项卡的显示事件

带有 UINavigationController 作为选项卡的 UITabViewController

引导导航选项卡的字体颜色在活动状态下没有变化

在带有选项卡的 Winforms 的模型视图演示器中应该使用多少个演示器?