2020-02-02 15:20:49 +08:00
|
|
|
import {
|
|
|
|
|
cloneNode,
|
|
|
|
|
appendChild,
|
|
|
|
|
appendChildren,
|
|
|
|
|
createElement,
|
2020-02-07 14:34:40 +08:00
|
|
|
querySelectorAll,
|
|
|
|
|
offsetHeight,
|
|
|
|
|
styled,
|
2020-02-02 15:20:49 +08:00
|
|
|
} from './node-ops';
|
|
|
|
|
import {
|
2020-02-06 18:51:14 +08:00
|
|
|
getAttrNumber,
|
2020-02-05 11:12:40 +08:00
|
|
|
createTableWrapper,
|
2020-02-02 15:20:49 +08:00
|
|
|
} from './utils';
|
|
|
|
|
|
|
|
|
|
export default function(vm, theadModel, tbodyModel) {
|
|
|
|
|
let rootMinWidth = 320;
|
|
|
|
|
const { fixedLeft, fixedRight } = vm.props;
|
|
|
|
|
|
|
|
|
|
//左边有固定列
|
|
|
|
|
if (fixedLeft.thead.length > 0) {
|
|
|
|
|
rootMinWidth = rootMinWidth > fixedLeft.width ? rootMinWidth : fixedLeft.width;
|
|
|
|
|
const headerWrapper = createHeaderWrapper(vm, theadModel, fixedLeft);
|
|
|
|
|
const bodyWrapper = createBodyWrapper(vm, tbodyModel, fixedLeft, 'left');
|
2020-02-05 17:10:11 +08:00
|
|
|
vm.$fixedLeft = createContainer(vm, headerWrapper, bodyWrapper, fixedLeft, 'stb_fixed', 'left');
|
|
|
|
|
appendChild(vm.$root, vm.$fixedLeft);
|
|
|
|
|
vm.$fixedLeftBody = bodyWrapper;
|
2020-02-02 15:20:49 +08:00
|
|
|
}
|
|
|
|
|
//右边有固定列
|
|
|
|
|
if (fixedRight.thead.length > 0) {
|
|
|
|
|
rootMinWidth = rootMinWidth + fixedRight.width;
|
|
|
|
|
const headerWrapper = createHeaderWrapper(vm, theadModel, fixedRight);
|
|
|
|
|
const bodyWrapper = createBodyWrapper(vm, tbodyModel, fixedRight, 'right');
|
2020-02-05 17:10:11 +08:00
|
|
|
vm.$fixedRight = createContainer(vm, headerWrapper, bodyWrapper, fixedRight, 'stb_fixed-right', 'right');
|
|
|
|
|
appendChild(vm.$root, vm.$fixedRight);
|
|
|
|
|
vm.$fixedRightBody = bodyWrapper;
|
2020-02-02 15:20:49 +08:00
|
|
|
|
2020-02-05 17:10:11 +08:00
|
|
|
let rightPatch = createElement("div", "stb_fixed-right-patch");
|
2020-02-07 14:34:40 +08:00
|
|
|
styled(rightPatch, {
|
|
|
|
|
display: 'none',
|
|
|
|
|
width: vm.gutterWidth + "px",
|
|
|
|
|
height: offsetHeight(vm.$thead) + "px"
|
|
|
|
|
})
|
2020-02-05 17:10:11 +08:00
|
|
|
appendChild(vm.$root, rightPatch)
|
|
|
|
|
vm.$rightPatch = rightPatch;
|
2020-02-02 15:20:49 +08:00
|
|
|
if (vm.scrollY) {
|
2020-02-07 14:34:40 +08:00
|
|
|
styled(vm.$rightPatch, {
|
|
|
|
|
display: 'block'
|
|
|
|
|
})
|
2020-02-02 15:20:49 +08:00
|
|
|
}
|
|
|
|
|
}
|
2020-02-07 14:34:40 +08:00
|
|
|
styled(vm.$root, {
|
|
|
|
|
minWidth: rootMinWidth + "px"
|
|
|
|
|
})
|
2020-02-02 15:20:49 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function createHeaderWrapper(vm, model, meta) {
|
2020-02-05 17:10:11 +08:00
|
|
|
const thead = cloneNode(model, true);
|
2020-02-03 14:06:31 +08:00
|
|
|
querySelectorAll(thead, "tr:first-child>th").forEach((column, index) => {
|
2020-02-02 15:20:49 +08:00
|
|
|
if (meta.thead.indexOf("field-" + index) === -1) {
|
|
|
|
|
column.classList.add('is-hidden')
|
|
|
|
|
}
|
|
|
|
|
})
|
2020-02-05 11:12:40 +08:00
|
|
|
return createTableWrapper("stb_fixed-header-wrapper", vm, "header", thead);
|
2020-02-02 15:20:49 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function createBodyWrapper(vm, model, meta, type) {
|
2020-02-05 17:10:11 +08:00
|
|
|
const tbody = cloneNode(model, true);
|
|
|
|
|
const rows = querySelectorAll(tbody, "tr");
|
2020-02-02 15:20:49 +08:00
|
|
|
rows.forEach(row => {
|
|
|
|
|
let offsetX = -1;
|
|
|
|
|
querySelectorAll(row, "td").forEach((column, index) => {
|
|
|
|
|
if (type === 'left') {
|
|
|
|
|
offsetX = index
|
|
|
|
|
} else {
|
2020-02-06 18:51:14 +08:00
|
|
|
offsetX += getAttrNumber(column, "colspan", 1);
|
2020-02-02 15:20:49 +08:00
|
|
|
}
|
|
|
|
|
if (meta.tbody.indexOf("field-" + offsetX) === -1) {
|
|
|
|
|
column.classList.add('is-hidden')
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
})
|
2020-02-05 17:10:11 +08:00
|
|
|
const bodyWrapper = createTableWrapper("stb_fixed-body-wrapper", vm, "body", tbody);
|
2020-02-07 14:34:40 +08:00
|
|
|
styled(bodyWrapper, {
|
|
|
|
|
top: offsetHeight(vm.$thead) + "px",
|
|
|
|
|
height: (vm.size.tbodyWrapperHeight - (vm.scrollX ? vm.gutterWidth : 0)) + "px"
|
|
|
|
|
})
|
2020-02-02 15:20:49 +08:00
|
|
|
return bodyWrapper
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function createContainer(vm, thead, tbody, meta, className, type) {
|
2020-02-05 17:10:11 +08:00
|
|
|
const fixedContainer = createElement("div", className);
|
2020-02-02 15:20:49 +08:00
|
|
|
appendChildren(fixedContainer, [thead, tbody]);
|
2020-02-07 14:34:40 +08:00
|
|
|
const clientHeight = (offsetHeight(vm.$root) - (vm.scrollX ? vm.gutterWidth : 2));
|
|
|
|
|
const tableHeight = offsetHeight(vm.$thead) + offsetHeight(vm.$tbody);
|
|
|
|
|
styled(fixedContainer, {
|
|
|
|
|
width: meta.width + "px",
|
|
|
|
|
height: (tableHeight > clientHeight ? clientHeight : tableHeight) + "px",
|
|
|
|
|
right: type === 'right' ? ((vm.scrollY ? vm.gutterWidth : 0) + "px") : ''
|
|
|
|
|
})
|
2020-02-02 15:20:49 +08:00
|
|
|
return fixedContainer
|
|
|
|
|
}
|