Compare commits
10 Commits
5b08f4f1ee
...
e326621f44
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e326621f44 | ||
|
|
06fbfac3d8 | ||
|
|
838cd27a39 | ||
|
|
c5c0da76a3 | ||
|
|
250b404fae | ||
|
|
2f75abad78 | ||
|
|
15fb982fd6 | ||
|
|
ce247606b2 | ||
|
|
481359a57c | ||
|
|
de3c25e15c |
3
.gitignore
vendored
3
.gitignore
vendored
@@ -3,4 +3,5 @@ node_modules
|
||||
*.log
|
||||
RELEASE_NOTE*.md
|
||||
.vscode
|
||||
docs/
|
||||
docs/
|
||||
package-lock.json
|
||||
16
CHANGELOG.md
16
CHANGELOG.md
@@ -1,6 +1,20 @@
|
||||
# Changelog
|
||||
|
||||
## [1.2.1](https://github.com/peng92055/smart-table/tree/1.2.1) (2020-02-08)
|
||||
## [1.2.3](https://github.com/peng92055/smart-table/tree/1.2.3) (2020-05-06)
|
||||
|
||||
[Full Changelog](https://github.com/peng92055/smart-table/compare/1.2.2...1.2.3)
|
||||
|
||||
- 优化树形表格含有非法expand-parent
|
||||
- 优化树形表格支持自定义高度控制
|
||||
- 修复expand中多标签bug
|
||||
|
||||
## [1.2.2](https://github.com/peng92055/smart-table/tree/1.2.2) (2020-02-19)
|
||||
|
||||
[Full Changelog](https://github.com/peng92055/smart-table/compare/1.2.1...1.2.2)
|
||||
|
||||
- 增加动态开展行,支持异步请求,指定关键key
|
||||
|
||||
## [1.2.1](https://github.com/peng92055/smart-table/tree/1.2.1) (2020-02-11)
|
||||
|
||||
[Full Changelog](https://github.com/peng92055/smart-table/compare/1.2.0...1.2.1)
|
||||
|
||||
|
||||
17
README.md
17
README.md
@@ -1,6 +1,7 @@
|
||||
# Smart Table 组件
|
||||

|
||||

|
||||

|
||||

|
||||
|
||||
**专处理纯静态table固定头列及排序功能**
|
||||
@@ -24,6 +25,7 @@
|
||||
- 树形结构
|
||||
- 单选
|
||||
- 多选
|
||||
- 开展动态行
|
||||
|
||||
## 体验
|
||||
可直接访问https://peng92055.github.io/smart-table
|
||||
@@ -68,8 +70,18 @@
|
||||
height: 300,
|
||||
align: 'left',
|
||||
size: 'middle',
|
||||
selection: 'checkbox',
|
||||
selectionKey: 1,
|
||||
expandCallback: function(slot, value) {
|
||||
//模拟异步 可直接写同步代码
|
||||
setTimeout(function() {
|
||||
var content = "<span>我是展开内容第一次,当前展开的值为:" + value + "</span>"
|
||||
slot.open(content, true) //第二个参数为是否需要parseDom 当传递的content为字符串时,该值必须传递true
|
||||
|
||||
var content2 = document.createElement("span")
|
||||
content2.innerText = "我是展开内容第二次,当前展开的值为:" + value
|
||||
slot.open(content2)
|
||||
})
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
@@ -99,8 +111,9 @@
|
||||
| expand | boolean | no | 是否开启树形结构(树形结构会忽略排序及固定列) | false |
|
||||
| defaultExpandAll | boolean | no | 是否默认展开所有树形结构 | false |
|
||||
| selection | string | no | 单选或多选(radio、checkbox),选中值会存储在根节点selected属性上 | false |
|
||||
| selectionKey | string or number | no | 单选或多选时选中取值对应的tbody中有效列的角标(角标从0开始) | 0 |
|
||||
| selectionKey | string or number | no | 单选、多选或展开时选中取值对应的tbody中有效列的角标(角标从0开始) | 0 |
|
||||
| radioBgColor | string | no | 单选时,body中选中行的背景色 | '#D1E7FF' |
|
||||
| expandCallback | function | no | 动态展开行回调函数,回传slot及value参数 | |
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ module.exports = merge(common, {
|
||||
inject: 'head'
|
||||
})
|
||||
],
|
||||
devtool: 'inline-source-map',
|
||||
devtool: 'cheap-module-eval-source-map',
|
||||
devServer: {
|
||||
contentBase: './examples'
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ module.exports = merge(common, {
|
||||
}
|
||||
}],
|
||||
},
|
||||
devtool: 'cheap-module-source-map',
|
||||
plugins: [
|
||||
new CleanWebpackPlugin(),
|
||||
new webpack.BannerPlugin(`smartTable v${pkg.version} | (c) pengyajun 2020 | Released under the MIT License.`),
|
||||
|
||||
@@ -21,6 +21,7 @@ module.exports = merge(common, {
|
||||
}
|
||||
}],
|
||||
},
|
||||
devtool: 'cheap-module-source-map',
|
||||
plugins: [
|
||||
new CleanWebpackPlugin(),
|
||||
new webpack.BannerPlugin(`smartTable v${pkg.version} | (c) pengyajun 2020 | Released under the MIT License.`)
|
||||
|
||||
3
dist/smartTable.min.js
vendored
3
dist/smartTable.min.js
vendored
File diff suppressed because one or more lines are too long
1
dist/smartTable.min.js.map
vendored
Normal file
1
dist/smartTable.min.js.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"smartTable.min.js","sources":["webpack:///smartTable.min.js"],"mappings":"AACA","sourceRoot":""}
|
||||
@@ -82,6 +82,7 @@
|
||||
<p> <a href="#smartTable2">• 固定列</a></p>
|
||||
<p> <a href="#smartTable2">• 多选</a></p>
|
||||
<p> <a href="#smartTable3">• 树形表</a></p>
|
||||
<p> <a href="#smartTable4">• 展开动态行</a></p>
|
||||
</div>
|
||||
<div class="container">
|
||||
<div id="smartTable1">
|
||||
@@ -368,6 +369,99 @@
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div id="smartTable4">
|
||||
<table stripe>
|
||||
<thead>
|
||||
<tr>
|
||||
<th colspan="1" fixed sort>Id</th>
|
||||
<th colspan="1" fixed sort>Logo</th>
|
||||
<th colspan="1" width="200" fixed>日期</th>
|
||||
<th colspan="1" width="100" sort>姓名</th>
|
||||
<th colspan="1">省份(包含自治区)</th>
|
||||
<th colspan="1" sort>市区</th>
|
||||
<th colspan="1">地址</th>
|
||||
<th colspan="1" width="95" fixed>邮编</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>10</td>
|
||||
<td><img src="./assets/js-table.png" /></td>
|
||||
<td>2020-01-03</td>
|
||||
<td>1王小虎</td>
|
||||
<td>1上海</td>
|
||||
<td>2长宁区</td>
|
||||
<td>3上海市长宁区淞虹路888号</td>
|
||||
<td>200331</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>13</td>
|
||||
<td><img src="./assets/js-table.png" /></td>
|
||||
<td>2020-02-03</td>
|
||||
<td>2王小虎</td>
|
||||
<td>3上海</td>
|
||||
<td>4长宁区</td>
|
||||
<td>2上海市长宁区淞虹路888号</td>
|
||||
<td>200331</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>14</td>
|
||||
<td><img src="./assets/js-table.png" /></td>
|
||||
<td>2020-03-03</td>
|
||||
<td>3王小虎</td>
|
||||
<td>4上海</td>
|
||||
<td>1长宁区</td>
|
||||
<td>6上海市长宁区淞虹路888号</td>
|
||||
<td>200331</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>15</td>
|
||||
<td><img src="./assets/js-table.png" /></td>
|
||||
<td>2020-02-03</td>
|
||||
<td>2王小虎</td>
|
||||
<td>3上海</td>
|
||||
<td>4长宁区</td>
|
||||
<td>2上海市长宁区淞虹路888号</td>
|
||||
<td>200331</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>14</td>
|
||||
<td><img src="./assets/js-table.png" /></td>
|
||||
<td>2020-03-03</td>
|
||||
<td>3王小虎</td>
|
||||
<td>4上海</td>
|
||||
<td>1长宁区</td>
|
||||
<td>6上海市长宁区淞虹路888号</td>
|
||||
<td>200331</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>13</td>
|
||||
<td><img src="./assets/js-table.png" /></td>
|
||||
<td>2020-02-03</td>
|
||||
<td>2王小虎</td>
|
||||
<td>3上海</td>
|
||||
<td>4长宁区</td>
|
||||
<td>2上海市长宁区淞虹路888号</td>
|
||||
<td>200331</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>14</td>
|
||||
<td><img src="./assets/js-table.png" /></td>
|
||||
<td>2020-03-03</td>
|
||||
<td>3王小虎</td>
|
||||
<td>4上海</td>
|
||||
<td>1长宁区</td>
|
||||
<td>6上海市长宁区淞虹路888号</td>
|
||||
<td>200331</td>
|
||||
</tr>
|
||||
<tr unsort>
|
||||
<td colspan="6">合计</td>
|
||||
<td>6上海市长宁区淞虹路888号</td>
|
||||
<td>200331</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
@@ -391,6 +485,20 @@
|
||||
expand: true,
|
||||
defaultExpandAll: true
|
||||
})
|
||||
new SmartTable({
|
||||
selector: '#smartTable4',
|
||||
height: 320,
|
||||
expandCallback: function(slot, value) {
|
||||
setTimeout(function() {
|
||||
var content = "<span>我是展开内容第一次,当前展开的值为:" + value + "</span>"
|
||||
slot.open(content, true)
|
||||
|
||||
var content2 = document.createElement("span")
|
||||
content2.innerText = "我是展开内容第二次,当前展开的值为:" + value
|
||||
slot.open(content2)
|
||||
}, 2000)
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
</body>
|
||||
|
||||
239
lib/core/core.js
239
lib/core/core.js
@@ -21,6 +21,7 @@ import {
|
||||
debounce,
|
||||
getAttrNumber,
|
||||
createCheckbox,
|
||||
createExpandTrigger,
|
||||
refactorCell,
|
||||
replaceColGroup,
|
||||
createTableWrapper,
|
||||
@@ -29,7 +30,7 @@ import {
|
||||
import scrollBarWidth from './scrollbar-width';
|
||||
|
||||
export default function initMixin(Table) {
|
||||
Table.prototype._init = function(options = {}) {
|
||||
Table.prototype._init = function (options = {}) {
|
||||
if (!options.selector) {
|
||||
return console.error("Smart Table init need a selector")
|
||||
}
|
||||
@@ -49,14 +50,18 @@ export default function initMixin(Table) {
|
||||
hasAttribute(table, "stripe") && tbody.classList.add("stripe")
|
||||
|
||||
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")
|
||||
}))
|
||||
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")
|
||||
}))
|
||||
|
||||
!!options.expandCallback && (querySelectorAll(thead, 'th[fixed]').forEach(column => {
|
||||
removeAttribute(column, "fixed")
|
||||
}))
|
||||
|
||||
const vm = this;
|
||||
vm.$root = root
|
||||
@@ -70,6 +75,9 @@ export default function initMixin(Table) {
|
||||
}
|
||||
vm.size = {}
|
||||
vm.hasCheckbox = !options.expand && options.selection === 'checkbox'
|
||||
vm.hasExpandCb = !!options.expandCallback
|
||||
|
||||
vm.hasExpandCb && appendExpandTrigger(vm)
|
||||
|
||||
vm.hasCheckbox && appendCheckbox(vm)
|
||||
|
||||
@@ -89,25 +97,48 @@ export default function initMixin(Table) {
|
||||
bindEvents(vm)
|
||||
|
||||
const th = createElement("th");
|
||||
styled(th, { display: 'none' })
|
||||
styled(th, {
|
||||
display: 'none'
|
||||
})
|
||||
setAttribute(th, "width", vm.gutterWidth);
|
||||
setAttribute(th, "rowspan", vm.props.shapes.length);
|
||||
appendChild(querySelector(vm.$thead, "tr"), th);
|
||||
vm.$scrollTH = th;
|
||||
if (vm.scrollY) {
|
||||
styled(vm.$scrollTH, { display: 'table-cell' })
|
||||
styled(vm.$scrollTH, {
|
||||
display: 'table-cell'
|
||||
})
|
||||
resize(vm)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function appendCheckbox(vm) {
|
||||
const { $thead, $tbody } = vm;
|
||||
function appendExpandTrigger(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)
|
||||
let cell = createExpandTrigger("th", getAttrNumber(th, "rowspan", 1));
|
||||
hasAttribute(th, "fixed") && setAttribute(cell, "fixed")
|
||||
insertBefore(theadRow, cell, th)
|
||||
querySelectorAll($tbody, "tr").forEach(row => {
|
||||
let td = row.querySelector("td")
|
||||
insertBefore(row, createExpandTrigger("td", getAttrNumber(td, "rowspan", 1)), td)
|
||||
})
|
||||
}
|
||||
|
||||
function appendCheckbox(vm) {
|
||||
const {
|
||||
$thead,
|
||||
$tbody
|
||||
} = vm;
|
||||
let theadRow = querySelector($thead, "tr");
|
||||
let th = theadRow.querySelector("th");
|
||||
let cell = createCheckbox("th", getAttrNumber(th, "rowspan", 1));
|
||||
hasAttribute(th, "fixed") && setAttribute(cell, "fixed")
|
||||
insertBefore(theadRow, cell, th)
|
||||
querySelectorAll($tbody, "tr").forEach(row => {
|
||||
let td = row.querySelector("td")
|
||||
insertBefore(row, createCheckbox("td", getAttrNumber(td, "rowspan", 1)), td)
|
||||
@@ -115,8 +146,15 @@ function appendCheckbox(vm) {
|
||||
}
|
||||
|
||||
function layout(vm, table) {
|
||||
const { $root, $thead, $tbody, options } = vm;
|
||||
const { height } = options;
|
||||
const {
|
||||
$root,
|
||||
$thead,
|
||||
$tbody,
|
||||
options
|
||||
} = vm;
|
||||
const {
|
||||
height
|
||||
} = options;
|
||||
|
||||
querySelectorAll($thead, "th").forEach(cell => refactorCell(cell))
|
||||
querySelectorAll($tbody, "td").forEach(cell => refactorCell(cell))
|
||||
@@ -132,7 +170,10 @@ function layout(vm, table) {
|
||||
const theadHeight = offsetHeight($thead);
|
||||
const custHeight = (typeof height === 'function' ? height.call() : height) || offsetHeight($root);
|
||||
const tbodyWrapperHeight = custHeight > theadHeight ? (custHeight - theadHeight - 1) : (theadHeight + 150)
|
||||
styled(vm.$tbodyWrapper, { height: tbodyWrapperHeight + "px" })
|
||||
styled(vm.$tbodyWrapper, {
|
||||
height: tbodyWrapperHeight + "px"
|
||||
})
|
||||
|
||||
|
||||
vm.size.tbodyWrapperHeight = tbodyWrapperHeight;
|
||||
|
||||
@@ -144,7 +185,10 @@ function layout(vm, table) {
|
||||
|
||||
//根据表格中的tbody第一行 查出每列的宽度并记录
|
||||
function initColgroupData(vm) {
|
||||
const { $root, props } = vm;
|
||||
const {
|
||||
$root,
|
||||
props
|
||||
} = vm;
|
||||
const rootWidth = offsetWidth($root) - 1;
|
||||
const clientWidth = rootWidth - (vm.scrollY ? vm.gutterWidth : 0);
|
||||
let arr = [];
|
||||
@@ -171,8 +215,8 @@ function initColgroupData(vm) {
|
||||
totalWidth = 0;
|
||||
arr = arr.map((item, index) => {
|
||||
if (item === 0) {
|
||||
if (vm.hasCheckbox && index === 0) {
|
||||
item = per > 55 ? per : 55;
|
||||
if ((vm.hasCheckbox || vm.hasExpandCb) && index === 0) {
|
||||
item = 55;
|
||||
} else {
|
||||
item = min;
|
||||
}
|
||||
@@ -203,13 +247,16 @@ function bindResizeEvents(vm) {
|
||||
function bindEvents(vm) {
|
||||
bindScrollEvents(vm);
|
||||
bindRowEvents(vm);
|
||||
vm.options.expand ? bindExpandEvents(vm) : bindSortEvents(vm);
|
||||
vm.options.expand ? bindExpandTreeEvents(vm) : bindSortEvents(vm);
|
||||
bindResizeEvents(vm);
|
||||
}
|
||||
|
||||
function resize(vm) {
|
||||
debounce(500, () => {
|
||||
const { fixedLeft, fixedRight } = vm.props;
|
||||
const {
|
||||
fixedLeft,
|
||||
fixedRight
|
||||
} = vm.props;
|
||||
initColgroupData(vm)
|
||||
replaceColGroup(vm)
|
||||
|
||||
@@ -272,7 +319,7 @@ function syncPostion(vm) {
|
||||
})()
|
||||
}
|
||||
|
||||
function bindExpandEvents(vm) {
|
||||
function bindExpandTreeEvents(vm) {
|
||||
function seek(arr) {
|
||||
arr.forEach(item => {
|
||||
if (item.expand) {
|
||||
@@ -286,7 +333,9 @@ function bindExpandEvents(vm) {
|
||||
function expanding(item, expanded) {
|
||||
expanded ? setAttribute(item.$el, "expanded") : removeAttribute(item.$el, "expanded");
|
||||
item.children && (item.children.forEach(child => {
|
||||
styled(child.$el, { display: expanded ? '' : 'none' })
|
||||
styled(child.$el, {
|
||||
display: expanded ? '' : 'none'
|
||||
})
|
||||
expanding(child, expanded)
|
||||
}))
|
||||
}
|
||||
@@ -301,14 +350,19 @@ function bindScrollEvents(vm) {
|
||||
}
|
||||
|
||||
function bindRowEvents(vm) {
|
||||
const { selection, selectionKey } = vm.options;
|
||||
let {
|
||||
selection,
|
||||
selectionKey
|
||||
} = vm.options;
|
||||
selectionKey = selectionKey || 0;
|
||||
vm.hasExpandCb && (selectionKey++)
|
||||
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])
|
||||
const value = row['field-' + selectionKey]
|
||||
if (selection) {
|
||||
let value = row['field-' + (selectionKey || 0)]
|
||||
switch (selection) {
|
||||
case 'radio':
|
||||
addRadioEvent(vm, row.$el, [row.$fixedLeftEl, row.$fixedRightEl], value)
|
||||
@@ -320,17 +374,55 @@ function bindRowEvents(vm) {
|
||||
break
|
||||
}
|
||||
}
|
||||
vm.hasExpandCb && addExpandTriggerEvent(vm, row.$fixedLeftEl || row.$el, row.$key, value)
|
||||
})
|
||||
if (vm.hasCheckbox) {
|
||||
addTotalCheckboxEvent(vm, totalCheckbox)
|
||||
}
|
||||
}
|
||||
|
||||
function addExpandTriggerEvent(vm, row, key, value) {
|
||||
const {
|
||||
options
|
||||
} = vm;
|
||||
const trigger = querySelector(row, ".expand-cell>.stb_cell")
|
||||
if (!trigger) return;
|
||||
trigger.addEventListener('click', ($event) => {
|
||||
if (trigger.hasAttribute("loading")) return;
|
||||
if (trigger.hasAttribute("open")) {
|
||||
removeAttribute(trigger, "open")
|
||||
querySelectorAll(vm.$root, "tr.expand-" + key).forEach(expandRow => {
|
||||
removeChild(expandRow.parentNode, expandRow)
|
||||
})
|
||||
} else {
|
||||
setAttribute(trigger, "loading", true)
|
||||
options.expandCallback.call(this, {
|
||||
open: function (content, needParse) {
|
||||
let cell = createElement("td")
|
||||
setAttribute(cell, "colspan", vm.colgroup.length)
|
||||
let wrapper = createElement("div", "std-dialog_content")
|
||||
needParse ? (wrapper.innerHTML = content) : (appendChild(wrapper, content))
|
||||
appendChild(cell, wrapper)
|
||||
let expandRow = createElement("tr", `std-expand-row expand-${key}`)
|
||||
appendChild(expandRow, cell)
|
||||
insertBefore(row.parentNode, expandRow, row.nextSibling)
|
||||
setAttribute(trigger, "open")
|
||||
removeAttribute(trigger, "loading")
|
||||
}
|
||||
}, value)
|
||||
}
|
||||
$event.stopPropagation();
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
function addCheckboxEvent(vm, row, totalCheckbox, value) {
|
||||
const trigger = querySelector(row, "label.std-checkbox")
|
||||
if (!trigger || !totalCheckbox) return;
|
||||
trigger.addEventListener('click', () => {
|
||||
let { selected } = vm;
|
||||
let {
|
||||
selected
|
||||
} = vm;
|
||||
selected = selected || [];
|
||||
const target = !hasAttribute(trigger, "checked");
|
||||
target ? setAttribute(trigger, 'checked', true) : removeAttribute(trigger, 'checked')
|
||||
@@ -344,14 +436,17 @@ function addCheckboxEvent(vm, row, totalCheckbox, value) {
|
||||
}
|
||||
vm.selected = selected;
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
function addTotalCheckboxEvent(vm, totalCheckbox) {
|
||||
if (!totalCheckbox) return;
|
||||
const { selectionKey } = vm.options;
|
||||
const {
|
||||
selectionKey
|
||||
} = vm.options;
|
||||
totalCheckbox.addEventListener('click', () => {
|
||||
let { selected } = vm;
|
||||
let {
|
||||
selected
|
||||
} = vm;
|
||||
selected = [];
|
||||
const target = !hasAttribute(totalCheckbox, "checked");
|
||||
target ? setAttribute(totalCheckbox, 'checked', true) : removeAttribute(totalCheckbox, 'checked');
|
||||
@@ -369,11 +464,15 @@ function addTotalCheckboxEvent(vm, totalCheckbox) {
|
||||
function addRadioEvent(vm, trigger, relates, radioValue) {
|
||||
if (!trigger) return;
|
||||
trigger.addEventListener('click', () => {
|
||||
let { selected } = vm;
|
||||
let {
|
||||
selected
|
||||
} = vm;
|
||||
let target = false;
|
||||
if (selected === radioValue && !hasAttribute(trigger, "checked")) return;
|
||||
if (selected !== radioValue) {
|
||||
querySelectorAll(vm.$root, 'tr[checked]>td').forEach(item => styled(item, { background: '' }))
|
||||
querySelectorAll(vm.$root, 'tr[checked]>td').forEach(item => styled(item, {
|
||||
background: ''
|
||||
}))
|
||||
querySelectorAll(vm.$root, 'tr[checked]').forEach(item => removeAttribute(item, "checked"))
|
||||
target = true;
|
||||
} else {
|
||||
@@ -384,13 +483,17 @@ function addRadioEvent(vm, trigger, relates, radioValue) {
|
||||
selected = target ? radioValue : null;
|
||||
target ? setAttribute(trigger, "checked", true) : removeAttribute(trigger, "checked");
|
||||
trigger.querySelectorAll("td").forEach(column => {
|
||||
styled(column, { background: target ? vm.style.radioBgColor : '' })
|
||||
styled(column, {
|
||||
background: target ? vm.style.radioBgColor : ''
|
||||
})
|
||||
})
|
||||
relates.forEach(item => {
|
||||
if (item) {
|
||||
target ? setAttribute(item, "checked", true) : removeAttribute(item, "checked")
|
||||
item.querySelectorAll("td").forEach(column => {
|
||||
styled(column, { background: target ? vm.style.radioBgColor : '' })
|
||||
styled(column, {
|
||||
background: target ? vm.style.radioBgColor : ''
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
@@ -402,15 +505,23 @@ function addRadioEvent(vm, trigger, relates, radioValue) {
|
||||
function addHoverEvent(vm, trigger, relates) {
|
||||
if (!trigger) return;
|
||||
trigger.addEventListener('mouseenter', () => {
|
||||
styled(trigger, { background: vm.style.hoverBgColor })
|
||||
styled(trigger, {
|
||||
background: vm.style.hoverBgColor
|
||||
})
|
||||
relates.forEach(el => {
|
||||
el && styled(el, { background: vm.style.hoverBgColor })
|
||||
el && styled(el, {
|
||||
background: vm.style.hoverBgColor
|
||||
})
|
||||
})
|
||||
})
|
||||
trigger.addEventListener('mouseleave', () => {
|
||||
styled(trigger, { background: '' })
|
||||
styled(trigger, {
|
||||
background: ''
|
||||
})
|
||||
relates.forEach(el => {
|
||||
el && styled(el, { background: '' })
|
||||
el && styled(el, {
|
||||
background: ''
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
@@ -437,6 +548,15 @@ function bindSortEvents(vm) {
|
||||
}
|
||||
return item
|
||||
})
|
||||
querySelectorAll(vm.$root, "tr.std-expand-row").forEach(row => {
|
||||
removeChild(row.parentNode, row)
|
||||
})
|
||||
querySelectorAll(vm.$root, ".expand-cell>.stb_cell[open]").forEach(el => {
|
||||
removeAttribute(el, "open")
|
||||
})
|
||||
querySelectorAll(vm.$root, ".expand-cell>.stb_cell[loading]").forEach(el => {
|
||||
removeAttribute(el, "loading")
|
||||
})
|
||||
sort(vm, getAttribute(el, "sortkey"), sortType, sortOrder)
|
||||
})
|
||||
})
|
||||
@@ -548,21 +668,28 @@ function initExpand(vm, tbody) {
|
||||
const expandAll = vm.options.defaultExpandAll;
|
||||
let data = [];
|
||||
let parents = [];
|
||||
let parentIds = [];
|
||||
querySelectorAll(tbody, "tr").forEach(row => {
|
||||
let paddingLength = parents.length;
|
||||
let expand = hasAttribute(row, "expand");
|
||||
let hasParent = hasAttribute(row, "expand-parent");
|
||||
let node = { $el: row, id: getAttribute(row, "expand"), expand: expand };
|
||||
if (expand) {
|
||||
if (expandAll) {
|
||||
setAttribute(row, 'expanded')
|
||||
} else {
|
||||
removeAttribute(row, 'expanded')
|
||||
}
|
||||
let expandParentId = getAttribute(row, "expand-parent");
|
||||
if (parentIds.indexOf(expandParentId) === -1) {
|
||||
hasParent = false;
|
||||
}
|
||||
let node = {
|
||||
$el: row,
|
||||
id: getAttribute(row, "expand"),
|
||||
expand: expand
|
||||
};
|
||||
if (expand) {
|
||||
expandAll ? setAttribute(row, 'expanded') : removeAttribute(row, 'expanded');
|
||||
}
|
||||
|
||||
if (expand && !hasParent) {
|
||||
node.children = [];
|
||||
parents = [node];
|
||||
parentIds.push(node.id)
|
||||
data.push(node);
|
||||
} else if (hasParent) {
|
||||
let parentId = getAttribute(row, "expand-parent");
|
||||
@@ -579,18 +706,28 @@ function initExpand(vm, tbody) {
|
||||
parent && parent.children.push(node);
|
||||
if (expand) {
|
||||
parents.push(node)
|
||||
parentIds.push(node.id)
|
||||
node.children = [];
|
||||
}
|
||||
} else {
|
||||
data.push(node)
|
||||
}
|
||||
if (hasParent) {
|
||||
styled(querySelector(row, "td"), { paddingLeft: 32 * paddingLength + "px" })
|
||||
styled(row, { display: expandAll ? '' : 'none' })
|
||||
styled(querySelector(row, "td"), {
|
||||
paddingLeft: 32 * paddingLength + "px"
|
||||
})
|
||||
styled(row, {
|
||||
display: expandAll ? '' : 'none'
|
||||
})
|
||||
}
|
||||
})
|
||||
vm.expandData = data;
|
||||
styled(vm.$tbodyWrapper, { height: '' })
|
||||
styled(vm.$tbodyWrapper, {
|
||||
height: ''
|
||||
})
|
||||
styled(vm.$tbodyWrapper, {
|
||||
maxHeight: vm.size.tbodyWrapperHeight + 'px'
|
||||
})
|
||||
}
|
||||
|
||||
function initData(vm, tbody) {
|
||||
@@ -603,7 +740,7 @@ function initData(vm, tbody) {
|
||||
$el: row,
|
||||
$fixedLeftEl: fixedLeftRows && fixedLeftRows[index],
|
||||
$fixedRightEl: fixedRightRows && fixedRightRows[index],
|
||||
$key: '$$rowkey' + index
|
||||
$key: 'rowkey' + index
|
||||
};
|
||||
querySelectorAll(row, "td .stb_cell").forEach((cell, index) => {
|
||||
rowData["field-" + index] = cell.innerHTML;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import {
|
||||
appendChild,
|
||||
removeChild,
|
||||
setAttribute,
|
||||
getAttribute,
|
||||
createElement,
|
||||
@@ -20,14 +21,23 @@ export function refactorCell(cell) {
|
||||
|
||||
export function createCheckbox(parentTag, rowspan) {
|
||||
if (!parentTag) return;
|
||||
let td = createElement(parentTag)
|
||||
setAttribute(td, "rowspan", rowspan)
|
||||
let cell = createElement(parentTag)
|
||||
setAttribute(cell, "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
|
||||
appendChild(cell, wrapper)
|
||||
return cell
|
||||
}
|
||||
|
||||
export function createExpandTrigger(parentTag, rowspan) {
|
||||
if (!parentTag) return;
|
||||
let cell = createElement(parentTag, parentTag === "td" ? "expand-cell" : "")
|
||||
setAttribute(cell, "rowspan", rowspan)
|
||||
let trigger = createElement("span", parentTag === "td" ? "expand-trigger" : "")
|
||||
appendChild(cell, trigger)
|
||||
return cell
|
||||
}
|
||||
|
||||
export function createTableWrapper(className, vm, type, content) {
|
||||
|
||||
144
lib/index.scss
144
lib/index.scss
@@ -9,6 +9,7 @@
|
||||
border: 1px solid #ECF0F5;
|
||||
border-right: none;
|
||||
border-bottom: none;
|
||||
|
||||
&:after,
|
||||
&:before {
|
||||
content: "";
|
||||
@@ -16,35 +17,43 @@
|
||||
background-color: #ECF0F5;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
&:before {
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
height: 1px;
|
||||
}
|
||||
|
||||
&:after {
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 1px;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
table {
|
||||
border-spacing: 0;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
thead {
|
||||
background: #F5F7FB;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
tr {
|
||||
transition: background-color .25s ease;
|
||||
}
|
||||
|
||||
tbody {
|
||||
font-size: 12px;
|
||||
|
||||
tr[expand] {
|
||||
td:first-child {
|
||||
cursor: pointer;
|
||||
:before {
|
||||
|
||||
&:before {
|
||||
transition: 0.35s ease transform;
|
||||
transform-origin: 25% 50%;
|
||||
content: '';
|
||||
@@ -57,16 +66,58 @@
|
||||
margin: 5px 0 0 5px;
|
||||
}
|
||||
}
|
||||
&[expanded]>td:first-child>:before {
|
||||
transform: rotate(90deg);
|
||||
|
||||
&[expanded]>td:first-child {
|
||||
&:before {
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.expand-trigger {
|
||||
display: inline-block;
|
||||
transition: 0.35s ease transform;
|
||||
transform-origin: 25% 50%;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-width: 6px;
|
||||
border-style: solid;
|
||||
border-color: transparent transparent transparent #c0c4cc;
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
.expand-cell>.stb_cell {
|
||||
cursor: pointer;
|
||||
|
||||
&[open] {
|
||||
.expand-trigger {
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
}
|
||||
|
||||
&[loading] {
|
||||
.expand-trigger {
|
||||
margin-left: 0;
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
border-color: none;
|
||||
transform-origin: center;
|
||||
border: .2em solid transparent;
|
||||
border-left-color: currentcolor;
|
||||
border-right-color: currentcolor;
|
||||
border-radius: 50%;
|
||||
animation: 1s loading linear infinite;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.stripe {
|
||||
tr:nth-child(2n) {
|
||||
background-color: #F9FBFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
td,
|
||||
th {
|
||||
padding: 5px 0;
|
||||
@@ -76,17 +127,21 @@
|
||||
border-bottom: 1px solid #ECF0F5;
|
||||
border-right: 1px solid #ECF0F5;
|
||||
text-align: center;
|
||||
|
||||
&.is-hidden>* {
|
||||
visibility: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
th {
|
||||
user-select: none;
|
||||
overflow: hidden;
|
||||
&[sort] {
|
||||
|
||||
&[sort]>.stb_cell {
|
||||
cursor: pointer;
|
||||
:before,
|
||||
:after {
|
||||
|
||||
&:before,
|
||||
&:after {
|
||||
content: '';
|
||||
float: right;
|
||||
width: 0;
|
||||
@@ -94,80 +149,99 @@
|
||||
border-width: 5px;
|
||||
border-style: solid;
|
||||
}
|
||||
:before {
|
||||
|
||||
&:before {
|
||||
margin: 1px 0 0 -10px;
|
||||
border-color: transparent transparent #c0c4cc transparent;
|
||||
}
|
||||
:after {
|
||||
|
||||
&:after {
|
||||
margin: 12px 0 0 4px;
|
||||
border-color: #c0c4cc transparent transparent transparent;
|
||||
}
|
||||
|
||||
&.desc {
|
||||
:after {
|
||||
&:after {
|
||||
border-top-color: #409eff;
|
||||
}
|
||||
}
|
||||
|
||||
&.asc {
|
||||
:before {
|
||||
&:before {
|
||||
border-bottom-color: #409eff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.stb-cust-large {
|
||||
thead {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
tbody {
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
td,
|
||||
th {
|
||||
padding: 12px 0;
|
||||
}
|
||||
}
|
||||
|
||||
&.stb-cust-middle {
|
||||
thead {
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
tbody {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
td,
|
||||
th {
|
||||
padding: 10px 0;
|
||||
}
|
||||
}
|
||||
|
||||
&.stb-cust-left {
|
||||
|
||||
td,
|
||||
th {
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
|
||||
&.stb-cust-right {
|
||||
|
||||
td,
|
||||
th {
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
|
||||
th[align="left"],
|
||||
td[align="left"] {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
th[align="center"],
|
||||
td[align="center"] {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
th[align="right"],
|
||||
td[align="right"] {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
th[nowrap],
|
||||
td[nowrap] {
|
||||
.stb_cell {
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
.std-checkbox_inner {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
@@ -179,6 +253,7 @@
|
||||
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: "";
|
||||
@@ -195,6 +270,7 @@
|
||||
transform-origin: center;
|
||||
}
|
||||
}
|
||||
|
||||
.std-checkbox_input {
|
||||
white-space: nowrap;
|
||||
cursor: pointer;
|
||||
@@ -204,6 +280,7 @@
|
||||
position: relative;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.std-checkbox {
|
||||
color: #606266;
|
||||
font-weight: 500;
|
||||
@@ -213,14 +290,17 @@
|
||||
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;
|
||||
@@ -229,11 +309,13 @@
|
||||
padding: 0 4px;
|
||||
line-height: 23px;
|
||||
}
|
||||
|
||||
th>.stb_cell {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.stb_body,
|
||||
.stb_footer,
|
||||
.stb_header {
|
||||
@@ -241,12 +323,15 @@
|
||||
border-collapse: separate;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.stb_header-wrapper {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.stb_body-wrapper {
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.stb_fixed,
|
||||
.stb_fixed-right {
|
||||
position: absolute;
|
||||
@@ -256,11 +341,13 @@
|
||||
overflow-y: hidden;
|
||||
box-shadow: 0 -1px 8px rgba(0, 0, 0, .08);
|
||||
}
|
||||
|
||||
.stb_fixed-right {
|
||||
top: 0;
|
||||
left: auto;
|
||||
right: 0;
|
||||
box-shadow: -1px 0 8px rgba(0, 0, 0, .08);
|
||||
|
||||
.stb_fixed-body-wrapper,
|
||||
.stb_fixed-footer-wrapper,
|
||||
.stb_fixed-header-wrapper {
|
||||
@@ -268,18 +355,21 @@
|
||||
right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.stb_fixed-right-patch {
|
||||
position: absolute;
|
||||
top: -1px;
|
||||
right: 0;
|
||||
background-color: #F5F7FB;
|
||||
}
|
||||
|
||||
.stb_fixed-header-wrapper {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
z-index: 3;
|
||||
}
|
||||
|
||||
.stb_fixed-body-wrapper {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
@@ -287,19 +377,47 @@
|
||||
overflow: hidden;
|
||||
z-index: 3;
|
||||
}
|
||||
::-webkit-scrollbar {
|
||||
|
||||
::-webkit-scrollbar {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
background-color: #e9edf4;
|
||||
}
|
||||
::-webkit-scrollbar-thumb {
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
background-color: #ccc;
|
||||
border-radius: 2em;
|
||||
}
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background-color: #919191;
|
||||
}
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
@-webkit-keyframes loading {
|
||||
0% {
|
||||
-webkit-transform: rotate(0deg);
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
100% {
|
||||
-webkit-transform: rotate(360deg);
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes loading {
|
||||
0% {
|
||||
-webkit-transform: rotate(0deg);
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
100% {
|
||||
-webkit-transform: rotate(360deg);
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
8922
package-lock.json
generated
8922
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "smart-table",
|
||||
"version": "1.2.1",
|
||||
"version": "1.2.3",
|
||||
"description": "smart table for static html",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
|
||||
Reference in New Issue
Block a user