diff --git a/examples/index.html b/examples/index.html
index a66ccbb..34da4d0 100644
--- a/examples/index.html
+++ b/examples/index.html
@@ -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,
})
diff --git a/lib/core/core.js b/lib/core/core.js
index 391983c..1e9b5cc 100644
--- a/lib/core/core.js
+++ b/lib/core/core.js
@@ -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) {
- item = min;
+ if (vm.hasCheckbox && index === 0) {
+ item = per > 55 ? per : 55;
+ } else {
+ item = min;
+ }
lastZeroIndex = index;
}
totalWidth += item
@@ -279,17 +302,68 @@ 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)]
- 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)
+ 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;
+ })
}
function addRadioEvent(vm, trigger, relates, radioValue) {
@@ -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' })
}
})
diff --git a/lib/core/utils.js b/lib/core/utils.js
index c3beb7f..f3f693b 100644
--- a/lib/core/utils.js
+++ b/lib/core/utils.js
@@ -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);
diff --git a/lib/core/vdom.js b/lib/core/vdom.js
index a97e33c..ce8922f 100644
--- a/lib/core/vdom.js
+++ b/lib/core/vdom.js
@@ -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;
diff --git a/lib/index.scss b/lib/index.scss
index bddd83b..e6513f5 100644
--- a/lib/index.scss
+++ b/lib/index.scss
@@ -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;