- 增加多选功能

This commit is contained in:
Julyp
2020-02-07 21:13:37 +08:00
parent 5753d10f03
commit 5ac634ea05
5 changed files with 153 additions and 11 deletions

View File

@@ -370,13 +370,14 @@
new SmartTable({
selector: '#smartTable1',
height: 320,
selection: 'radio',
selection: 'radio'
})
new SmartTable({
selector: '#smartTable2',
align: 'left',
height: 320,
size: 'middle',
align: 'center',
selection: 'checkbox',
selectionKey: 1,
})

View File

@@ -9,6 +9,7 @@ import {
removeChild,
createElement,
querySelector,
insertBefore,
querySelectorAll,
offsetHeight,
offsetWidth,
@@ -19,6 +20,7 @@ import {
throttle,
debounce,
getAttrNumber,
createCheckbox,
refactorCell,
replaceColGroup,
createTableWrapper,
@@ -67,6 +69,9 @@ export default function initMixin(Table) {
hoverBgColor: options.hoverBgColor || '#EFF8FF'
}
vm.size = {}
vm.hasCheckbox = !options.expand && options.selection === 'checkbox'
vm.hasCheckbox && appendCheckbox(vm)
//初始化thead 并获取props
initProps(vm)
@@ -96,9 +101,23 @@ export default function initMixin(Table) {
}
}
function appendCheckbox(vm) {
const { $thead, $tbody } = vm;
let theadRow = querySelector($thead, "tr");
let th = theadRow.querySelector("th");
let selectionTh = createCheckbox("th", getAttrNumber(th, "rowspan", 1));
hasAttribute(th, "fixed") && setAttribute(selectionTh, "fixed")
insertBefore(theadRow, selectionTh, th)
querySelectorAll($tbody, "tr").forEach(row => {
let td = row.querySelector("td")
insertBefore(row, createCheckbox("td", getAttrNumber(td, "rowspan", 1)), td)
})
}
function layout(vm, table) {
const { $root, $thead, $tbody, options } = vm;
const { height, selection } = options;
const { height } = options;
querySelectorAll($thead, "th").forEach(cell => refactorCell(cell))
querySelectorAll($tbody, "td").forEach(cell => refactorCell(cell))
@@ -152,7 +171,11 @@ function initColgroupData(vm) {
totalWidth = 0;
arr = arr.map((item, index) => {
if (item === 0) {
if (vm.hasCheckbox && index === 0) {
item = per > 55 ? per : 55;
} else {
item = min;
}
lastZeroIndex = index;
}
totalWidth += item
@@ -279,16 +302,67 @@ function bindScrollEvents(vm) {
function bindRowEvents(vm) {
const { selection, selectionKey } = vm.options;
const totalCheckbox = querySelector(vm.$fixedLeft || vm.$thead, "th>.stb_cell>label.std-checkbox");
[].concat(vm.data, vm.unsortData).forEach(row => {
addHoverEvent(vm, row.$el, [row.$fixedLeftEl, row.$fixedRightEl])
row.$fixedLeftEl && addHoverEvent(vm, row.$fixedLeftEl, [row.$el, row.$fixedRightEl])
row.$fixedRightEl && addHoverEvent(vm, row.$fixedRightEl, [row.$el, row.$fixedLeftEl])
if (selection === 'radio') {
if (selection) {
let value = row['field-' + (selectionKey || 0)]
switch (selection) {
case 'radio':
addRadioEvent(vm, row.$el, [row.$fixedLeftEl, row.$fixedRightEl], value)
row.$fixedLeftEl && addRadioEvent(vm, row.$fixedLeftEl, [row.$el, row.$fixedRightEl], value)
row.$fixedRightEl && addRadioEvent(vm, row.$fixedRightEl, [row.$el, row.$fixedLeftEl], value)
break
case 'checkbox':
addCheckboxEvent(vm, row.$fixedLeftEl || row.$el, totalCheckbox, value)
break
}
}
})
if (vm.hasCheckbox) {
addTotalCheckboxEvent(vm, totalCheckbox)
}
}
function addCheckboxEvent(vm, row, totalCheckbox, value) {
const trigger = querySelector(row, "label.std-checkbox")
if (!trigger || !totalCheckbox) return;
trigger.addEventListener('click', () => {
let { selected } = vm;
selected = selected || [];
const target = !hasAttribute(trigger, "checked");
target ? setAttribute(trigger, 'checked', true) : removeAttribute(trigger, 'checked')
target ? selected.push(value) : selected.splice(selected.indexOf(value), 1)
const len = selected.length;
len ? setAttribute(vm.$root, 'selected', selected) : removeAttribute(vm.$root, 'selected');
if (len === (vm.data.length + vm.unsortData.length)) {
setAttribute(totalCheckbox, 'checked', true)
} else {
removeAttribute(totalCheckbox, 'checked')
}
vm.selected = selected;
})
}
function addTotalCheckboxEvent(vm, totalCheckbox) {
if (!totalCheckbox) return;
const { selectionKey } = vm.options;
totalCheckbox.addEventListener('click', () => {
let { selected } = vm;
selected = [];
const target = !hasAttribute(totalCheckbox, "checked");
target ? setAttribute(totalCheckbox, 'checked', true) : removeAttribute(totalCheckbox, 'checked');
[].concat(vm.data, vm.unsortData).forEach(row => {
let trigger = querySelector(row.$fixedLeftEl || row.$el, "label.std-checkbox")
target ? setAttribute(trigger, 'checked', true) : removeAttribute(trigger, 'checked')
target && selected.push(row['field-' + (selectionKey || 0)])
})
const len = selected.length;
len ? setAttribute(vm.$root, 'selected', selected) : removeAttribute(vm.$root, 'selected');
vm.selected = selected;
})
}
@@ -511,7 +585,7 @@ function initExpand(vm, tbody) {
data.push(node)
}
if (hasParent) {
styled(querySelector(row, "td"), { paddingLeft: 25 * paddingLength + "px" })
styled(querySelector(row, "td"), { paddingLeft: 35 * paddingLength + "px" })
styled(row, { display: expandAll ? '' : 'none' })
}
})

View File

@@ -18,6 +18,18 @@ export function refactorCell(cell) {
appendChild(cell, wrapper)
}
export function createCheckbox(parentTag, rowspan) {
if (!parentTag) return;
let td = createElement(parentTag)
setAttribute(td, "rowspan", rowspan)
let wrapper = createElement("label", "std-checkbox");
let input = createElement("span", "std-checkbox_input");
appendChild(input, createElement("span", "std-checkbox_inner"))
appendChild(wrapper, input)
appendChild(td, wrapper)
return td
}
export function createTableWrapper(className, vm, type, content) {
let wrapper = createElement("div", className);
let table = createElement("table", "stb_" + type);

View File

@@ -1,3 +1,5 @@
import { insertBefore } from './node-ops';
export default function(vm, key, sortType, sortOrder) {
if (!vm.data || vm.data.length < 1) return;
//使用快速排序
@@ -28,16 +30,16 @@ function diff(oldVnode, vnode) {
const lastNextVNode = vnode[i - 1];
const refNode = lastNextVNode.$el.nextSibling;
refNode.parentNode.insertBefore(prevVNode.$el, refNode);
insertBefore(refNode.parentNode, prevVNode.$el, refNode);
if (lastNextVNode.$fixedLeftEl) {
const refLeftNode = lastNextVNode.$fixedLeftEl.nextSibling;
refLeftNode.parentNode.insertBefore(prevVNode.$fixedLeftEl, refLeftNode);
insertBefore(refLeftNode.parentNode, prevVNode.$fixedLeftEl, refLeftNode);
}
if (lastNextVNode.$fixedRightEl) {
const refRightNode = lastNextVNode.$fixedRightEl.nextSibling;
refRightNode.parentNode.insertBefore(prevVNode.$fixedRightEl, refRightNode);
insertBefore(refRightNode.parentNode, prevVNode.$fixedRightEl, refRightNode);
}
} else {
lastIndex = j;

View File

@@ -150,6 +150,59 @@
text-align: right;
}
}
.std-checkbox_inner {
display: inline-block;
position: relative;
border: 1px solid #dcdfe6;
border-radius: 2px;
box-sizing: border-box;
width: 14px;
height: 14px;
background-color: #fff;
z-index: 1;
transition: border-color .25s cubic-bezier(.71, -.46, .29, 1.46), background-color .25s cubic-bezier(.71, -.46, .29, 1.46);
&:after {
box-sizing: content-box;
content: "";
border: 1px solid #fff;
border-left: 0;
border-top: 0;
height: 7px;
left: 4px;
position: absolute;
top: 1px;
transform: rotate(45deg) scaleY(0);
width: 3px;
transition: transform .15s ease-in .05s;
transform-origin: center;
}
}
.std-checkbox_input {
white-space: nowrap;
cursor: pointer;
outline: none;
display: inline-block;
line-height: 1;
position: relative;
vertical-align: middle;
}
.std-checkbox {
color: #606266;
font-weight: 500;
font-size: 14px;
position: relative;
cursor: pointer;
display: inline-block;
white-space: nowrap;
user-select: none;
&[checked]>.std-checkbox_input>.std-checkbox_inner {
background-color: #409eff;
border-color: #409eff;
&:after {
transform: rotate(45deg) scaleY(1);
}
}
}
.stb_cell {
overflow: hidden;
text-overflow: ellipsis;