- 增加树形结构表格

This commit is contained in:
Julyp
2020-02-06 18:51:14 +08:00
parent cdee69bb82
commit 076d64be9e
7 changed files with 91 additions and 79 deletions

View File

@@ -51,6 +51,10 @@
<td colspan="2">合计</td> <td colspan="2">合计</td>
... ...
<td>18988.00</td> <td>18988.00</td>
...
<tr expand="001"> <!-- 指定当前为展开行 -->
<tr expand-parent="001"> <!-- 指定当前为展开行子项 -->
<tr expand="001-001" expand-parent="001"> <!-- 指定当前为展开行及为其他行子项 -->
``` ```
- 初始化表格 - 初始化表格
```javascript ```javascript
@@ -65,14 +69,14 @@
### Table Attributes ### Table Attributes
| Property | Tag Position | Description | | Property | Tag Position | Description |
| :---------------- | :--------------------- | :---------------------------------------------------------------- | | :---------------- | :--------------------- | :---------------------------------------------------------------------------- |
| stripe | table | 表格是否需要斑马间隔色 | | stripe | table | 表格是否需要斑马间隔色 |
| fixed | thead -> tr -> th | 是否固定该列 | | fixed | thead -> tr -> th | 是否固定该列 |
| sort | thead -> tr -> th | 是否对该列有排序功能默认按照string排序可指定为sort="number" | | sort | thead -> tr -> th | 是否对该列有排序功能默认按照string排序可指定为sort="number" |
| unsort | tbody -> tr | 可指定body中的某一行不参与排序 | | unsort | tbody -> tr | 可指定body中的某一行不参与排序 |
| expand | tbody -> tr | 可指定body中的某一行是否需要展开 | | expand | tbody -> tr | 可指定body中的某一行是否需要展开 指定expand="001" 001为当前行的ID |
| expand-child | tbody -> tr | 可指定body中的某一行为上一级子项 | | expand-parent | tbody -> tr | 可指定body中的某一行子项 指定expand-parent="001" 001为父级ID |
### Table Options ### Table Options

View File

