Skip to content
This repository was archived by the owner on Apr 1, 2022. It is now read-only.

Commit d4c699b

Browse files
author
Ken Berkeley
committed
merge vue2-datatable-plugins into this repo
1 parent 963676d commit d4c699b

File tree

3 files changed

+137
-3
lines changed

3 files changed

+137
-3
lines changed

doc/en/_sidebar.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,4 @@
1212
- [I18N](en/i18n)
1313
- [DIY](en/DIY)
1414
- [Q & A (issues)](https://github.com/OneWayTech/vue2-datatable/issues)
15-
- [Changelog (releases)](https://github.com/OneWayTech/vue2-datatable/releases)
15+
- [Custom plugins](https://github.com/OneWayTech/vue2-datatable/tree/master/plugins)

doc/zh-cn/_sidebar.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,5 @@
1111
- [动态组件](zh-cn/details/dynamic-comps)
1212
- [国际化](zh-cn/i18n)
1313
- [自定制 (DIY)](zh-cn/DIY)
14-
- [问题反馈(issues)](zh-cn/https://github.com/OneWayTech/vue2-datatable/issues)
15-
- [版本迭代(releases)](https://github.com/OneWayTech/vue2-datatable/releases)
14+
- [问题反馈(issues)](https://github.com/OneWayTech/vue2-datatable/issues)
15+
- [自定制插件](https://github.com/OneWayTech/vue2-datatable/tree/master/plugins)

plugins/HeaderSettingsDnD.js

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
/**
2+
* apply drag-and-drop sortable feature to HeaderSettings
3+
* note that this function should be invoked in `mounted`
4+
* e.g.
5+
<template>
6+
<datatable v-bind="$data">
7+
</template>
8+
<script>
9+
import dnd from 'vue2-datatable-component/plugins/HeaderSettingsDnD'
10+
11+
export default {
12+
mounted () {
13+
dnd(this) // done!
14+
},
15+
...
16+
}
17+
</script>
18+
19+
* `vm.columns` should also meet the requirement that:
20+
* the same-group columns should be put together
21+
* e.g.
22+
[ // ok
23+
{ field: 'a1', group: 'A' },
24+
{ field: 'a2', group: 'A' },
25+
{ field: 'b1', group: 'B' },
26+
{ field: 'b2', group: 'B' },
27+
{ field: 'c1', group: 'C' },
28+
{ field: 'c2', group: 'C' }
29+
]
30+
[ // not ok
31+
{ field: 'a1', group: 'A' },
32+
{ field: 'b1', group: 'B' },
33+
{ field: 'c1', group: 'C' },
34+
{ field: 'a2', group: 'A' },
35+
{ field: 'b2', group: 'B' },
36+
{ field: 'c2', group: 'C' }
37+
]
38+
39+
* @param {VueInstance} vm
40+
*/
41+
export default function dnd(vm) {
42+
const $ColGroupContainer = $(vm.$el).find('div.-col-group-container')
43+
const DRAGGABLE = 'li[draggable=true]'
44+
const DROP_ZONE = 'li.-col-drop-zone'
45+
46+
function dropZoneGen(idx) {
47+
return `<li class="-col-drop-zone" target-idx="${idx}"></li>`
48+
}
49+
/** generate adjacent drop zones for each column displayed as <li> */
50+
function generateDropZones() {
51+
$ColGroupContainer
52+
.find(DROP_ZONE).remove().end() // ensure no drop zone exists
53+
.find('li').each(function (idx) {
54+
const $this = $(this)
55+
$this
56+
.attr('draggable', 'true')
57+
.attr('source-idx', idx)
58+
.before(
59+
dropZoneGen(
60+
$this.is('li:first-of-type') ? idx - 0.25 : idx
61+
)
62+
)
63+
64+
$this.is('li:last-of-type') && $this.after(dropZoneGen(idx + 0.25))
65+
})
66+
}
67+
68+
vm.$watch('columns', () => {
69+
vm.$nextTick(generateDropZones)
70+
}, { immediate: true, deep: true })
71+
72+
/*** ↑↑↑ preparatory work --- main logic ↓↓↓ ***/
73+
74+
let draggingIdx = null
75+
76+
$.fn.isAllowedToDrop = function () {
77+
const targetIdx = +$(this).attr('target-idx')
78+
return ![-0.25, 0, 0.25, 1].includes(targetIdx - draggingIdx) // filter adjacent drop zones
79+
}
80+
81+
$ColGroupContainer
82+
.on('dragstart', DRAGGABLE, function () {
83+
draggingIdx = +$(this).addClass('-dragging').attr('source-idx')
84+
})
85+
.on('dragend', DRAGGABLE, function () {
86+
draggingIdx = null
87+
$(this).removeClass('-dragging')
88+
})
89+
.on('dragover', DROP_ZONE, function (e) {
90+
e.preventDefault() // must
91+
e.originalEvent.dataTransfer.dropEffect = $(this).isAllowedToDrop() ? 'move' : 'none'
92+
})
93+
.on('dragenter', DROP_ZONE, function () {
94+
const $this = $(this)
95+
$this.isAllowedToDrop() && $this.addClass('-droppable')
96+
})
97+
.on('drop', DROP_ZONE, function () {
98+
const $this = $(this).removeClass('-droppable')
99+
if (!$this.isAllowedToDrop()) return
100+
101+
const { columns } = vm
102+
const targetIdx = +$this.attr('target-idx')
103+
columns[draggingIdx].group = columns[Math.round(targetIdx)].group
104+
arrMove(columns, draggingIdx, Math.ceil(targetIdx))
105+
})
106+
.on('dragleave', DROP_ZONE, function () {
107+
const $this = $(this)
108+
$this.isAllowedToDrop() && $this.removeClass('-droppable')
109+
})
110+
}
111+
112+
// similar to https://github.com/sindresorhus/array-move
113+
function arrMove(arr, from, to) {
114+
arr.splice((from < to ? to - 1 : to), 0, arr.splice(from, 1)[0])
115+
}
116+
117+
$('head').append(`<style>
118+
.-col-group > [draggable],
119+
.-col-group > .-col-drop-zone {
120+
margin-bottom: 0;
121+
}
122+
.-dragging {
123+
opacity: 0.3;
124+
}
125+
.-col-drop-zone {
126+
height: 10px;
127+
transition: height .25s ease;
128+
}
129+
.-droppable {
130+
height: 30px;
131+
border: 1px dashed #ddd;
132+
border-radius: 4px;
133+
}
134+
</style>`)

0 commit comments

Comments
 (0)