[英]Tabulator rendering issue using responsive layout
问题:如果我坚持布局:“fitColumns”,我尝试的任何其他内容似乎都会导致渲染(如果这是正确的术语)问题。 我没有使用框架(时间范围内的桥梁)。 当页面完全加载后显示表格时,无论我选择何种布局 - 它总是像“fitColumns”一样开始显示。 例如,如果我将它设置为“fitDataFill”,它将加载并显示为“fitColumns”。 当我单击另一个选项卡并再次返回时,它会显示 fitDataFill 应有的数据。
修改:
粗略的步骤顺序:
setTab function 包含两次重绘(to be sure, to be sure)。
如果您看到的代码类似于您在此处编写的代码,那么多亏了您,我编写的大部分内容都是从其他人那里收集来的。
Tabulator 版本是 4.8 代码是使用 Visual Studio Code 创建的,使用 Live Server 扩展在每次保存后重新加载页面浏览器是 Chrome 版本 85.0.4183.121(官方构建)(64 位)
HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<!-- CSS -->
<link rel="stylesheet" href="./scripts/dist/css/tabulator.min.css">
<link rel="stylesheet" href="./styles/style.css">
<!-- Scripts -->
<script type="text/javascript" src="./scripts/dist/js/tabulator.min.js"></script>
<script type="text/javascript" src="./scripts/dist/js/papaparse.min.js"></script>
<title>My Team</title>
</head>
<body>
<!-- Wrapper -->
<div class="wrapper">
<section class="container">
<!-- Header -->
<header id="header" class="header">
<h1>Reporting</h1>
</header>
<!-- Tabs -->
<div id="csv-tab-buttons" class="tab">
</div>
<!-- Tables on each tab -->
<div id="csv-tabs">
</div>
<!-- Footer -->
<footer class="footer">
<p>My Team © 2020</p>
</footer>
</section>
</div><!-- Wrapper Ends-->
<script src="./scripts/dist/js/miscsv.min.js"></script>
</body>
</html>
修订版 Javascript:
//*******************************************************************************************************
// Global variables
//*******************************************************************************************************
var file = 'DS.PPTE.DB2.VIARACF.VARLEGND.CSV'
var tables = []
var tableDivs = []
var tabConfig = {}
//*******************************************************************************************************
// Global functions
//*******************************************************************************************************
let onlyUnique = (value, index, self) => {
return self.indexOf(value) === index
}
//*******************************************************************************************************
// Async functions
//*******************************************************************************************************
// Set the tab to whichever button was clicked
async function activateTab(target) {
// hides all tabs
document.querySelectorAll(".tabcontent").forEach(tabContent => tabContent.style.display = "none");
// Remove the active class from all tab links
document.querySelectorAll('.tablinks').forEach(tabLink => tabLink.className.replace("active", ""));
// Remove the active class from the active tab
document.querySelectorAll(".active").forEach(activeTab => activeTab.classList.remove("active"))
// Activate the selected tab
document.querySelector(`#${target.textContent}`).style.display = "block"
target.classList.add("active");
}
async function setTab(target) {
console.log("Activate the tab")
await activateTab(target)
console.log("Redraw the table")
// Redraw the table
tableDivs[`${target.textContent}`].redraw(true);
}
// Read a CSV file
const readCSV = async (file) => {
return new Promise(resolve => {
Papa.parse(`data/${file}`, {
header: true,
download: true,
skipEmptyLines: true,
complete: results => {
console.log(`${file} loaded - ${results.data.length} records.`)
resolve(results)
}
})
})
}
// Get all the data first
async function getData() {
// Read the meta data file with the data and table config
let parseMeta = await readCSV(file)
tabConfig = {
// Get the names of the tables to present
tabs: parseMeta.data.map((data) => data['TABLE-NAME']).filter(onlyUnique).sort(),
// Find the file name for each table
files: parseMeta.data.map((data) => `${data['TABLE-NAME']}-${data['CSV-FILE-NAME']}`).filter(onlyUnique)
.map((entry) => {
let tmpEntry = entry.split('-')
return { table: `${tmpEntry[0]}`, file: `${tmpEntry[1]}` }
}),
// Save the float over help for each column by table name
help: parseMeta.data.map((data) => {
return { key: `${data['TABLE-NAME']}-${data['VARIABLE']}`, helpText: data['VAR-DESCRIPTION'] != '' ? data['VAR-DESCRIPTION'] : data['VARIABLE'] }
}),
data: tables,
divs: tableDivs,
}
// Read in the files which contain the table data
for (const tabName of tabConfig.tabs) {
let file = tabConfig.files.filter(entry => entry.table == tabName)[0].file
tables[tabName] = await readCSV(file)
tableDivs[tabName] = `csv-table-${tabName}`
}
}
// Master function to do everything in the right order
async function doAll() {
// Get all the data and build the table config
await getData()
// Store the buttons and tabs anchor divs
let buttonsDiv = document.getElementById("csv-tab-buttons")
let tabsDiv = document.getElementById("csv-tabs")
// Add the buttons and tables
for ([idx, tabName] of tabConfig.tabs.entries()) {
// Add tabs to hold the tables to the page
const elemTabDiv = document.createElement('div')
const elemTableDiv = document.createElement('div')
elemTabDiv.id = tabName
elemTabDiv.className = "tabcontent"
elemTableDiv.id = `csv-table-${tabName}`
elemTableDiv.className = "table"
elemTabDiv.appendChild(elemTableDiv)
tabsDiv.appendChild(elemTabDiv)
// Define header context menu
let headerMenu = [
{
label:"Hide Column",
action:function(e, column){
column.hide()
},
},
]
// Create the table
tableDivs[tabName] = new Tabulator(`#csv-table-${tabName}`, {
data:tabConfig.data[tabName].data,
layout:"fitData",
responsiveLayout:"collapse",
tooltips:true,
pagination:"local",
paginationSize:20,
resizableColumns:true,
movableColumns:true,
resizableRows:true,
autoColumns: true,
autoColumnsDefinitions: function(definitions) {
definitions.forEach((column) => {
let helpText = tabConfig.help.find(key => key.key === `${tabName}-${column.field}`).help
// Add float over help based on column name
column.headerTooltip = helpText
column.headerMenu = headerMenu
column.headerFilter = true
column.headerSort = true
column.headerFilterLiveFilter = false
})
return definitions
},
renderStarted:function(){
console.log("Render started")
},
renderComplete:function(){
console.log("Render complete")
},
})
// Add tab buttons to page
const elemTabButton = document.createElement('button')
elemTabButton.id = `button-${tabName}`
if ( idx == 0 ) {
elemTabButton.className = "tablinks active"
} else {
elemTabButton.className = "tablinks"
}
elemTabButton.onclick = function() { setTab(this) }
elemTabButton.textContent = tabName
buttonsDiv.appendChild(elemTabButton)
}
document.querySelector(".active").click();
}
doAll()
CSS:
:root {
--shadow: 0 1px 5px rgba(104, 104, 104, 0.8);
--raisin: #262730;
--vermillion: #d33f49;
--cadet: #576c75;
--navyboy: #8db2c2;
--space-cadet: #363457;
--baby-powder: #f0f4ef;
--ice: rgb(245, 247, 253);
}
html {
box-sizing: border-box;
font-family: Arial, Helvetica, sans-serif;
color: var(--dark);
}
body {
background: var(--baby-powder);
margin: 10px 10px;
line-height: 1.4;
}
/* .wrapper {
display: grid;
grid-gap: 10px;
} */
.container {
display: grid;
grid-gap: 10px;
grid-template-areas:
'header'
'csv-tab-buttons'
'footer';
margin: auto;
width: 98%;
overflow: auto;
padding: 1rem 1rem;
}
header {
background: var(--raisin);
color: var(--vermillion);
font-size: 150%;
line-height: 1;
padding: 0.1rem;
text-align: center;
box-shadow: var(--shadow);
}
.tab {
background-color: var(--ice);
box-shadow: var(--shadow);
}
/* Style the buttons that are used to open the tab content */
.tab button {
background-color: inherit;
/* float: left; */
border: none;
outline: none;
cursor: pointer;
/* padding: 14px 16px; */
padding: 1rem 1.1rem;
transition: 0.3s;
}
/* Change background color of buttons on hover */
.tab button:hover {
background-color: var(--cadet);
color: var(--ice);
}
/* Create an active/current tablink class */
.tab button.active {
background-color: var(--vermillion);
color: var(--ice);
}
/* Style the tab content */
.tabcontent {
/* overflow: hidden; */
display: none;
/* padding: 6px 12px; */
/* border-top: none; */
}
/* Override Tabulator header background */
.tabulator-col-content {
background-color: var(--ice);
}
.table {
overflow: hidden;
box-shadow: var(--shadow);
}
.footer {
background: var(--cadet);
color: white;
padding: 0rem 2rem;
line-height: 1;
box-shadow: var(--shadow);
}
编辑:我对所有内容的顺序进行了一些更改,以便在调用setTab function 时可以将表 object 保留在 scope 中,并且可以在单击选项卡按钮时发出重绘。 我第一次点击每个选项卡时,它似乎填充到数据的宽度。 当我再次单击每个选项卡时,它会正确地将屏幕外的列换行到下一行。 我在 setTab 例程中放置了多个表格重绘,这对表格的呈现没有影响。 然而,它确实以某种方式改变了表的属性。 我在调试器中观察到 tableWidth 从第一次重绘前的 0 变为 2734,在第二次重绘后变为 2786,并保持该值不变。 如果我点击离开并再次返回,它会按预期换行。
如果在创建表格时元素不可见,制表符表格将无法正确呈现。
要正确呈现表格,您必须在元素可见时重新绘制表格。
看这里
来自网站:
如果包含 Tabulator 的元素的大小发生变化(并且您无法使用内置的自动调整大小功能)或者您在其包含元素可见之前创建了一个表格,则需要重绘表格以确保行和列正确呈现。
您可以通过重绘表格
table.redraw();
要么
table.redraw(true); //trigger full rerender including all data and rows
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.