@@ -262,7 +262,6 @@
<thead> <thead>
<tr> <tr>
<th colspan="1" fixed width="200">Id</th> <th colspan="1" fixed width="200">Id</th>
<th colspan="1" sort>Logo</th>
<th colspan="1" width="200">日期</th> <th colspan="1" width="200">日期</th>
<th colspan="1" width="100">姓名</th> <th colspan="1" width="100">姓名</th>
<th colspan="1">省份(包含自治区)</th> <th colspan="1">省份(包含自治区)</th>
@@ -272,7 +271,7 @@
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr expand> <tr expand="001">
<td>001</td> <td>001</td>
<td>2020-05-02</td> <td>2020-05-02</td>
<td>王小虎2</td> <td>王小虎2</td>
@@ -280,9 +279,8 @@
<td>长宁区2</td> <td>长宁区2</td>
<td>上海市长宁区淞虹路888号2</td> <td>上海市长宁区淞虹路888号2</td>
<td>200332</td> <td>200332</td>
<td><a href="#">查看2</a></td>
</tr> </tr>
<tr expand-child> <tr expand-parent="001">
<td>001-1</td> <td>001-1</td>
<td>2020-05-03</td> <td>2020-05-03</td>
<td>上小虎3</td> <td>上小虎3</td>
@@ -290,9 +288,8 @@
<td>长宁区3</td> <td>长宁区3</td>
<td>上海市长宁区淞虹路888号3</td> <td>上海市长宁区淞虹路888号3</td>
<td>200333</td> <td>200333</td>
<td><a href="#">查看3</a></td>
</tr> </tr>
<tr expand expand-child> <tr expand="001-001" expand-parent="001">
<td>001-2</td> <td>001-2</td>
<td>2020-05-03</td> <td>2020-05-03</td>
<td>上小虎3</td> <td>上小虎3</td>
@@ -300,9 +297,8 @@
<td>长宁区3</td> <td>长宁区3</td>
<td>上海市长宁区淞虹路888号3</td> <td>上海市长宁区淞虹路888号3</td>
<td>200333</td> <td>200333</td>
<td><a href="#">查看3</a></td>
</tr> </tr>
<tr expand-child> <tr expand-parent="001-001">
<td>001-2-1</td> <td>001-2-1</td>
<td>2020-05-03</td> <td>2020-05-03</td>
<td>上小虎3</td> <td>上小虎3</td>
@@ -310,9 +306,8 @@
<td>长宁区3</td> <td>长宁区3</td>
<td>上海市长宁区淞虹路888号3</td> <td>上海市长宁区淞虹路888号3</td>
<td>200333</td> <td>200333</td>
<td><a href="#">查看3</a></td>
</tr> </tr>
<tr expand-child> <tr expand-parent="001-001">
<td>001-2-2</td> <td>001-2-2</td>
<td>2020-05-03</td> <td>2020-05-03</td>
<td>上小虎3</td> <td>上小虎3</td>
@@ -320,9 +315,17 @@
<td>长宁区3</td> <td>长宁区3</td>
<td>上海市长宁区淞虹路888号3</td> <td>上海市长宁区淞虹路888号3</td>
<td>200333</td> <td>200333</td>
<td><a href="#">查看3</a></td>
</tr> </tr>
<tr expand> <tr expand-parent="001">
<td>001-3</td>
<td>2020-05-03</td>
<td>上小虎3</td>
<td>上海3</td>
<td>长宁区3</td>
<td>上海市长宁区淞虹路888号3</td>
<td>200333</td>
</tr>
<tr expand="002">
<td>002</td> <td>002</td>
<td>2020-01-03</td> <td>2020-01-03</td>
<td>小小虎1</td> <td>小小虎1</td>
@@ -330,9 +333,8 @@
<td>长宁区1</td> <td>长宁区1</td>
<td>上海市长宁区淞虹路888号1</td> <td>上海市长宁区淞虹路888号1</td>
<td>200331</td> <td>200331</td>
<td><a href="#">查看1</a></td>
</tr> </tr>
<tr expand-child> <tr expand-parent="002">
<td>002-1</td> <td>002-1</td>
<td>2020-05-04</td> <td>2020-05-04</td>
<td>王小虎4</td> <td>王小虎4</td>
@@ -340,9 +342,8 @@
<td>长宁区4</td> <td>长宁区4</td>
<td>上海市长宁区淞虹路888号4</td> <td>上海市长宁区淞虹路888号4</td>
<td>200334</td> <td>200334</td>
<td><a href="#">查看4</a></td>
</tr> </tr>
<tr expand-child> <tr expand-parent="002">
<td>002-2</td> <td>002-2</td>
<td>2020-01-03</td> <td>2020-01-03</td>
<td>小小虎1</td> <td>小小虎1</td>
@@ -350,7 +351,6 @@
<td>长宁区1</td> <td>长宁区1</td>
<td>上海市长宁区淞虹路888号1</td> <td>上海市长宁区淞虹路888号1</td>
<td>200331</td> <td>200331</td>
<td><a href="#">查看1</a></td>
</tr> </tr>
<tr> <tr>
<td>003</td> <td>003</td>
@@ -360,7 +360,6 @@
<td>长宁区4</td> <td>长宁区4</td>
<td>上海市长宁区淞虹路888号4</td> <td>上海市长宁区淞虹路888号4</td>
<td>200334</td> <td>200334</td>
<td><a href="#">查看4</a></td>
</tr> </tr>
</tbody> </tbody>
</table> </table>

View File

