- 增加树形结构表格
This commit is contained in:
20
README.md
20
README.md
@@ -51,6 +51,10 @@
|
||||
<td colspan="2">合计</td>
|
||||
...
|
||||
<td>18988.00</td>
|
||||
...
|
||||
<tr expand="001"> <!-- 指定当前为展开行 -->
|
||||
<tr expand-parent="001"> <!-- 指定当前为展开行子项 -->
|
||||
<tr expand="001-001" expand-parent="001"> <!-- 指定当前为展开行及为其他行子项 -->
|
||||
```
|
||||
- 初始化表格
|
||||
```javascript
|
||||
@@ -65,14 +69,14 @@
|
||||
|
||||
### Table Attributes
|
||||
|
||||
| Property | Tag Position | Description |
|
||||
| :---------------- | :--------------------- | :---------------------------------------------------------------- |
|
||||
| stripe | table | 表格是否需要斑马间隔色 |
|
||||
| fixed | thead -> tr -> th | 是否固定该列 |
|
||||
| sort | thead -> tr -> th | 是否对该列有排序功能(默认按照string排序,可指定为sort="number" ) |
|
||||
| unsort | tbody -> tr | 可指定body中的某一行不参与排序 |
|
||||
| expand | tbody -> tr | 可指定body中的某一行是否需要展开 |
|
||||
| expand-child | tbody -> tr | 可指定body中的某一行为上一级子项 |
|
||||
| Property | Tag Position | Description |
|
||||
| :---------------- | :--------------------- | :---------------------------------------------------------------------------- |
|
||||
| stripe | table | 表格是否需要斑马间隔色 |
|
||||
| fixed | thead -> tr -> th | 是否固定该列 |
|
||||
| sort | thead -> tr -> th | 是否对该列有排序功能(默认按照string排序,可指定为sort="number" ) |
|
||||
| unsort | tbody -> tr | 可指定body中的某一行不参与排序 |
|
||||
| expand | tbody -> tr | 可指定body中的某一行是否需要展开, 指定expand="001" 001为当前行的ID |
|
||||
| expand-parent | tbody -> tr | 可指定body中的某一行是子项, 指定expand-parent="001" 001为父级ID |
|
||||
|
||||
|
||||
### Table Options
|
||||
|
||||
@@ -262,7 +262,6 @@
|
||||
<thead>
|
||||
<tr>
|
||||
<th colspan="1" fixed width="200">Id</th>
|
||||
<th colspan="1" sort>Logo</th>
|
||||
<th colspan="1" width="200">日期</th>
|
||||
<th colspan="1" width="100">姓名</th>
|
||||
<th colspan="1">省份(包含自治区)</th>
|
||||
@@ -272,7 +271,7 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr expand>
|
||||
<tr expand="001">
|
||||
<td>001</td>
|
||||
<td>2020-05-02</td>
|
||||
<td>王小虎2</td>
|
||||
@@ -280,9 +279,8 @@
|
||||
<td>长宁区2</td>
|
||||
<td>上海市长宁区淞虹路888号2</td>
|
||||
<td>200332</td>
|
||||
<td><a href="#">查看2</a></td>
|
||||
</tr>
|
||||
<tr expand-child>
|
||||
<tr expand-parent="001">
|
||||
<td>001-1</td>
|
||||
<td>2020-05-03</td>
|
||||
<td>上小虎3</td>
|
||||
@@ -290,9 +288,8 @@
|
||||
<td>长宁区3</td>
|
||||
<td>上海市长宁区淞虹路888号3</td>
|
||||
<td>200333</td>
|
||||
<td><a href="#">查看3</a></td>
|
||||
</tr>
|
||||
<tr expand expand-child>
|
||||
<tr expand="001-001" expand-parent="001">
|
||||
<td>001-2</td>
|
||||
<td>2020-05-03</td>
|
||||
<td>上小虎3</td>
|
||||
@@ -300,9 +297,8 @@
|
||||
<td>长宁区3</td>
|
||||
<td>上海市长宁区淞虹路888号3</td>
|
||||
<td>200333</td>
|
||||
<td><a href="#">查看3</a></td>
|
||||
</tr>
|
||||
<tr expand-child>
|
||||
<tr expand-parent="001-001">
|
||||
<td>001-2-1</td>
|
||||
<td>2020-05-03</td>
|
||||
<td>上小虎3</td>
|
||||
@@ -310,9 +306,8 @@
|
||||
<td>长宁区3</td>
|
||||
<td>上海市长宁区淞虹路888号3</td>
|
||||
<td>200333</td>
|
||||
<td><a href="#">查看3</a></td>
|
||||
</tr>
|
||||
<tr expand-child>
|
||||
<tr expand-parent="001-001">
|
||||
<td>001-2-2</td>
|
||||
<td>2020-05-03</td>
|
||||
<td>上小虎3</td>
|
||||
@@ -320,9 +315,17 @@
|
||||
<td>长宁区3</td>
|
||||
<td>上海市长宁区淞虹路888号3</td>
|
||||
<td>200333</td>
|
||||
<td><a href="#">查看3</a></td>
|
||||
</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>2020-01-03</td>
|
||||
<td>小小虎1</td>
|
||||
@@ -330,9 +333,8 @@
|
||||
<td>长宁区1</td>
|
||||
<td>上海市长宁区淞虹路888号1</td>
|
||||
<td>200331</td>
|
||||
<td><a href="#">查看1</a></td>
|
||||
</tr>
|
||||
<tr expand-child>
|
||||
<tr expand-parent="002">
|
||||
<td>002-1</td>
|
||||
<td>2020-05-04</td>
|
||||
<td>王小虎4</td>
|
||||
@@ -340,9 +342,8 @@
|
||||
<td>长宁区4</td>
|
||||
<td>上海市长宁区淞虹路888号4</td>
|
||||
<td>200334</td>
|
||||
<td><a href="#">查看4</a></td>
|
||||
</tr>
|
||||
<tr expand-child>
|
||||
<tr expand-parent="002">
|
||||
<td>002-2</td>
|
||||
<td>2020-01-03</td>
|
||||
<td>小小虎1</td>
|
||||
@@ -350,7 +351,6 @@
|
||||
<td>长宁区1</td>
|
||||
<td>上海市长宁区淞虹路888号1</td>
|
||||
<td>200331</td>
|
||||
<td><a href="#">查看1</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>003</td>
|
||||
@@ -360,7 +360,6 @@
|
||||
<td>长宁区4</td>
|
||||
<td>上海市长宁区淞虹路888号4</td>
|
||||
<td>200334</td>
|
||||
<td><a href="#">查看4</a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
@@ -3,6 +3,7 @@ import {
|
||||
setAttribute,
|
||||
removeAttribute,
|
||||
hasAttribute,
|
||||
getAttribute,
|
||||
appendChild,
|
||||
appendChildren,
|
||||
removeChild,
|
||||
@@ -14,7 +15,7 @@ import createFixed from './fixed';
|
||||
import {
|
||||
throttle,
|
||||
debounce,
|
||||
getIntByAttr,
|
||||
getAttrNumber,
|
||||
refactorCell,
|
||||
replaceColGroup,
|
||||
createTableWrapper,
|
||||
@@ -42,11 +43,14 @@ export default function initMixin(Table) {
|
||||
options.align && root.classList.add("stb-cust-" + options.align)
|
||||
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")
|
||||
}), querySelectorAll(thead, 'th[fixed]').forEach(column => {
|
||||
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;
|
||||
@@ -125,9 +129,9 @@ function initColgroupData(vm) {
|
||||
props.shapes.forEach(shape => {
|
||||
shape.forEach((column, cIndex) => {
|
||||
if (column) {
|
||||
let colspan = getIntByAttr(column, 'colspan', 1)
|
||||
let colspan = getAttrNumber(column, '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 seek(arr) {
|
||||
arr.forEach(item => {
|
||||
if (item.expand) {
|
||||
let row = item.$el;
|
||||
let column = querySelector(row, "td");
|
||||
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)
|
||||
}
|
||||
querySelector(item.$el, "td").addEventListener('click', () => {
|
||||
expanding(item, !hasAttribute(item.$el, "expanded"))
|
||||
})
|
||||
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)
|
||||
|
||||
}
|
||||
|
||||
function bindScrollEvents(vm) {
|
||||
@@ -296,7 +294,7 @@ function bindSortEvents(vm) {
|
||||
el.addEventListener("click", $event => {
|
||||
$event.stopPropagation();
|
||||
let sortType = "ASC";
|
||||
let sortOrder = el.getAttribute("sort") || "string";
|
||||
let sortOrder = getAttribute(el, "sort") || "string";
|
||||
if (el.classList.contains("asc")) {
|
||||
el.classList.remove("asc");
|
||||
el.classList.add("desc");
|
||||
@@ -311,7 +309,7 @@ function bindSortEvents(vm) {
|
||||
}
|
||||
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 columns = querySelectorAll(row, "th");
|
||||
columns.forEach((column) => {
|
||||
let rowspan = getIntByAttr(column, "rowspan", 1);
|
||||
let colspan = getIntByAttr(column, "colspan", 1);
|
||||
let rowspan = getAttrNumber(column, "rowspan", 1);
|
||||
let colspan = getAttrNumber(column, "colspan", 1);
|
||||
let insertIndex = getEmptyIndexInArray(shape) || shape.length;
|
||||
shape[insertIndex] = column;
|
||||
|
||||
@@ -382,7 +380,7 @@ function initFixed(vm) {
|
||||
if (hasAttribute(columns[i], "fixed")) {
|
||||
lastLeftIndex = 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++) {
|
||||
fixedLeft.tbody.push("field-" + (i + j));
|
||||
fixedLeft.width += colgroup[i + j];
|
||||
@@ -402,7 +400,7 @@ function initFixed(vm) {
|
||||
break;
|
||||
}
|
||||
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++) {
|
||||
rightCnt++;
|
||||
fixedRight.tbody.push("field-" + (colgroupLen - rightCnt))
|
||||
@@ -419,43 +417,49 @@ function initFixed(vm) {
|
||||
}
|
||||
|
||||
function initExpand(vm, tbody) {
|
||||
const expandedAll = vm.options.defaultExpandAll;
|
||||
const expandAll = vm.options.defaultExpandAll;
|
||||
let data = [];
|
||||
let parents = [];
|
||||
querySelectorAll(tbody, "tr").forEach(row => {
|
||||
let paddingLength = parents.length;
|
||||
let expand = hasAttribute(row, "expand");
|
||||
let child = hasAttribute(row, "expand-child");
|
||||
let node = { $el: row, expand: expand };
|
||||
if (child) {
|
||||
querySelector(row, "td").style.paddingLeft = 20 * (parents.length) + "px";
|
||||
row.style.display = expandedAll ? '' : 'none'
|
||||
}
|
||||
let hasParent = hasAttribute(row, "expand-parent");
|
||||
let node = { $el: row, id: getAttribute(row, "expand"), expand: expand };
|
||||
if (expand) {
|
||||
if (expandedAll) {
|
||||
if (expandAll) {
|
||||
setAttribute(row, 'expanded')
|
||||
} else {
|
||||
removeAttribute(row, 'expanded')
|
||||
}
|
||||
}
|
||||
if (expand && !child) {
|
||||
if (expand && !hasParent) {
|
||||
node.children = [];
|
||||
parents = [node];
|
||||
data.push(node);
|
||||
} else if (!expand && child) {
|
||||
let parent = parents[parents.length - 1]
|
||||
if (parent) {
|
||||
parent.children.push(node)
|
||||
} else if (hasParent) {
|
||||
let parentId = getAttribute(row, "expand-parent");
|
||||
let arr = [];
|
||||
for (let i = 0; i < parents.length; i++) {
|
||||
arr.push(parents[i])
|
||||
if (parents[i].id === parentId) {
|
||||
break
|
||||
}
|
||||
}
|
||||
} else if (expand && child) {
|
||||
node.children = [];
|
||||
let parent = parents[parents.length - 1]
|
||||
if (parent) {
|
||||
parent.children.push(node)
|
||||
parents = arr;
|
||||
paddingLength = parents.length;
|
||||
let parent = parents[parents.length - 1];
|
||||
parent && parent.children.push(node);
|
||||
if (expand) {
|
||||
parents.push(node)
|
||||
node.children = [];
|
||||
}
|
||||
parents.push(node)
|
||||
} else {
|
||||
data.push(node)
|
||||
}
|
||||
if (hasParent) {
|
||||
querySelector(row, "td").style.paddingLeft = 20 * paddingLength + "px";
|
||||
row.style.display = expandAll ? '' : 'none'
|
||||
}
|
||||
})
|
||||
vm.expandData = data;
|
||||
vm.$tbodyWrapper.style.height = ''
|
||||
|
||||
@@ -6,7 +6,7 @@ import {
|
||||
querySelectorAll
|
||||
} from './node-ops';
|
||||
import {
|
||||
getIntByAttr,
|
||||
getAttrNumber,
|
||||
createTableWrapper,
|
||||
} from './utils';
|
||||
|
||||
@@ -64,7 +64,7 @@ function createBodyWrapper(vm, model, meta, type) {
|
||||
if (type === 'left') {
|
||||
offsetX = index
|
||||
} else {
|
||||
offsetX += getIntByAttr(column, "colspan", 1);
|
||||
offsetX += getAttrNumber(column, "colspan", 1);
|
||||
}
|
||||
if (meta.tbody.indexOf("field-" + offsetX) === -1) {
|
||||
column.classList.add('is-hidden')
|
||||
|
||||
@@ -16,6 +16,10 @@ export function setAttribute(node, attrName, attrValue) {
|
||||
return node.setAttribute(attrName, attrValue || true)
|
||||
}
|
||||
|
||||
export function getAttribute(node, attrName) {
|
||||
return node.getAttribute(attrName)
|
||||
}
|
||||
|
||||
export function removeAttribute(node, attrName) {
|
||||
return node.removeAttribute(attrName)
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import {
|
||||
appendChild,
|
||||
getAttribute,
|
||||
createElement,
|
||||
querySelector,
|
||||
appendChildren,
|
||||
@@ -31,8 +32,8 @@ export function replaceColGroup(vm) {
|
||||
})
|
||||
}
|
||||
|
||||
export function getIntByAttr(el, key, def) {
|
||||
return Number.parseInt(el.getAttribute(key) || def)
|
||||
export function getAttrNumber(el, key, def) {
|
||||
return Number.parseInt(getAttribute(el, key) || def)
|
||||
}
|
||||
|
||||
export function getEmptyIndexInArray(array) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "smart-table",
|
||||
"version": "1.1.1",
|
||||
"version": "1.1.2",
|
||||
"description": "smart table for static html",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
@@ -30,4 +30,4 @@
|
||||
},
|
||||
"dependencies": {},
|
||||
"keywords": []
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user