2026-05-17 17:03:21 +08:00
|
|
|
<!DOCTYPE html>
|
|
|
|
|
<html lang="en">
|
|
|
|
|
|
|
|
|
|
<head>
|
|
|
|
|
<meta charset="UTF-8">
|
|
|
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
|
|
|
<title>DataTable Demo</title>
|
|
|
|
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
|
2026-05-24 13:23:44 +08:00
|
|
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.2/font/bootstrap-icons.min.css">
|
2026-05-17 17:03:21 +08:00
|
|
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
|
|
|
|
|
<style>
|
2026-05-17 20:11:20 +08:00
|
|
|
body, html { height: 100%; margin: 0; padding: 0; overflow: hidden; }
|
|
|
|
|
.demo-container { height: 100vh; padding: 20px; display: flex; flex-direction: column; }
|
|
|
|
|
.table-wrapper { flex-grow: 1; min-height: 0; border-radius: 8px; overflow: hidden; box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08); }
|
2026-05-17 17:03:21 +08:00
|
|
|
</style>
|
|
|
|
|
</head>
|
|
|
|
|
|
|
|
|
|
<body class="bg-light">
|
|
|
|
|
<div class="demo-container">
|
|
|
|
|
<div class="table-wrapper">
|
|
|
|
|
<DataTable id="myTable"></DataTable>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
2026-05-23 17:37:25 +08:00
|
|
|
<script type="importmap">
|
|
|
|
|
{
|
|
|
|
|
"imports": {
|
|
|
|
|
"@web/state": "../../state/src/index.js",
|
|
|
|
|
"@web/base": "../../base/src/index.js"
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
</script>
|
2026-05-17 17:03:21 +08:00
|
|
|
<script type="module">
|
2026-05-17 20:11:20 +08:00
|
|
|
import { RefreshState } from '@web/state'
|
2026-05-17 17:03:21 +08:00
|
|
|
import '@web/base'
|
2026-05-28 17:07:51 +08:00
|
|
|
import { DataTable } from '../src/index.js'
|
|
|
|
|
|
|
|
|
|
// Externally register TagsInput
|
|
|
|
|
DataTable.registerFieldType({
|
|
|
|
|
value: 'TagsInput', label: '{#Tags#}', typeForDB: 'v4096',
|
|
|
|
|
schema: [{ name: 'placeholder', label: 'Placeholder', type: 'text', if: 'this.data.user_type=="TagsInput"' }],
|
|
|
|
|
formatter: (val) => Array.isArray(val) ? val.join(' | ') : val
|
|
|
|
|
});
|
2026-05-17 17:03:21 +08:00
|
|
|
|
2026-05-17 20:11:20 +08:00
|
|
|
const table = document.getElementById('myTable')
|
2026-05-17 17:03:21 +08:00
|
|
|
|
2026-05-17 20:11:20 +08:00
|
|
|
const fields = [
|
2026-05-27 23:27:45 +08:00
|
|
|
{ id: 'id', name: 'ID', type: 'string', settings: { width: 60, formType: 'text', pinned: 'left' } },
|
|
|
|
|
{ id: 'name', name: 'User Name', type: 'string', settings: { width: 150, formType: 'text', pinned: 'left' } },
|
2026-05-28 17:07:51 +08:00
|
|
|
{ id: 'role', name: 'Role', type: 'string', settings: { width: 120, formType: 'select', options: [{label:'Administrator', value:'Admin'}, {label:'Content Editor', value:'Editor'}, {label:'Viewer', value:'Viewer'}] } },
|
|
|
|
|
{ id: 'active', name: 'Active', type: 'boolean', settings: { width: 80, formType: 'switch', labelOn: 'YES', labelOff: 'NO' } },
|
2026-05-27 23:27:45 +08:00
|
|
|
{ id: 'bio', name: 'Bio', type: 'string', settings: { width: 250, formType: 'textarea' } },
|
|
|
|
|
{ id: 'gender', name: 'Gender', type: 'string', settings: { width: 120, formType: 'radio', options: ['Male', 'Female', 'Other'] } },
|
|
|
|
|
{ id: 'tags', name: 'Tags', type: 'object', settings: { width: 150, formType: 'TagsInput' } },
|
2026-05-28 17:07:51 +08:00
|
|
|
{ id: 'score', name: 'Score', type: 'number', settings: { width: 100, formType: 'number', prefix: '$', decimals: 2, thousandSep: true } },
|
2026-05-27 23:27:45 +08:00
|
|
|
{ id: 'created', name: 'Created At', type: 'date', settings: { width: 150, formType: 'date' } },
|
2026-05-28 17:07:51 +08:00
|
|
|
{ id: 'actions', name: 'Actions', type: 'string', settings: { width: 100, formType: 'text', pinned: 'right' }, formatter: () => '🔧 Edit' }
|
2026-05-17 20:11:20 +08:00
|
|
|
]
|
2026-05-17 17:03:21 +08:00
|
|
|
|
2026-05-17 20:11:20 +08:00
|
|
|
const generateData = (count) => Array.from({ length: count }, (_, i) => ({
|
|
|
|
|
id: i + 1,
|
|
|
|
|
name: 'User ' + (i + 1),
|
|
|
|
|
role: ['Admin', 'Editor', 'Viewer'][i % 3],
|
|
|
|
|
active: i % 2 === 0,
|
|
|
|
|
bio: 'Bio ' + (i + 1),
|
|
|
|
|
gender: ['Male', 'Female', 'Other'][i % 3],
|
|
|
|
|
tags: ['State.js', 'Vite'].slice(0, (i % 2) + 1),
|
2026-05-28 17:07:51 +08:00
|
|
|
score: 8000.5,
|
2026-05-17 20:11:20 +08:00
|
|
|
created: '2026-05-17',
|
|
|
|
|
actions: '...'
|
|
|
|
|
}))
|
2026-05-17 17:03:21 +08:00
|
|
|
|
2026-05-23 17:37:25 +08:00
|
|
|
const data = generateData(1000)
|
2026-05-17 17:03:21 +08:00
|
|
|
|
2026-05-17 20:11:20 +08:00
|
|
|
const init = () => {
|
|
|
|
|
if (table.state) {
|
2026-05-27 23:27:45 +08:00
|
|
|
table.state.fields = fields;
|
|
|
|
|
table.state.list = data;
|
2026-05-23 17:37:25 +08:00
|
|
|
RefreshState(table);
|
2026-05-17 20:11:20 +08:00
|
|
|
window.testStatus = 'passed';
|
|
|
|
|
} else {
|
|
|
|
|
setTimeout(init, 50);
|
|
|
|
|
}
|
|
|
|
|
};
|
2026-05-23 17:37:25 +08:00
|
|
|
|
|
|
|
|
document.addEventListener('DOMContentLoaded', () => {
|
|
|
|
|
RefreshState(document.documentElement);
|
|
|
|
|
init();
|
|
|
|
|
});
|
2026-05-17 17:03:21 +08:00
|
|
|
</script>
|
|
|
|
|
</body>
|
2026-05-17 18:50:30 +08:00
|
|
|
</html>
|