@@ -3,6 +3,7 @@ import {
setAttribute, setAttribute,
removeAttribute, removeAttribute,
hasAttribute, hasAttribute,
getAttribute,
appendChild, appendChild,
appendChildren, appendChildren,
removeChild, removeChild,
@@ -14,7 +15,7 @@ import createFixed from './fixed';
import { import {
throttle, throttle,
debounce, debounce,
getIntByAttr, getAttrNumber,
refactorCell, refactorCell,
replaceColGroup, replaceColGroup,
createTableWrapper, createTableWrapper,
@@ -42,11 +43,14 @@ export default function initMixin(Table) {
options.align && root.classList.add("stb-cust-" + options.align) options.align && root.classList.add("stb-cust-" + options.align)
hasAttribute(table, "stripe") && tbody.classList.add("stripe") hasAttribute(table, "stripe") && tbody.classList.add("stripe")
//树形结构时 清理不应该有的sort及fixed options.expand ? (querySelectorAll(thead, 'th[sort]').forEach(column => {
options.expand && (querySelectorAll(thead, 'th[sort]').forEach(column => {
removeAttribute(column, "sort") removeAttribute(column, "sort")
}), querySelectorAll(thead, 'th[fixed]').forEach(column => { }), querySelectorAll(thead, 'th[fixed]').forEach(column => {
removeAttribute(column, "fixed") removeAttribute(column, "fixed")
})) : (querySelectorAll(tbody, 'tr[expand]').forEach(column => {
removeAttribute(column, "expand")
}), querySelectorAll(thead, 'tr[expand-parent]').forEach(column => {
removeAttribute(column, "expand-parent")
})) }))
const vm = this; const vm = this;
@@ -125,9 +129,9 @@ function initColgroupData(vm) {
props.shapes.forEach(shape => { props.shapes.forEach(shape => {
shape.forEach((column, cIndex) => { shape.forEach((column, cIndex) => {
if (column) { if (column) {
let colspan = getIntByAttr(column, 'colspan', 1) let colspan = getAttrNumber(column, 'colspan', 1)
if (colspan === 1) { if (colspan === 1) {
arr[cIndex] = getIntByAttr(column, 'width', 0) arr[cIndex] = getAttrNumber(column, 'width', 0)
} }
} }
}) })
@@ -230,31 +234,25 @@ function syncPostion(vm) {
} }
function bindExpandEvents(vm) { function bindExpandEvents(vm) {
function seek(arr) { function seek(arr) {
arr.forEach(item => { arr.forEach(item => {
if (item.expand) { if (item.expand) {
let row = item.$el; querySelector(item.$el, "td").addEventListener('click', () => {
let column = querySelector(row, "td"); expanding(item, !hasAttribute(item.$el, "expanded"))
column.addEventListener('click', () => {
let display = '';
if (hasAttribute(row, "expanded")) {
removeAttribute(row, "expanded")
display = 'none'
} else {
setAttribute(row, "expanded")
}
if (item.children) {
item.children.forEach(child => child.$el.style.display = display)
}
}) })
if (item.children && item.children.length > 0) seek(item.children) item.children && seek(item.children)
} }
}) })
function expanding(item, expanded) {
expanded ? setAttribute(item.$el, "expanded") : removeAttribute(item.$el, "expanded");
item.children && (item.children.forEach(child => {
child.$el.style.display = expanded ? '' : 'none';
expanding(child, expanded)
}))
}
} }
seek(vm.expandData) seek(vm.expandData)
} }
function bindScrollEvents(vm) { function bindScrollEvents(vm) {
@@ -296,7 +294,7 @@ function bindSortEvents(vm) {
el.addEventListener("click", $event => { el.addEventListener("click", $event => {
$event.stopPropagation(); $event.stopPropagation();
let sortType = "ASC"; let sortType = "ASC";
let sortOrder = el.getAttribute("sort") || "string"; let sortOrder = getAttribute(el, "sort") || "string";
if (el.classList.contains("asc")) { if (el.classList.contains("asc")) {
el.classList.remove("asc"); el.classList.remove("asc");
el.classList.add("desc"); el.classList.add("desc");
@@ -311,7 +309,7 @@ function bindSortEvents(vm) {
} }
return item return item
}) })
sort(vm, el.getAttribute("sortkey"), sortType, sortOrder) sort(vm, getAttribute(el, "sortkey"), sortType, sortOrder)
}) })
}) })
} }
@@ -325,8 +323,8 @@ function initProps(vm) {
let shape = shapes[index] || []; let shape = shapes[index] || [];
let columns = querySelectorAll(row, "th"); let columns = querySelectorAll(row, "th");
columns.forEach((column) => { columns.forEach((column) => {
let rowspan = getIntByAttr(column, "rowspan", 1); let rowspan = getAttrNumber(column, "rowspan", 1);
let colspan = getIntByAttr(column, "colspan", 1); let colspan = getAttrNumber(column, "colspan", 1);
let insertIndex = getEmptyIndexInArray(shape) || shape.length; let insertIndex = getEmptyIndexInArray(shape) || shape.length;
shape[insertIndex] = column; shape[insertIndex] = column;
@@ -382,7 +380,7 @@ function initFixed(vm) {
if (hasAttribute(columns[i], "fixed")) { if (hasAttribute(columns[i], "fixed")) {
lastLeftIndex = i; lastLeftIndex = i;
fixedLeft.thead.push("field-" + i); fixedLeft.thead.push("field-" + i);
let colspan = getIntByAttr(columns[i], "colspan", 1); let colspan = getAttrNumber(columns[i], "colspan", 1);
for (let j = 0; j < colspan; j++) { for (let j = 0; j < colspan; j++) {
fixedLeft.tbody.push("field-" + (i + j)); fixedLeft.tbody.push("field-" + (i + j));
fixedLeft.width += colgroup[i + j]; fixedLeft.width += colgroup[i + j];
@@ -402,7 +400,7 @@ function initFixed(vm) {
break; break;
} }
fixedRight.thead.push("field-" + i); fixedRight.thead.push("field-" + i);
let colspan = getIntByAttr(columns[i], "colspan", 1); let colspan = getAttrNumber(columns[i], "colspan", 1);
for (let j = 0; j < colspan; j++) { for (let j = 0; j < colspan; j++) {
rightCnt++; rightCnt++;
fixedRight.tbody.push("field-" + (colgroupLen - rightCnt)) fixedRight.tbody.push("field-" + (colgroupLen - rightCnt))
@@ -419,43 +417,49 @@ function initFixed(vm) {
} }
function initExpand(vm, tbody) { function initExpand(vm, tbody) {
const expandedAll = vm.options.defaultExpandAll; const expandAll = vm.options.defaultExpandAll;
let data = []; let data = [];
let parents = []; let parents = [];
querySelectorAll(tbody, "tr").forEach(row => { querySelectorAll(tbody, "tr").forEach(row => {
let paddingLength = parents.length;
let expand = hasAttribute(row, "expand"); let expand = hasAttribute(row, "expand");
let child = hasAttribute(row, "expand-child"); let hasParent = hasAttribute(row, "expand-parent");
let node = { $el: row, expand: expand }; let node = { $el: row, id: getAttribute(row, "expand"), expand: expand };
if (child) {
querySelector(row, "td").style.paddingLeft = 20 * (parents.length) + "px";
row.style.display = expandedAll ? '' : 'none'
}
if (expand) { if (expand) {
if (expandedAll) { if (expandAll) {
setAttribute(row, 'expanded') setAttribute(row, 'expanded')
} else { } else {
removeAttribute(row, 'expanded') removeAttribute(row, 'expanded')
} }
} }
if (expand && !child) { if (expand && !hasParent) {
node.children = []; node.children = [];
parents = [node]; parents = [node];
data.push(node); data.push(node);
} else if (!expand && child) { } else if (hasParent) {
let parent = parents[parents.length - 1] let parentId = getAttribute(row, "expand-parent");
if (parent) { let arr = [];
parent.children.push(node) for (let i = 0; i < parents.length; i++) {
arr.push(parents[i])
if (parents[i].id === parentId) {
break
}
} }
} else if (expand && child) { parents = arr;
node.children = []; paddingLength = parents.length;
let parent = parents[parents.length - 1] let parent = parents[parents.length - 1];
if (parent) { parent && parent.children.push(node);
parent.children.push(node) if (expand) {
parents.push(node)
node.children = [];
} }
parents.push(node)
} else { } else {
data.push(node) data.push(node)
} }
if (hasParent) {
querySelector(row, "td").style.paddingLeft = 20 * paddingLength + "px";
row.style.display = expandAll ? '' : 'none'
}
}) })
vm.expandData = data; vm.expandData = data;
vm.$tbodyWrapper.style.height = '' vm.$tbodyWrapper.style.height = ''

View File

@@ -6,7 +6,7 @@ import {
querySelectorAll querySelectorAll
} from './node-ops'; } from './node-ops';
import { import {
getIntByAttr, getAttrNumber,
createTableWrapper, createTableWrapper,
} from './utils'; } from './utils';
@@ -64,7 +64,7 @@ function createBodyWrapper(vm, model, meta, type) {
if (type === 'left') { if (type === 'left') {
offsetX = index offsetX = index
} else { } else {
offsetX += getIntByAttr(column, "colspan", 1); offsetX += getAttrNumber(column, "colspan", 1);
} }
if (meta.tbody.indexOf("field-" + offsetX) === -1) { if (meta.tbody.indexOf("field-" + offsetX) === -1) {
column.classList.add('is-hidden') column.classList.add('is-hidden')

View File

@@ -16,6 +16,10 @@ export function setAttribute(node, attrName, attrValue) {
return node.setAttribute(attrName, attrValue || true) return node.setAttribute(attrName, attrValue || true)
} }
export function getAttribute(node, attrName) {
return node.getAttribute(attrName)
}
export function removeAttribute(node, attrName) { export function removeAttribute(node, attrName) {
return node.removeAttribute(attrName) return node.removeAttribute(attrName)
} }

View File

@@ -1,5 +1,6 @@
import { import {
appendChild, appendChild,
getAttribute,
createElement, createElement,
querySelector, querySelector,
appendChildren, appendChildren,
@@ -31,8 +32,8 @@ export function replaceColGroup(vm) {
}) })
} }
export function getIntByAttr(el, key, def) { export function getAttrNumber(el, key, def) {
return Number.parseInt(el.getAttribute(key) || def) return Number.parseInt(getAttribute(el, key) || def)
} }
export function getEmptyIndexInArray(array) { export function getEmptyIndexInArray(array) {

View File

@@ -1,6 +1,6 @@
{ {
"name": "smart-table", "name": "smart-table",
"version": "1.1.1", "version": "1.1.2",
"description": "smart table for static html", "description": "smart table for static html",
"main": "index.js", "main": "index.js",
"scripts": { "scripts": {
@@ -30,4 +30,4 @@
}, },
"dependencies": {}, "dependencies": {},
"keywords": [] "keywords": []
} }