vxe-table 4.19.0-beta.2 → 4.19.0-beta.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (121) hide show
  1. package/LICENSE +20 -20
  2. package/README.en.md +118 -118
  3. package/README.ja-JP.md +117 -117
  4. package/README.md +268 -268
  5. package/README.zh-TW.md +117 -117
  6. package/es/style.css +1 -1
  7. package/es/table/render/index.js +1 -1
  8. package/es/ui/index.js +1 -1
  9. package/es/ui/src/log.js +1 -1
  10. package/lib/index.umd.js +2767 -2851
  11. package/lib/index.umd.min.js +1 -1
  12. package/lib/style.css +1 -1
  13. package/lib/table/render/index.js +1 -1
  14. package/lib/table/render/index.min.js +1 -1
  15. package/lib/ui/index.js +1 -1
  16. package/lib/ui/index.min.js +1 -1
  17. package/lib/ui/src/log.js +1 -1
  18. package/lib/ui/src/log.min.js +1 -1
  19. package/package.json +92 -92
  20. package/packages/colgroup/index.ts +22 -22
  21. package/packages/column/index.ts +22 -22
  22. package/packages/components.ts +43 -43
  23. package/packages/grid/index.ts +18 -18
  24. package/packages/grid/src/emits.ts +19 -19
  25. package/packages/grid/src/grid.ts +1768 -1768
  26. package/packages/grid/src/props.ts +23 -23
  27. package/packages/index.ts +4 -4
  28. package/packages/locale/lang/ar-EG.ts +840 -840
  29. package/packages/locale/lang/de-DE.ts +840 -840
  30. package/packages/locale/lang/en-US.ts +840 -840
  31. package/packages/locale/lang/es-ES.ts +840 -840
  32. package/packages/locale/lang/fr-FR.ts +840 -840
  33. package/packages/locale/lang/hu-HU.ts +840 -840
  34. package/packages/locale/lang/hy-AM.ts +840 -840
  35. package/packages/locale/lang/id-ID.ts +840 -840
  36. package/packages/locale/lang/it-IT.ts +840 -840
  37. package/packages/locale/lang/ja-JP.ts +840 -840
  38. package/packages/locale/lang/ko-KR.ts +840 -840
  39. package/packages/locale/lang/ms-MY.ts +840 -840
  40. package/packages/locale/lang/nb-NO.ts +840 -840
  41. package/packages/locale/lang/pt-BR.ts +840 -840
  42. package/packages/locale/lang/ru-RU.ts +840 -840
  43. package/packages/locale/lang/th-TH.ts +840 -840
  44. package/packages/locale/lang/ug-CN.ts +840 -840
  45. package/packages/locale/lang/uk-UA.ts +840 -840
  46. package/packages/locale/lang/uz-UZ.ts +840 -840
  47. package/packages/locale/lang/vi-VN.ts +840 -840
  48. package/packages/locale/lang/zh-CHT.ts +840 -840
  49. package/packages/locale/lang/zh-CN.ts +840 -840
  50. package/packages/locale/lang/zh-HK.ts +3 -3
  51. package/packages/locale/lang/zh-MO.ts +3 -3
  52. package/packages/locale/lang/zh-TC.ts +3 -3
  53. package/packages/locale/lang/zh-TW.ts +3 -3
  54. package/packages/table/index.ts +26 -26
  55. package/packages/table/module/custom/hook.ts +422 -422
  56. package/packages/table/module/custom/panel.ts +1512 -1512
  57. package/packages/table/module/edit/hook.ts +1064 -1064
  58. package/packages/table/module/export/export-panel.ts +567 -567
  59. package/packages/table/module/export/hook.ts +1654 -1654
  60. package/packages/table/module/export/import-panel.ts +266 -266
  61. package/packages/table/module/export/util.ts +24 -24
  62. package/packages/table/module/filter/hook.ts +468 -468
  63. package/packages/table/module/filter/panel.ts +301 -301
  64. package/packages/table/module/keyboard/hook.ts +494 -494
  65. package/packages/table/module/menu/hook.ts +325 -325
  66. package/packages/table/module/menu/panel.ts +201 -201
  67. package/packages/table/module/validator/hook.ts +631 -631
  68. package/packages/table/render/index.ts +1440 -1440
  69. package/packages/table/src/body.ts +935 -935
  70. package/packages/table/src/cell.ts +1290 -1290
  71. package/packages/table/src/column.ts +190 -190
  72. package/packages/table/src/columnInfo.ts +225 -225
  73. package/packages/table/src/emits.ts +125 -125
  74. package/packages/table/src/footer.ts +368 -368
  75. package/packages/table/src/group.ts +59 -59
  76. package/packages/table/src/header.ts +561 -561
  77. package/packages/table/src/props.ts +324 -324
  78. package/packages/table/src/store.ts +14 -14
  79. package/packages/table/src/table.ts +14274 -14274
  80. package/packages/table/src/use/cell-view.ts +44 -44
  81. package/packages/table/src/use/index.ts +1 -1
  82. package/packages/table/src/util.ts +1086 -1086
  83. package/packages/toolbar/index.ts +18 -18
  84. package/packages/toolbar/src/toolbar.ts +701 -701
  85. package/packages/ui/index.ts +532 -532
  86. package/packages/ui/src/anime.ts +52 -52
  87. package/packages/ui/src/comp.ts +3 -3
  88. package/packages/ui/src/dom.ts +264 -264
  89. package/packages/ui/src/log.ts +8 -8
  90. package/packages/ui/src/utils.ts +56 -56
  91. package/packages/ui/src/vn.ts +55 -55
  92. package/packages/v-x-e-table/index.d.ts +4 -4
  93. package/packages/v-x-e-table/index.ts +4 -4
  94. package/styles/all.scss +7 -7
  95. package/styles/base.scss +16 -16
  96. package/styles/components/grid.scss +89 -89
  97. package/styles/components/icon.scss +225 -225
  98. package/styles/components/old-icon.scss +715 -715
  99. package/styles/components/table-module/all.scss +6 -6
  100. package/styles/components/table-module/custom.scss +550 -550
  101. package/styles/components/table-module/export.scss +130 -130
  102. package/styles/components/table-module/filter.scss +130 -130
  103. package/styles/components/table-module/menu.scss +81 -81
  104. package/styles/components/table.scss +2679 -2679
  105. package/styles/components/toolbar.scss +119 -119
  106. package/styles/default.scss +2 -2
  107. package/styles/helpers/baseMixin.scss +95 -95
  108. package/styles/index.scss +4 -4
  109. package/styles/modules.scss +5 -5
  110. package/styles/theme/base.scss +93 -93
  111. package/styles/theme/dark.scss +49 -49
  112. package/styles/theme/light.scss +44 -44
  113. package/styles/variable.scss +43 -43
  114. package/types/all.d.ts +37 -37
  115. package/types/index.d.ts +4 -4
  116. /package/es/{iconfont.1778157083004.ttf → iconfont.1778318183872.ttf} +0 -0
  117. /package/es/{iconfont.1778157083004.woff → iconfont.1778318183872.woff} +0 -0
  118. /package/es/{iconfont.1778157083004.woff2 → iconfont.1778318183872.woff2} +0 -0
  119. /package/lib/{iconfont.1778157083004.ttf → iconfont.1778318183872.ttf} +0 -0
  120. /package/lib/{iconfont.1778157083004.woff → iconfont.1778318183872.woff} +0 -0
  121. /package/lib/{iconfont.1778157083004.woff2 → iconfont.1778318183872.woff2} +0 -0
@@ -1,1064 +1,1064 @@
1
- import { reactive, nextTick } from 'vue'
2
- import XEUtils from 'xe-utils'
3
- import { VxeUI } from '../../../ui'
4
- import { isEnableConf } from '../../../ui/src/utils'
5
- import { getCellValue, setCellValue, getRowid } from '../../src/util'
6
- import { removeClass, addClass } from '../../../ui/src/dom'
7
- import { warnLog, errLog } from '../../../ui/src/log'
8
-
9
- import type { TableEditMethods, TableEditPrivateMethods, VxeTableDefines } from '../../../../types'
10
-
11
- const { getConfig, renderer, hooks, getI18n } = VxeUI
12
-
13
- const tableEditMethodKeys: (keyof TableEditMethods)[] = ['insert', 'insertAt', 'insertNextAt', 'insertChild', 'insertChildAt', 'insertChildNextAt', 'remove', 'removeCheckboxRow', 'removeRadioRow', 'removeCurrentRow', 'getRecordset', 'getInsertRecords', 'getRemoveRecords', 'getUpdateRecords', 'getEditRecord', 'getActiveRecord', 'getEditCell', 'getSelectedCell', 'clearEdit', 'clearActived', 'clearSelected', 'isEditByRow', 'isActiveByRow', 'setEditRow', 'setActiveRow', 'setEditCell', 'setActiveCell', 'setSelectCell']
14
-
15
- hooks.add('tableEditModule', {
16
- setupTable ($xeTable) {
17
- const { props, reactData, internalData } = $xeTable
18
- const { refElem } = $xeTable.getRefMaps()
19
- const { computeMouseOpts, computeEditOpts, computeCheckboxOpts, computeTreeOpts, computeValidOpts } = $xeTable.getComputeMaps()
20
-
21
- const browseObj = XEUtils.browse()
22
-
23
- let editMethods = {} as TableEditMethods
24
- let editPrivateMethods = {} as TableEditPrivateMethods
25
-
26
- const getEditColumnModel = (row: any, column: VxeTableDefines.ColumnInfo) => {
27
- const { model, editRender } = column
28
- if (editRender) {
29
- model.value = getCellValue(row, column)
30
- model.update = false
31
- }
32
- }
33
-
34
- const setEditColumnModel = (row: any, column: VxeTableDefines.ColumnInfo) => {
35
- const { model, editRender } = column
36
- if (editRender && model.update) {
37
- setCellValue(row, column, model.value)
38
- model.update = false
39
- model.value = null
40
- }
41
- }
42
-
43
- const removeCellSelectedClass = () => {
44
- const el = refElem.value
45
- if (el) {
46
- const cell = el.querySelector('.col--selected')
47
- if (cell) {
48
- removeClass(cell, 'col--selected')
49
- }
50
- }
51
- }
52
-
53
- const syncActivedCell = () => {
54
- const { editStore, tableColumn } = reactData
55
- const editOpts = computeEditOpts.value
56
- const { actived } = editStore
57
- const { row, column } = actived
58
- if (row && column) {
59
- if (editOpts.mode === 'row') {
60
- tableColumn.forEach((column) => setEditColumnModel(row, column))
61
- } else {
62
- setEditColumnModel(row, column)
63
- }
64
- }
65
- }
66
-
67
- const insertTreeRow = (newRecords: any[], isAppend: boolean) => {
68
- const { tableFullTreeData, afterFullData, fullDataRowIdData, fullAllDataRowIdData } = internalData
69
- const treeOpts = computeTreeOpts.value
70
- const { rowField, parentField, mapChildrenField } = treeOpts
71
- const childrenField = treeOpts.children || treeOpts.childrenField
72
- const funcName = isAppend ? 'push' : 'unshift'
73
- newRecords.forEach(item => {
74
- const parentRowId = item[parentField]
75
- const rowid = getRowid($xeTable, item)
76
- const matchObj = parentRowId ? XEUtils.findTree(tableFullTreeData, item => parentRowId === item[rowField], { children: mapChildrenField }) : null
77
- if (matchObj) {
78
- const { item: parentRow } = matchObj
79
- const parentRest = fullAllDataRowIdData[getRowid($xeTable, parentRow)]
80
- const parentLevel = parentRest ? parentRest.level : 0
81
- let pChilds = parentRow[childrenField]
82
- let pMapChilds = parentRow[mapChildrenField]
83
- if (!XEUtils.isArray(pChilds)) {
84
- pChilds = parentRow[childrenField] = []
85
- }
86
- if (!XEUtils.isArray(pMapChilds)) {
87
- pMapChilds = parentRow[mapChildrenField] = []
88
- }
89
- pChilds[funcName](item)
90
- pMapChilds[funcName](item)
91
- const rest = { row: item, rowid, seq: -1, index: -1, _index: -1, $index: -1, treeIndex: -1, _tIndex: -1, items: pChilds, parent: parentRow, level: parentLevel + 1, height: 0, resizeHeight: 0, oTop: 0, expandHeight: 0 }
92
- fullDataRowIdData[rowid] = rest
93
- fullAllDataRowIdData[rowid] = rest
94
- } else {
95
- if (parentRowId) {
96
- warnLog('vxe.error.unableInsert')
97
- }
98
- afterFullData[funcName](item)
99
- tableFullTreeData[funcName](item)
100
- const rest = { row: item, rowid, seq: -1, index: -1, _index: -1, $index: -1, treeIndex: -1, _tIndex: -1, items: tableFullTreeData, parent: null, level: 0, height: 0, resizeHeight: 0, oTop: 0, expandHeight: 0 }
101
- fullDataRowIdData[rowid] = rest
102
- fullAllDataRowIdData[rowid] = rest
103
- }
104
- })
105
- $xeTable.handleClearStack()
106
- }
107
-
108
- // const insertGroupRow = (newRecords: any[], isAppend: boolean) => {
109
-
110
- // }
111
-
112
- const handleInsertRowAt = (records: any, targetRowOrRowid: any, isInsertNextRow?: boolean) => {
113
- const { treeConfig } = props
114
- const { isRowGroupStatus } = reactData
115
- const { tableFullTreeData, afterFullData, mergeBodyList, tableFullData, fullDataRowIdData, fullAllDataRowIdData, insertRowMaps, removeRowMaps } = internalData
116
- const treeOpts = computeTreeOpts.value
117
- const { transform, parentField, rowField, mapChildrenField } = treeOpts
118
- const childrenField = treeOpts.children || treeOpts.childrenField
119
- if (!XEUtils.isArray(records)) {
120
- records = [records]
121
- }
122
- let targetRow = targetRowOrRowid
123
- if (XEUtils.isString(targetRowOrRowid) || XEUtils.isNumber(targetRowOrRowid)) {
124
- const rowRest = fullAllDataRowIdData[targetRowOrRowid]
125
- if (rowRest) {
126
- targetRow = rowRest.row
127
- }
128
- }
129
- const newRecords: any[] = reactive($xeTable.defineField(records.map((record: any) => Object.assign(treeConfig && transform ? { [mapChildrenField]: [], [childrenField]: [] } : {}, record))))
130
- let treeRecords: any[] = []
131
- if (treeConfig && transform) {
132
- treeRecords = XEUtils.toArrayTree(newRecords, { key: rowField, parentKey: parentField, children: childrenField })
133
- }
134
- if (XEUtils.eqNull(targetRow)) {
135
- // 如果为虚拟树
136
- if (treeConfig && transform) {
137
- insertTreeRow(newRecords, false)
138
- } else if (isRowGroupStatus) {
139
- // 如果分组
140
- if (treeConfig) {
141
- throw new Error(getI18n('vxe.error.noTree', ['insert']))
142
- }
143
- errLog(getI18n('vxe.error.noGroup', ['insert']))
144
- // insertGroupRow(newRecords, false)
145
- } else {
146
- newRecords.forEach(item => {
147
- const rowid = getRowid($xeTable, item)
148
- const rest = { row: item, rowid, seq: -1, index: -1, _index: -1, $index: -1, treeIndex: -1, _tIndex: -1, items: afterFullData, parent: null, level: 0, height: 0, resizeHeight: 0, oTop: 0, expandHeight: 0 }
149
- fullDataRowIdData[rowid] = rest
150
- fullAllDataRowIdData[rowid] = rest
151
- afterFullData.unshift(item)
152
- tableFullData.unshift(item)
153
- })
154
- // 刷新单元格合并
155
- mergeBodyList.forEach((mergeItem: any) => {
156
- const { row: mergeRowIndex } = mergeItem
157
- if (mergeRowIndex >= 0) {
158
- mergeItem.row = mergeRowIndex + newRecords.length
159
- }
160
- })
161
- $xeTable.handleClearStack()
162
- }
163
- } else {
164
- if (targetRow === -1) {
165
- // 如果为虚拟树
166
- if (treeConfig && transform) {
167
- insertTreeRow(newRecords, true)
168
- } else if (isRowGroupStatus) {
169
- // 如果分组
170
- if (treeConfig) {
171
- throw new Error(getI18n('vxe.error.noTree', ['insert']))
172
- }
173
- errLog(getI18n('vxe.error.noGroup', ['insert']))
174
- // insertGroupRow(newRecords, true)
175
- } else {
176
- newRecords.forEach(item => {
177
- const rowid = getRowid($xeTable, item)
178
- const rest = { row: item, rowid, seq: -1, index: -1, _index: -1, treeIndex: -1, _tIndex: -1, $index: -1, items: afterFullData, parent: null, level: 0, height: 0, resizeHeight: 0, oTop: 0, expandHeight: 0 }
179
- fullDataRowIdData[rowid] = rest
180
- fullAllDataRowIdData[rowid] = rest
181
- afterFullData.push(item)
182
- tableFullData.push(item)
183
- })
184
- $xeTable.handleClearStack()
185
- }
186
- } else {
187
- // 如果为虚拟树
188
- if (treeConfig && transform) {
189
- const matchMapObj = XEUtils.findTree(tableFullTreeData, item => targetRow[rowField] === item[rowField], { children: mapChildrenField })
190
- if (matchMapObj) {
191
- const { parent: parentRow } = matchMapObj
192
- const parentMapChilds = parentRow ? parentRow[mapChildrenField] : tableFullTreeData
193
- const parentRest = fullAllDataRowIdData[getRowid($xeTable, parentRow)]
194
- const parentLevel = parentRest ? parentRest.level : 0
195
- treeRecords.forEach((row, i) => {
196
- if (parentRow) {
197
- if (row[parentField] !== parentRow[rowField]) {
198
- errLog('vxe.error.errProp', [`${parentField}=${row[parentField]}`, `${parentField}=${parentRow[rowField]}`])
199
- row[parentField] = parentRow[rowField]
200
- }
201
- } else {
202
- if (row[parentField] !== null) {
203
- if (!XEUtils.eqNull(row[parentField])) {
204
- errLog('vxe.error.errProp', [`${parentField}=${row[parentField]}`, 'null'])
205
- }
206
- row[parentField] = null
207
- }
208
- }
209
- let targetIndex = matchMapObj.index + i
210
- if (isInsertNextRow) {
211
- targetIndex = targetIndex + 1
212
- }
213
- parentMapChilds.splice(targetIndex, 0, row)
214
- })
215
- XEUtils.eachTree(treeRecords, (item) => {
216
- const rowid = getRowid($xeTable, item)
217
- const rest = { row: item, rowid, seq: -1, index: -1, _index: -1, $index: -1, treeIndex: -1, _tIndex: -1, items: parentMapChilds, parent: parentRow, level: parentLevel + 1, height: 0, resizeHeight: 0, oTop: 0, expandHeight: 0 }
218
- if (item[childrenField]) {
219
- item[mapChildrenField] = item[childrenField]
220
- }
221
- fullDataRowIdData[rowid] = rest
222
- fullAllDataRowIdData[rowid] = rest
223
- }, { children: childrenField })
224
- // 源
225
- if (parentRow) {
226
- const matchObj = XEUtils.findTree(tableFullTreeData, item => targetRow[rowField] === item[rowField], { children: childrenField })
227
- if (matchObj) {
228
- const parentChilds = matchObj.items
229
- let targetIndex = matchObj.index
230
- if (isInsertNextRow) {
231
- targetIndex = targetIndex + 1
232
- }
233
- parentChilds.splice(targetIndex, 0, ...treeRecords)
234
- }
235
- }
236
- $xeTable.handleClearStack()
237
- } else {
238
- warnLog('vxe.error.unableInsert')
239
- insertTreeRow(newRecords, true)
240
- }
241
- } else if (isRowGroupStatus) {
242
- // 如果分组
243
- if (treeConfig) {
244
- throw new Error(getI18n('vxe.error.noTree', ['insert']))
245
- }
246
- errLog(getI18n('vxe.error.noGroup', ['insert']))
247
- } else {
248
- if (treeConfig) {
249
- throw new Error(getI18n('vxe.error.noTree', ['insert']))
250
- }
251
- let afIndex = -1
252
- // 如果是可视索引
253
- if (XEUtils.isNumber(targetRow)) {
254
- if (targetRow < afterFullData.length) {
255
- afIndex = targetRow
256
- }
257
- } else {
258
- afIndex = $xeTable.findRowIndexOf(afterFullData, targetRow)
259
- }
260
- // 如果是插入指定行的下一行
261
- if (isInsertNextRow) {
262
- afIndex = Math.min(afterFullData.length, afIndex + 1)
263
- }
264
- if (afIndex === -1) {
265
- throw new Error(getI18n('vxe.error.unableInsert'))
266
- }
267
- afterFullData.splice(afIndex, 0, ...newRecords)
268
- const tfIndex = $xeTable.findRowIndexOf(tableFullData, targetRow)
269
- if (tfIndex > -1) {
270
- tableFullData.splice(tfIndex + (isInsertNextRow ? 1 : 0), 0, ...newRecords)
271
- } else {
272
- tableFullData.push(...newRecords)
273
- }
274
- // 刷新单元格合并
275
- mergeBodyList.forEach((mergeItem: any) => {
276
- const { row: mergeRowIndex, rowspan: mergeRowspan } = mergeItem
277
- if (mergeRowIndex >= afIndex) {
278
- mergeItem.row = mergeRowIndex + newRecords.length
279
- } else if (isInsertNextRow ? (mergeRowIndex + mergeRowspan >= afIndex) : (mergeRowIndex + mergeRowspan > afIndex)) {
280
- mergeItem.rowspan = mergeRowspan + newRecords.length
281
- }
282
- })
283
- $xeTable.handleClearStack()
284
- }
285
- }
286
- }
287
-
288
- const handleStatus = (newRow: any) => {
289
- const rowid = getRowid($xeTable, newRow)
290
- // 如果是被删除的数据,则还原状态
291
- if (removeRowMaps[rowid]) {
292
- delete removeRowMaps[rowid]
293
- if (insertRowMaps[rowid]) {
294
- delete insertRowMaps[rowid]
295
- }
296
- } else {
297
- insertRowMaps[rowid] = newRow
298
- }
299
- }
300
- // 如果为虚拟树
301
- if (treeConfig && transform) {
302
- XEUtils.eachTree(treeRecords, handleStatus, { children: mapChildrenField })
303
- } else {
304
- newRecords.forEach(handleStatus)
305
- }
306
-
307
- reactData.removeRowFlag++
308
- reactData.insertRowFlag++
309
- $xeTable.cacheRowMap(false)
310
- $xeTable.updateScrollYStatus()
311
- $xeTable.handleTableData(treeConfig && transform)
312
- if (!(treeConfig && transform)) {
313
- $xeTable.updateAfterDataIndex()
314
- }
315
- $xeTable.updateFooter()
316
- $xeTable.handleUpdateBodyMerge()
317
- $xeTable.checkSelectionStatus()
318
- if (reactData.scrollYLoad) {
319
- $xeTable.updateScrollYSpace()
320
- }
321
- return nextTick().then(() => {
322
- $xeTable.updateCellAreas()
323
- return $xeTable.recalculate(true)
324
- }).then(() => {
325
- return {
326
- row: newRecords.length ? newRecords[newRecords.length - 1] : null,
327
- rows: newRecords
328
- }
329
- })
330
- }
331
-
332
- const handleInsertChildRowAt = (records: any, parentRowOrParentId: any, targetRow: any, isInsertNextRow?: boolean) => {
333
- const { treeConfig } = props
334
- const { fullAllDataRowIdData } = internalData
335
- const treeOpts = computeTreeOpts.value
336
- const { transform, rowField, parentField } = treeOpts
337
- if (treeConfig && transform) {
338
- if (!XEUtils.isArray(records)) {
339
- records = [records]
340
- }
341
- let parentRow = parentRowOrParentId
342
- if (XEUtils.isString(parentRowOrParentId) || XEUtils.isNumber(parentRowOrParentId)) {
343
- const rowRest = fullAllDataRowIdData[parentRowOrParentId]
344
- if (rowRest) {
345
- parentRow = rowRest.row
346
- }
347
- }
348
- return handleInsertRowAt(records.map((item: any) => Object.assign({}, item, { [parentField]: parentRow[rowField] })), targetRow, isInsertNextRow)
349
- } else {
350
- errLog('vxe.error.errProp', ['tree-config.transform=false', 'tree-config.transform=true'])
351
- }
352
- return Promise.resolve({ row: null, rows: [] })
353
- }
354
-
355
- const handleClearEdit = (evnt: Event | null, targetRow?: any) => {
356
- const { editStore } = reactData
357
- const { actived, focused } = editStore
358
- const { row, column } = actived
359
- const validOpts = computeValidOpts.value
360
- if (row || column) {
361
- if (targetRow && getRowid($xeTable, targetRow) !== getRowid($xeTable, row)) {
362
- return nextTick()
363
- }
364
- syncActivedCell()
365
- $xeTable.updateFooter()
366
- actived.args = null
367
- actived.row = null
368
- actived.column = null
369
- $xeTable.dispatchEvent('edit-closed', {
370
- row,
371
- rowIndex: $xeTable.getRowIndex(row),
372
- $rowIndex: $xeTable.getVMRowIndex(row),
373
- column,
374
- columnIndex: $xeTable.getColumnIndex(column),
375
- $columnIndex: $xeTable.getVMColumnIndex(column)
376
- }, evnt || null)
377
- }
378
- focused.row = null
379
- focused.column = null
380
- if (validOpts.autoClear) {
381
- if (validOpts.msgMode !== 'full' || getConfig().cellVaildMode === 'obsolete') {
382
- if ($xeTable.clearValidate) {
383
- return $xeTable.clearValidate()
384
- }
385
- }
386
- }
387
- return nextTick().then(() => $xeTable.updateCellAreas())
388
- }
389
-
390
- const handleEditActive = (params: any, evnt: Event | null, options: {
391
- isClear?: boolean
392
- isFocus?: boolean
393
- isPos?: boolean
394
- }) => {
395
- const $xeGrid = $xeTable.xeGrid
396
- const $xeGantt = $xeTable.xeGantt
397
-
398
- const { editConfig, mouseConfig } = props
399
- const { editStore, tableColumn } = reactData
400
- const editOpts = computeEditOpts.value
401
- const { mode } = editOpts
402
- const { actived, focused } = editStore
403
- const { row, column } = params
404
- const { editRender } = column
405
- const { isFocus, isPos, isClear } = options
406
- const cell = (params.cell || $xeTable.getCellElement(row, column))
407
- const beforeEditMethod = editOpts.beforeEditMethod || editOpts.activeMethod
408
- params.cell = cell
409
- if (cell && isEnableConf(editConfig) && isEnableConf(editRender)) {
410
- // 激活编辑
411
- if (!$xeTable.isPendingByRow(row) && !$xeTable.isAggregateRecord(row)) {
412
- if (actived.row !== row || (mode === 'cell' ? actived.column !== column : false)) {
413
- // 判断是否禁用编辑
414
- let type: 'edit-disabled' | 'edit-activated' = 'edit-disabled'
415
- if (!beforeEditMethod || beforeEditMethod({ ...params, $table: $xeTable, $grid: $xeGrid, $gantt: $xeGantt })) {
416
- if (mouseConfig) {
417
- $xeTable.clearSelected()
418
- if ($xeTable.clearCellAreas) {
419
- $xeTable.clearCellAreas()
420
- $xeTable.clearCopyCellArea()
421
- }
422
- }
423
- $xeTable.closeTooltip()
424
- if (actived.column) {
425
- handleClearEdit(evnt)
426
- }
427
- type = 'edit-activated'
428
- column.renderHeight = cell.offsetHeight
429
- actived.args = params
430
- actived.row = row
431
- actived.column = column
432
- $xeTable.handlePushStack()
433
- if (isClear) {
434
- setCellValue(row, column, null)
435
- }
436
- if (mode === 'row') {
437
- tableColumn.forEach((column: any) => getEditColumnModel(row, column))
438
- } else {
439
- getEditColumnModel(row, column)
440
- }
441
- const afterEditMethod = editOpts.afterEditMethod
442
- nextTick(() => {
443
- if (isFocus) {
444
- $xeTable.handleFocus(params, evnt)
445
- }
446
- if (afterEditMethod) {
447
- afterEditMethod({ ...params, $table: $xeTable, $grid: $xeGrid, $gantt: $xeGantt })
448
- }
449
- })
450
- }
451
- $xeTable.dispatchEvent(type, {
452
- row,
453
- rowIndex: $xeTable.getRowIndex(row),
454
- $rowIndex: $xeTable.getVMRowIndex(row),
455
- column,
456
- columnIndex: $xeTable.getColumnIndex(column),
457
- $columnIndex: $xeTable.getVMColumnIndex(column)
458
- }, evnt)
459
-
460
- // v4已废弃
461
- if (type === 'edit-activated') {
462
- $xeTable.dispatchEvent('edit-actived', {
463
- row,
464
- rowIndex: $xeTable.getRowIndex(row),
465
- $rowIndex: $xeTable.getVMRowIndex(row),
466
- column,
467
- columnIndex: $xeTable.getColumnIndex(column),
468
- $columnIndex: $xeTable.getVMColumnIndex(column)
469
- }, evnt)
470
- }
471
- } else {
472
- const { column: oldColumn } = actived
473
- if (mouseConfig) {
474
- $xeTable.clearSelected()
475
- if ($xeTable.clearCellAreas) {
476
- $xeTable.clearCellAreas()
477
- $xeTable.clearCopyCellArea()
478
- }
479
- }
480
- if (oldColumn && oldColumn !== column) {
481
- const { model: oldModel } = oldColumn
482
- if (oldModel.update) {
483
- setCellValue(row, oldColumn, oldModel.value)
484
- }
485
- if ($xeTable.clearValidate) {
486
- $xeTable.clearValidate(row, column)
487
- }
488
- }
489
- column.renderHeight = cell.offsetHeight
490
- actived.args = params
491
- actived.column = column
492
- if (isPos) {
493
- setTimeout(() => {
494
- $xeTable.handleFocus(params, evnt)
495
- })
496
- }
497
- }
498
- focused.column = null
499
- focused.row = null
500
- $xeTable.focus()
501
- }
502
- }
503
- return nextTick()
504
- }
505
-
506
- const handleEditCell = (row: any, fieldOrColumn: string | VxeTableDefines.ColumnInfo | null, options: {
507
- isClear?: boolean | undefined;
508
- isFocus?: boolean | undefined;
509
- isPos?: boolean | undefined;
510
- }) => {
511
- const { editConfig } = props
512
- const { isPos } = options
513
- const column = XEUtils.isString(fieldOrColumn) ? $xeTable.getColumnByField(fieldOrColumn) : fieldOrColumn
514
- if (row && column && isEnableConf(editConfig) && isEnableConf(column.editRender) && !$xeTable.isAggregateRecord(row)) {
515
- return Promise.resolve(isPos ? $xeTable.scrollToRow(row, column) : null).then(() => {
516
- const cell = $xeTable.getCellElement(row, column)
517
- if (cell) {
518
- handleEditActive({
519
- row,
520
- rowIndex: $xeTable.getRowIndex(row),
521
- column,
522
- columnIndex: $xeTable.getColumnIndex(column),
523
- cell,
524
- $table: $xeTable
525
- }, null, {
526
- isFocus: isPos,
527
- isPos
528
- })
529
- internalData._lastCallTime = Date.now()
530
- }
531
- return nextTick()
532
- })
533
- }
534
- return nextTick()
535
- }
536
-
537
- editMethods = {
538
- /**
539
- * 往表格中插入临时数据
540
- *
541
- * @param {*} records
542
- */
543
- insert (records) {
544
- return handleInsertRowAt(records, null)
545
- },
546
- /**
547
- * 往表格指定行中插入临时数据
548
- * 如果 row 为空则从插入到顶部,如果为树结构,则插入到目标节点顶部
549
- * 如果 row 为 -1 则从插入到底部,如果为树结构,则插入到目标节点底部
550
- * 如果 row 为有效行则插入到该行的位置,如果为树结构,则有插入到效的目标节点该行的位置
551
- */
552
- insertAt (records, targetRowOrRowid) {
553
- return handleInsertRowAt(records, targetRowOrRowid)
554
- },
555
- insertNextAt (records, targetRowOrRowid) {
556
- return handleInsertRowAt(records, targetRowOrRowid, true)
557
- },
558
- insertChild (records, parentRowOrParentId) {
559
- (window as any).aa = internalData
560
- return handleInsertChildRowAt(records, parentRowOrParentId, null)
561
- },
562
- insertChildAt (records, parentRowOrParentId, targetRow) {
563
- return handleInsertChildRowAt(records, parentRowOrParentId, targetRow)
564
- },
565
- insertChildNextAt (records, parentRowOrParentId, targetRow) {
566
- return handleInsertChildRowAt(records, parentRowOrParentId, targetRow, true)
567
- },
568
- /**
569
- * 删除指定行数据
570
- * 如果传 row 则删除一行
571
- * 如果传 rows 则删除多行
572
- * 如果为空则删除所有
573
- */
574
- remove (rows: any) {
575
- const { treeConfig } = props
576
- const { editStore, isRowGroupStatus } = reactData
577
- const { tableFullTreeData, selectCheckboxMaps, afterFullData, mergeBodyList, tableFullData, pendingRowMaps, insertRowMaps, removeRowMaps } = internalData
578
- const checkboxOpts = computeCheckboxOpts.value
579
- const treeOpts = computeTreeOpts.value
580
- const { transform, mapChildrenField } = treeOpts
581
- const childrenField = treeOpts.children || treeOpts.childrenField
582
- const { actived } = editStore
583
- const { checkField } = checkboxOpts
584
- let delList: any[] = []
585
- if (!rows) {
586
- rows = tableFullData
587
- } else if (!XEUtils.isArray(rows)) {
588
- rows = [rows]
589
- }
590
- // 如果是新增,则保存记录
591
- rows.forEach((row: any) => {
592
- if (!$xeTable.isInsertByRow(row)) {
593
- const rowid = getRowid($xeTable, row)
594
- removeRowMaps[rowid] = row
595
- }
596
- })
597
- // 如果绑定了多选属性,则更新状态
598
- if (!checkField) {
599
- rows.forEach((row: any) => {
600
- const rowid = getRowid($xeTable, row)
601
- if (selectCheckboxMaps[rowid]) {
602
- delete selectCheckboxMaps[rowid]
603
- }
604
- })
605
- reactData.updateCheckboxFlag++
606
- }
607
- // 从数据源中移除
608
- if (tableFullData === rows) {
609
- rows = delList = tableFullData.slice(0)
610
- internalData.tableFullData = []
611
- internalData.afterFullData = []
612
- $xeTable.clearMergeCells()
613
- } else {
614
- // 如果为虚拟树
615
- if (treeConfig && transform) {
616
- rows.forEach((row: any) => {
617
- const rowid = getRowid($xeTable, row)
618
- const matchMapObj = XEUtils.findTree(tableFullTreeData, item => rowid === getRowid($xeTable, item), { children: mapChildrenField })
619
- if (matchMapObj) {
620
- const rItems = matchMapObj.items.splice(matchMapObj.index, 1)
621
- delList.push(rItems[0])
622
- }
623
- const matchObj = XEUtils.findTree(tableFullTreeData, item => rowid === getRowid($xeTable, item), { children: childrenField })
624
- if (matchObj) {
625
- matchObj.items.splice(matchObj.index, 1)
626
- }
627
- const afIndex = $xeTable.findRowIndexOf(afterFullData, row)
628
- if (afIndex > -1) {
629
- afterFullData.splice(afIndex, 1)
630
- }
631
- })
632
- } else if (isRowGroupStatus) {
633
- // 如果分组
634
- warnLog(getI18n('vxe.error.noGroup', ['remove']))
635
- } else {
636
- rows.forEach((row: any) => {
637
- const tfIndex = $xeTable.findRowIndexOf(tableFullData, row)
638
- if (tfIndex > -1) {
639
- const rItems = tableFullData.splice(tfIndex, 1)
640
- delList.push(rItems[0])
641
- }
642
- const afIndex = $xeTable.findRowIndexOf(afterFullData, row)
643
- if (afIndex > -1) {
644
- // 刷新单元格合并
645
- mergeBodyList.forEach((mergeItem) => {
646
- const { row: mergeRowIndex, rowspan: mergeRowspan } = mergeItem
647
- if (mergeRowIndex > afIndex) {
648
- mergeItem.row = mergeRowIndex - 1
649
- } else if (mergeRowIndex + mergeRowspan > afIndex) {
650
- mergeItem.rowspan = mergeRowspan - 1
651
- }
652
- })
653
- afterFullData.splice(afIndex, 1)
654
- }
655
- })
656
- }
657
- }
658
- // 如果当前行被激活编辑,则清除激活状态
659
- if (actived.row && $xeTable.findRowIndexOf(rows, actived.row) > -1) {
660
- editMethods.clearEdit()
661
- }
662
- // 从新增中移除已删除的数据
663
- rows.forEach((row: any) => {
664
- const rowid = getRowid($xeTable, row)
665
- if (insertRowMaps[rowid]) {
666
- delete insertRowMaps[rowid]
667
- }
668
- if (pendingRowMaps[rowid]) {
669
- delete pendingRowMaps[rowid]
670
- }
671
- })
672
- reactData.removeRowFlag++
673
- reactData.insertRowFlag++
674
- reactData.pendingRowFlag++
675
- $xeTable.handleClearStack()
676
- $xeTable.cacheRowMap(false)
677
- $xeTable.handleTableData(treeConfig && transform)
678
- $xeTable.updateFooter()
679
- $xeTable.handleUpdateBodyMerge()
680
- if (!(treeConfig && transform)) {
681
- $xeTable.updateAfterDataIndex()
682
- }
683
- $xeTable.checkSelectionStatus()
684
- if (reactData.scrollYLoad) {
685
- $xeTable.updateScrollYSpace()
686
- }
687
- return nextTick().then(() => {
688
- $xeTable.updateCellAreas()
689
- return $xeTable.recalculate(true)
690
- }).then(() => {
691
- return { row: delList.length ? delList[delList.length - 1] : null, rows: delList }
692
- })
693
- },
694
- /**
695
- * 删除复选框选中的数据
696
- */
697
- removeCheckboxRow () {
698
- return editMethods.remove($xeTable.getCheckboxRecords()).then((params: any) => {
699
- $xeTable.clearCheckboxRow()
700
- return params
701
- })
702
- },
703
- /**
704
- * 删除单选框选中的数据
705
- */
706
- removeRadioRow () {
707
- const radioRecord = $xeTable.getRadioRecord()
708
- return editMethods.remove(radioRecord || []).then((params: any) => {
709
- $xeTable.clearRadioRow()
710
- return params
711
- })
712
- },
713
- /**
714
- * 删除当前行选中的数据
715
- */
716
- removeCurrentRow () {
717
- const currentRecord = $xeTable.getCurrentRecord()
718
- return editMethods.remove(currentRecord || []).then((params: any) => {
719
- $xeTable.clearCurrentRow()
720
- return params
721
- })
722
- },
723
- /**
724
- * 获取表格数据集,包含新增、删除、修改、标记
725
- */
726
- getRecordset () {
727
- const removeRecords = editMethods.getRemoveRecords()
728
- const pendingRecords = $xeTable.getPendingRecords()
729
- const delRecords = removeRecords.concat(pendingRecords)
730
- // 如果已经被删除,则无需放到更新数组
731
- const updateRecords = editMethods.getUpdateRecords().filter(row => {
732
- return !delRecords.some(item => $xeTable.eqRow(item, row))
733
- })
734
- return {
735
- insertRecords: editMethods.getInsertRecords(),
736
- removeRecords,
737
- updateRecords,
738
- pendingRecords
739
- }
740
- },
741
- /**
742
- * 获取新增的临时数据
743
- */
744
- getInsertRecords () {
745
- const { fullAllDataRowIdData, insertRowMaps } = internalData
746
- const insertRecords: any[] = []
747
- XEUtils.each(insertRowMaps, (row, rowid) => {
748
- if (fullAllDataRowIdData[rowid]) {
749
- insertRecords.push(row)
750
- }
751
- })
752
- return insertRecords
753
- },
754
- /**
755
- * 获取已删除的数据
756
- */
757
- getRemoveRecords () {
758
- const { removeRowMaps } = internalData
759
- const removeRecords: any[] = []
760
- XEUtils.each(removeRowMaps, (row) => {
761
- removeRecords.push(row)
762
- })
763
- return removeRecords
764
- },
765
- /**
766
- * 获取更新数据
767
- * 只精准匹配 row 的更改
768
- * 如果是树表格,子节点更改状态不会影响父节点的更新状态
769
- */
770
- getUpdateRecords () {
771
- const { keepSource, treeConfig } = props
772
- const { tableFullData } = internalData
773
- const treeOpts = computeTreeOpts.value
774
- if (keepSource) {
775
- syncActivedCell()
776
- if (treeConfig) {
777
- return XEUtils.filterTree(tableFullData, row => $xeTable.isUpdateByRow(row), treeOpts)
778
- }
779
- return tableFullData.filter((row: any) => $xeTable.isUpdateByRow(row))
780
- }
781
- return []
782
- },
783
- getActiveRecord () {
784
- warnLog('vxe.error.delFunc', ['getActiveRecord', 'getEditCell'])
785
- const { editStore } = reactData
786
- const { fullAllDataRowIdData } = internalData
787
- const { args, row } = editStore.actived
788
- if (args && row && fullAllDataRowIdData[getRowid($xeTable, row)]) {
789
- return Object.assign({}, args, { row })
790
- }
791
- return null
792
- },
793
- getEditRecord () {
794
- warnLog('vxe.error.delFunc', ['getEditRecord', 'getEditCell'])
795
- const { editStore } = reactData
796
- const { fullAllDataRowIdData } = internalData
797
- const { args, row } = editStore.actived
798
- if (args && row && fullAllDataRowIdData[getRowid($xeTable, row)]) {
799
- return Object.assign({}, args, { row })
800
- }
801
- return null
802
- },
803
- getEditCell () {
804
- const { editStore } = reactData
805
- const { row, column } = editStore.actived
806
- if (column && row) {
807
- return {
808
- row,
809
- rowIndex: $xeTable.getRowIndex(row),
810
- column,
811
- columnIndex: $xeTable.getColumnIndex(column)
812
- }
813
- }
814
- return null
815
- },
816
- /**
817
- * 获取选中的单元格
818
- */
819
- getSelectedCell () {
820
- const { editStore } = reactData
821
- const { row, column } = editStore.selected
822
- if (row && column) {
823
- return {
824
- row,
825
- column
826
- }
827
- }
828
- return null
829
- },
830
- clearActived (row) {
831
- // 即将废弃
832
- warnLog('vxe.error.delFunc', ['clearActived', 'clearEdit'])
833
- return $xeTable.clearEdit(row)
834
- },
835
- /**
836
- * 清除激活的编辑
837
- */
838
- clearEdit (row) {
839
- return handleClearEdit(null, row)
840
- },
841
- /**
842
- * 清除所选中源状态
843
- */
844
- clearSelected () {
845
- const { editStore } = reactData
846
- const { selected } = editStore
847
- selected.row = null
848
- selected.column = null
849
- removeCellSelectedClass()
850
- return nextTick()
851
- },
852
- isActiveByRow (row) {
853
- warnLog('vxe.error.delFunc', ['isActiveByRow', 'isEditByRow'])
854
- // 即将废弃
855
- return $xeTable.isEditByRow(row)
856
- },
857
- /**
858
- * 判断行是否为激活编辑状态
859
- * @param {Row} row 行对象
860
- */
861
- isEditByRow (row) {
862
- const { editStore } = reactData
863
- return editStore.actived.row === row
864
- },
865
- setActiveRow (row) {
866
- warnLog('vxe.error.delFunc', ['setActiveRow', 'setEditRow'])
867
- // 即将废弃
868
- return editMethods.setEditRow(row)
869
- },
870
- /**
871
- * 激活行编辑
872
- */
873
- setEditRow (row, fieldOrColumn, options) {
874
- const { visibleColumn } = internalData
875
- let column: any = XEUtils.find(visibleColumn, column => isEnableConf(column.editRender))
876
- let isPos = false
877
- if (fieldOrColumn) {
878
- isPos = true
879
- if (fieldOrColumn !== true) {
880
- column = XEUtils.isString(fieldOrColumn) ? $xeTable.getColumnByField(fieldOrColumn) : fieldOrColumn
881
- }
882
- }
883
- return handleEditCell(row, column, Object.assign({
884
- isPos,
885
- isFocus: isPos
886
- }, options))
887
- },
888
- setActiveCell (row, fieldOrColumn) {
889
- warnLog('vxe.error.delFunc', ['setActiveCell', 'setEditCell'])
890
- // 即将废弃
891
- return editMethods.setEditCell(row, fieldOrColumn)
892
- },
893
- /**
894
- * 激活单元格编辑
895
- */
896
- setEditCell (row, fieldOrColumn, options) {
897
- return handleEditCell(row, fieldOrColumn, Object.assign({
898
- isFocus: true,
899
- isPos: true
900
- }, options))
901
- },
902
- /**
903
- * 只对 trigger=dblclick 有效,选中单元格
904
- */
905
- setSelectCell (row, fieldOrColumn) {
906
- const { tableData } = reactData
907
- const editOpts = computeEditOpts.value
908
- const column = XEUtils.isString(fieldOrColumn) ? $xeTable.getColumnByField(fieldOrColumn) : fieldOrColumn
909
- if (row && column && editOpts.trigger !== 'manual') {
910
- const rowIndex = $xeTable.findRowIndexOf(tableData, row)
911
- if (rowIndex > -1 && column) {
912
- const cell = $xeTable.getCellElement(row, column)
913
- const params = {
914
- row,
915
- rowIndex,
916
- column,
917
- columnIndex: $xeTable.getColumnIndex(column),
918
- cell
919
- }
920
- $xeTable.handleSelected(params, {})
921
- }
922
- }
923
- return nextTick()
924
- }
925
- }
926
-
927
- editPrivateMethods = {
928
- /**
929
- * 处理激活编辑
930
- */
931
- handleEdit (params, evnt, options) {
932
- return handleEditActive(params, evnt, Object.assign({
933
- isFocus: true,
934
- isPos: true
935
- }, options))
936
- },
937
- /**
938
- * @deprecated
939
- */
940
- handleActived (params, evnt) {
941
- return editPrivateMethods.handleEdit(params, evnt)
942
- },
943
- /**
944
- * 处理取消编辑
945
- * @param evnt
946
- * @returns
947
- */
948
- handleClearEdit,
949
- /**
950
- * 处理聚焦
951
- */
952
- handleFocus (params) {
953
- const { row, column, cell } = params
954
- const { editRender } = column
955
- const editOpts = computeEditOpts.value
956
- if (isEnableConf(editRender)) {
957
- const compRender = renderer.get(editRender.name)
958
- let autoFocus = editRender.autofocus || editRender.autoFocus
959
- let autoSelect = editRender.autoSelect || editRender.autoselect
960
- let inputElem
961
- // 是否启用聚焦
962
- if (editOpts.autoFocus) {
963
- if (!autoFocus && compRender) {
964
- autoFocus = compRender.tableAutoFocus || compRender.tableAutofocus || compRender.autofocus
965
- }
966
- if (!autoSelect && compRender) {
967
- autoSelect = compRender.tableAutoSelect || compRender.autoselect
968
- }
969
- // 如果指定了聚焦 class
970
- if (XEUtils.isFunction(autoFocus)) {
971
- inputElem = autoFocus(params)
972
- } else if (autoFocus) {
973
- if (autoFocus === true) {
974
- // 自动匹配模式,会自动匹配第一个可输入元素
975
- inputElem = cell.querySelector('input,textarea')
976
- } else {
977
- inputElem = cell.querySelector(autoFocus)
978
- }
979
- if (inputElem) {
980
- inputElem.focus()
981
- }
982
- }
983
- }
984
- if (inputElem) {
985
- if (autoSelect) {
986
- inputElem.select()
987
- } else {
988
- // 保持一致行为,光标移到末端
989
- if (browseObj.msie) {
990
- const textRange = inputElem.createTextRange()
991
- textRange.collapse(false)
992
- textRange.select()
993
- }
994
- }
995
- } else {
996
- // 是否自动定位
997
- if (editOpts.autoPos) {
998
- if (!column.fixed) {
999
- // 显示到可视区中
1000
- $xeTable.scrollToRow(row, column)
1001
- }
1002
- }
1003
- }
1004
- }
1005
- },
1006
- /**
1007
- * 处理选中源
1008
- */
1009
- handleSelected (params, evnt) {
1010
- const { mouseConfig } = props
1011
- const { editStore } = reactData
1012
- const mouseOpts = computeMouseOpts.value
1013
- const editOpts = computeEditOpts.value
1014
- const { actived, selected } = editStore
1015
- const { row, column } = params
1016
- const isMouseSelected = mouseConfig && mouseOpts.selected
1017
- const selectMethod = () => {
1018
- if (isMouseSelected && (selected.row !== row || selected.column !== column)) {
1019
- if (actived.row !== row || (editOpts.mode === 'cell' ? actived.column !== column : false)) {
1020
- handleClearEdit(evnt)
1021
- $xeTable.clearSelected()
1022
- if ($xeTable.clearCellAreas) {
1023
- $xeTable.clearCellAreas()
1024
- $xeTable.clearCopyCellArea()
1025
- }
1026
- selected.args = params
1027
- selected.row = row
1028
- selected.column = column
1029
- if (isMouseSelected) {
1030
- editPrivateMethods.addCellSelectedClass()
1031
- }
1032
- $xeTable.focus()
1033
- if (evnt) {
1034
- $xeTable.dispatchEvent('cell-selected', params, evnt)
1035
- }
1036
- }
1037
- }
1038
- return nextTick()
1039
- }
1040
- return selectMethod()
1041
- },
1042
- addCellSelectedClass () {
1043
- const { editStore } = reactData
1044
- const { selected } = editStore
1045
- const { row, column } = selected
1046
- removeCellSelectedClass()
1047
- if (row && column) {
1048
- const cell = $xeTable.getCellElement(row, column)
1049
- if (cell) {
1050
- addClass(cell, 'col--selected')
1051
- }
1052
- }
1053
- }
1054
- }
1055
-
1056
- return { ...editMethods, ...editPrivateMethods }
1057
- },
1058
- setupGrid ($xeGrid) {
1059
- return $xeGrid.extendTableMethods(tableEditMethodKeys)
1060
- },
1061
- setupGantt ($xeGantt) {
1062
- return $xeGantt.extendTableMethods(tableEditMethodKeys)
1063
- }
1064
- })
1
+ import { reactive, nextTick } from 'vue'
2
+ import XEUtils from 'xe-utils'
3
+ import { VxeUI } from '../../../ui'
4
+ import { isEnableConf } from '../../../ui/src/utils'
5
+ import { getCellValue, setCellValue, getRowid } from '../../src/util'
6
+ import { removeClass, addClass } from '../../../ui/src/dom'
7
+ import { warnLog, errLog } from '../../../ui/src/log'
8
+
9
+ import type { TableEditMethods, TableEditPrivateMethods, VxeTableDefines } from '../../../../types'
10
+
11
+ const { getConfig, renderer, hooks, getI18n } = VxeUI
12
+
13
+ const tableEditMethodKeys: (keyof TableEditMethods)[] = ['insert', 'insertAt', 'insertNextAt', 'insertChild', 'insertChildAt', 'insertChildNextAt', 'remove', 'removeCheckboxRow', 'removeRadioRow', 'removeCurrentRow', 'getRecordset', 'getInsertRecords', 'getRemoveRecords', 'getUpdateRecords', 'getEditRecord', 'getActiveRecord', 'getEditCell', 'getSelectedCell', 'clearEdit', 'clearActived', 'clearSelected', 'isEditByRow', 'isActiveByRow', 'setEditRow', 'setActiveRow', 'setEditCell', 'setActiveCell', 'setSelectCell']
14
+
15
+ hooks.add('tableEditModule', {
16
+ setupTable ($xeTable) {
17
+ const { props, reactData, internalData } = $xeTable
18
+ const { refElem } = $xeTable.getRefMaps()
19
+ const { computeMouseOpts, computeEditOpts, computeCheckboxOpts, computeTreeOpts, computeValidOpts } = $xeTable.getComputeMaps()
20
+
21
+ const browseObj = XEUtils.browse()
22
+
23
+ let editMethods = {} as TableEditMethods
24
+ let editPrivateMethods = {} as TableEditPrivateMethods
25
+
26
+ const getEditColumnModel = (row: any, column: VxeTableDefines.ColumnInfo) => {
27
+ const { model, editRender } = column
28
+ if (editRender) {
29
+ model.value = getCellValue(row, column)
30
+ model.update = false
31
+ }
32
+ }
33
+
34
+ const setEditColumnModel = (row: any, column: VxeTableDefines.ColumnInfo) => {
35
+ const { model, editRender } = column
36
+ if (editRender && model.update) {
37
+ setCellValue(row, column, model.value)
38
+ model.update = false
39
+ model.value = null
40
+ }
41
+ }
42
+
43
+ const removeCellSelectedClass = () => {
44
+ const el = refElem.value
45
+ if (el) {
46
+ const cell = el.querySelector('.col--selected')
47
+ if (cell) {
48
+ removeClass(cell, 'col--selected')
49
+ }
50
+ }
51
+ }
52
+
53
+ const syncActivedCell = () => {
54
+ const { editStore, tableColumn } = reactData
55
+ const editOpts = computeEditOpts.value
56
+ const { actived } = editStore
57
+ const { row, column } = actived
58
+ if (row && column) {
59
+ if (editOpts.mode === 'row') {
60
+ tableColumn.forEach((column) => setEditColumnModel(row, column))
61
+ } else {
62
+ setEditColumnModel(row, column)
63
+ }
64
+ }
65
+ }
66
+
67
+ const insertTreeRow = (newRecords: any[], isAppend: boolean) => {
68
+ const { tableFullTreeData, afterFullData, fullDataRowIdData, fullAllDataRowIdData } = internalData
69
+ const treeOpts = computeTreeOpts.value
70
+ const { rowField, parentField, mapChildrenField } = treeOpts
71
+ const childrenField = treeOpts.children || treeOpts.childrenField
72
+ const funcName = isAppend ? 'push' : 'unshift'
73
+ newRecords.forEach(item => {
74
+ const parentRowId = item[parentField]
75
+ const rowid = getRowid($xeTable, item)
76
+ const matchObj = parentRowId ? XEUtils.findTree(tableFullTreeData, item => parentRowId === item[rowField], { children: mapChildrenField }) : null
77
+ if (matchObj) {
78
+ const { item: parentRow } = matchObj
79
+ const parentRest = fullAllDataRowIdData[getRowid($xeTable, parentRow)]
80
+ const parentLevel = parentRest ? parentRest.level : 0
81
+ let pChilds = parentRow[childrenField]
82
+ let pMapChilds = parentRow[mapChildrenField]
83
+ if (!XEUtils.isArray(pChilds)) {
84
+ pChilds = parentRow[childrenField] = []
85
+ }
86
+ if (!XEUtils.isArray(pMapChilds)) {
87
+ pMapChilds = parentRow[mapChildrenField] = []
88
+ }
89
+ pChilds[funcName](item)
90
+ pMapChilds[funcName](item)
91
+ const rest = { row: item, rowid, seq: -1, index: -1, _index: -1, $index: -1, treeIndex: -1, _tIndex: -1, items: pChilds, parent: parentRow, level: parentLevel + 1, height: 0, resizeHeight: 0, oTop: 0, expandHeight: 0 }
92
+ fullDataRowIdData[rowid] = rest
93
+ fullAllDataRowIdData[rowid] = rest
94
+ } else {
95
+ if (parentRowId) {
96
+ warnLog('vxe.error.unableInsert')
97
+ }
98
+ afterFullData[funcName](item)
99
+ tableFullTreeData[funcName](item)
100
+ const rest = { row: item, rowid, seq: -1, index: -1, _index: -1, $index: -1, treeIndex: -1, _tIndex: -1, items: tableFullTreeData, parent: null, level: 0, height: 0, resizeHeight: 0, oTop: 0, expandHeight: 0 }
101
+ fullDataRowIdData[rowid] = rest
102
+ fullAllDataRowIdData[rowid] = rest
103
+ }
104
+ })
105
+ $xeTable.handleClearStack()
106
+ }
107
+
108
+ // const insertGroupRow = (newRecords: any[], isAppend: boolean) => {
109
+
110
+ // }
111
+
112
+ const handleInsertRowAt = (records: any, targetRowOrRowid: any, isInsertNextRow?: boolean) => {
113
+ const { treeConfig } = props
114
+ const { isRowGroupStatus } = reactData
115
+ const { tableFullTreeData, afterFullData, mergeBodyList, tableFullData, fullDataRowIdData, fullAllDataRowIdData, insertRowMaps, removeRowMaps } = internalData
116
+ const treeOpts = computeTreeOpts.value
117
+ const { transform, parentField, rowField, mapChildrenField } = treeOpts
118
+ const childrenField = treeOpts.children || treeOpts.childrenField
119
+ if (!XEUtils.isArray(records)) {
120
+ records = [records]
121
+ }
122
+ let targetRow = targetRowOrRowid
123
+ if (XEUtils.isString(targetRowOrRowid) || XEUtils.isNumber(targetRowOrRowid)) {
124
+ const rowRest = fullAllDataRowIdData[targetRowOrRowid]
125
+ if (rowRest) {
126
+ targetRow = rowRest.row
127
+ }
128
+ }
129
+ const newRecords: any[] = reactive($xeTable.defineField(records.map((record: any) => Object.assign(treeConfig && transform ? { [mapChildrenField]: [], [childrenField]: [] } : {}, record))))
130
+ let treeRecords: any[] = []
131
+ if (treeConfig && transform) {
132
+ treeRecords = XEUtils.toArrayTree(newRecords, { key: rowField, parentKey: parentField, children: childrenField })
133
+ }
134
+ if (XEUtils.eqNull(targetRow)) {
135
+ // 如果为虚拟树
136
+ if (treeConfig && transform) {
137
+ insertTreeRow(newRecords, false)
138
+ } else if (isRowGroupStatus) {
139
+ // 如果分组
140
+ if (treeConfig) {
141
+ throw new Error(getI18n('vxe.error.noTree', ['insert']))
142
+ }
143
+ errLog(getI18n('vxe.error.noGroup', ['insert']))
144
+ // insertGroupRow(newRecords, false)
145
+ } else {
146
+ newRecords.forEach(item => {
147
+ const rowid = getRowid($xeTable, item)
148
+ const rest = { row: item, rowid, seq: -1, index: -1, _index: -1, $index: -1, treeIndex: -1, _tIndex: -1, items: afterFullData, parent: null, level: 0, height: 0, resizeHeight: 0, oTop: 0, expandHeight: 0 }
149
+ fullDataRowIdData[rowid] = rest
150
+ fullAllDataRowIdData[rowid] = rest
151
+ afterFullData.unshift(item)
152
+ tableFullData.unshift(item)
153
+ })
154
+ // 刷新单元格合并
155
+ mergeBodyList.forEach((mergeItem: any) => {
156
+ const { row: mergeRowIndex } = mergeItem
157
+ if (mergeRowIndex >= 0) {
158
+ mergeItem.row = mergeRowIndex + newRecords.length
159
+ }
160
+ })
161
+ $xeTable.handleClearStack()
162
+ }
163
+ } else {
164
+ if (targetRow === -1) {
165
+ // 如果为虚拟树
166
+ if (treeConfig && transform) {
167
+ insertTreeRow(newRecords, true)
168
+ } else if (isRowGroupStatus) {
169
+ // 如果分组
170
+ if (treeConfig) {
171
+ throw new Error(getI18n('vxe.error.noTree', ['insert']))
172
+ }
173
+ errLog(getI18n('vxe.error.noGroup', ['insert']))
174
+ // insertGroupRow(newRecords, true)
175
+ } else {
176
+ newRecords.forEach(item => {
177
+ const rowid = getRowid($xeTable, item)
178
+ const rest = { row: item, rowid, seq: -1, index: -1, _index: -1, treeIndex: -1, _tIndex: -1, $index: -1, items: afterFullData, parent: null, level: 0, height: 0, resizeHeight: 0, oTop: 0, expandHeight: 0 }
179
+ fullDataRowIdData[rowid] = rest
180
+ fullAllDataRowIdData[rowid] = rest
181
+ afterFullData.push(item)
182
+ tableFullData.push(item)
183
+ })
184
+ $xeTable.handleClearStack()
185
+ }
186
+ } else {
187
+ // 如果为虚拟树
188
+ if (treeConfig && transform) {
189
+ const matchMapObj = XEUtils.findTree(tableFullTreeData, item => targetRow[rowField] === item[rowField], { children: mapChildrenField })
190
+ if (matchMapObj) {
191
+ const { parent: parentRow } = matchMapObj
192
+ const parentMapChilds = parentRow ? parentRow[mapChildrenField] : tableFullTreeData
193
+ const parentRest = fullAllDataRowIdData[getRowid($xeTable, parentRow)]
194
+ const parentLevel = parentRest ? parentRest.level : 0
195
+ treeRecords.forEach((row, i) => {
196
+ if (parentRow) {
197
+ if (row[parentField] !== parentRow[rowField]) {
198
+ errLog('vxe.error.errProp', [`${parentField}=${row[parentField]}`, `${parentField}=${parentRow[rowField]}`])
199
+ row[parentField] = parentRow[rowField]
200
+ }
201
+ } else {
202
+ if (row[parentField] !== null) {
203
+ if (!XEUtils.eqNull(row[parentField])) {
204
+ errLog('vxe.error.errProp', [`${parentField}=${row[parentField]}`, 'null'])
205
+ }
206
+ row[parentField] = null
207
+ }
208
+ }
209
+ let targetIndex = matchMapObj.index + i
210
+ if (isInsertNextRow) {
211
+ targetIndex = targetIndex + 1
212
+ }
213
+ parentMapChilds.splice(targetIndex, 0, row)
214
+ })
215
+ XEUtils.eachTree(treeRecords, (item) => {
216
+ const rowid = getRowid($xeTable, item)
217
+ const rest = { row: item, rowid, seq: -1, index: -1, _index: -1, $index: -1, treeIndex: -1, _tIndex: -1, items: parentMapChilds, parent: parentRow, level: parentLevel + 1, height: 0, resizeHeight: 0, oTop: 0, expandHeight: 0 }
218
+ if (item[childrenField]) {
219
+ item[mapChildrenField] = item[childrenField]
220
+ }
221
+ fullDataRowIdData[rowid] = rest
222
+ fullAllDataRowIdData[rowid] = rest
223
+ }, { children: childrenField })
224
+ // 源
225
+ if (parentRow) {
226
+ const matchObj = XEUtils.findTree(tableFullTreeData, item => targetRow[rowField] === item[rowField], { children: childrenField })
227
+ if (matchObj) {
228
+ const parentChilds = matchObj.items
229
+ let targetIndex = matchObj.index
230
+ if (isInsertNextRow) {
231
+ targetIndex = targetIndex + 1
232
+ }
233
+ parentChilds.splice(targetIndex, 0, ...treeRecords)
234
+ }
235
+ }
236
+ $xeTable.handleClearStack()
237
+ } else {
238
+ warnLog('vxe.error.unableInsert')
239
+ insertTreeRow(newRecords, true)
240
+ }
241
+ } else if (isRowGroupStatus) {
242
+ // 如果分组
243
+ if (treeConfig) {
244
+ throw new Error(getI18n('vxe.error.noTree', ['insert']))
245
+ }
246
+ errLog(getI18n('vxe.error.noGroup', ['insert']))
247
+ } else {
248
+ if (treeConfig) {
249
+ throw new Error(getI18n('vxe.error.noTree', ['insert']))
250
+ }
251
+ let afIndex = -1
252
+ // 如果是可视索引
253
+ if (XEUtils.isNumber(targetRow)) {
254
+ if (targetRow < afterFullData.length) {
255
+ afIndex = targetRow
256
+ }
257
+ } else {
258
+ afIndex = $xeTable.findRowIndexOf(afterFullData, targetRow)
259
+ }
260
+ // 如果是插入指定行的下一行
261
+ if (isInsertNextRow) {
262
+ afIndex = Math.min(afterFullData.length, afIndex + 1)
263
+ }
264
+ if (afIndex === -1) {
265
+ throw new Error(getI18n('vxe.error.unableInsert'))
266
+ }
267
+ afterFullData.splice(afIndex, 0, ...newRecords)
268
+ const tfIndex = $xeTable.findRowIndexOf(tableFullData, targetRow)
269
+ if (tfIndex > -1) {
270
+ tableFullData.splice(tfIndex + (isInsertNextRow ? 1 : 0), 0, ...newRecords)
271
+ } else {
272
+ tableFullData.push(...newRecords)
273
+ }
274
+ // 刷新单元格合并
275
+ mergeBodyList.forEach((mergeItem: any) => {
276
+ const { row: mergeRowIndex, rowspan: mergeRowspan } = mergeItem
277
+ if (mergeRowIndex >= afIndex) {
278
+ mergeItem.row = mergeRowIndex + newRecords.length
279
+ } else if (isInsertNextRow ? (mergeRowIndex + mergeRowspan >= afIndex) : (mergeRowIndex + mergeRowspan > afIndex)) {
280
+ mergeItem.rowspan = mergeRowspan + newRecords.length
281
+ }
282
+ })
283
+ $xeTable.handleClearStack()
284
+ }
285
+ }
286
+ }
287
+
288
+ const handleStatus = (newRow: any) => {
289
+ const rowid = getRowid($xeTable, newRow)
290
+ // 如果是被删除的数据,则还原状态
291
+ if (removeRowMaps[rowid]) {
292
+ delete removeRowMaps[rowid]
293
+ if (insertRowMaps[rowid]) {
294
+ delete insertRowMaps[rowid]
295
+ }
296
+ } else {
297
+ insertRowMaps[rowid] = newRow
298
+ }
299
+ }
300
+ // 如果为虚拟树
301
+ if (treeConfig && transform) {
302
+ XEUtils.eachTree(treeRecords, handleStatus, { children: mapChildrenField })
303
+ } else {
304
+ newRecords.forEach(handleStatus)
305
+ }
306
+
307
+ reactData.removeRowFlag++
308
+ reactData.insertRowFlag++
309
+ $xeTable.cacheRowMap(false)
310
+ $xeTable.updateScrollYStatus()
311
+ $xeTable.handleTableData(treeConfig && transform)
312
+ if (!(treeConfig && transform)) {
313
+ $xeTable.updateAfterDataIndex()
314
+ }
315
+ $xeTable.updateFooter()
316
+ $xeTable.handleUpdateBodyMerge()
317
+ $xeTable.checkSelectionStatus()
318
+ if (reactData.scrollYLoad) {
319
+ $xeTable.updateScrollYSpace()
320
+ }
321
+ return nextTick().then(() => {
322
+ $xeTable.updateCellAreas()
323
+ return $xeTable.recalculate(true)
324
+ }).then(() => {
325
+ return {
326
+ row: newRecords.length ? newRecords[newRecords.length - 1] : null,
327
+ rows: newRecords
328
+ }
329
+ })
330
+ }
331
+
332
+ const handleInsertChildRowAt = (records: any, parentRowOrParentId: any, targetRow: any, isInsertNextRow?: boolean) => {
333
+ const { treeConfig } = props
334
+ const { fullAllDataRowIdData } = internalData
335
+ const treeOpts = computeTreeOpts.value
336
+ const { transform, rowField, parentField } = treeOpts
337
+ if (treeConfig && transform) {
338
+ if (!XEUtils.isArray(records)) {
339
+ records = [records]
340
+ }
341
+ let parentRow = parentRowOrParentId
342
+ if (XEUtils.isString(parentRowOrParentId) || XEUtils.isNumber(parentRowOrParentId)) {
343
+ const rowRest = fullAllDataRowIdData[parentRowOrParentId]
344
+ if (rowRest) {
345
+ parentRow = rowRest.row
346
+ }
347
+ }
348
+ return handleInsertRowAt(records.map((item: any) => Object.assign({}, item, { [parentField]: parentRow[rowField] })), targetRow, isInsertNextRow)
349
+ } else {
350
+ errLog('vxe.error.errProp', ['tree-config.transform=false', 'tree-config.transform=true'])
351
+ }
352
+ return Promise.resolve({ row: null, rows: [] })
353
+ }
354
+
355
+ const handleClearEdit = (evnt: Event | null, targetRow?: any) => {
356
+ const { editStore } = reactData
357
+ const { actived, focused } = editStore
358
+ const { row, column } = actived
359
+ const validOpts = computeValidOpts.value
360
+ if (row || column) {
361
+ if (targetRow && getRowid($xeTable, targetRow) !== getRowid($xeTable, row)) {
362
+ return nextTick()
363
+ }
364
+ syncActivedCell()
365
+ $xeTable.updateFooter()
366
+ actived.args = null
367
+ actived.row = null
368
+ actived.column = null
369
+ $xeTable.dispatchEvent('edit-closed', {
370
+ row,
371
+ rowIndex: $xeTable.getRowIndex(row),
372
+ $rowIndex: $xeTable.getVMRowIndex(row),
373
+ column,
374
+ columnIndex: $xeTable.getColumnIndex(column),
375
+ $columnIndex: $xeTable.getVMColumnIndex(column)
376
+ }, evnt || null)
377
+ }
378
+ focused.row = null
379
+ focused.column = null
380
+ if (validOpts.autoClear) {
381
+ if (validOpts.msgMode !== 'full' || getConfig().cellVaildMode === 'obsolete') {
382
+ if ($xeTable.clearValidate) {
383
+ return $xeTable.clearValidate()
384
+ }
385
+ }
386
+ }
387
+ return nextTick().then(() => $xeTable.updateCellAreas())
388
+ }
389
+
390
+ const handleEditActive = (params: any, evnt: Event | null, options: {
391
+ isClear?: boolean
392
+ isFocus?: boolean
393
+ isPos?: boolean
394
+ }) => {
395
+ const $xeGrid = $xeTable.xeGrid
396
+ const $xeGantt = $xeTable.xeGantt
397
+
398
+ const { editConfig, mouseConfig } = props
399
+ const { editStore, tableColumn } = reactData
400
+ const editOpts = computeEditOpts.value
401
+ const { mode } = editOpts
402
+ const { actived, focused } = editStore
403
+ const { row, column } = params
404
+ const { editRender } = column
405
+ const { isFocus, isPos, isClear } = options
406
+ const cell = (params.cell || $xeTable.getCellElement(row, column))
407
+ const beforeEditMethod = editOpts.beforeEditMethod || editOpts.activeMethod
408
+ params.cell = cell
409
+ if (cell && isEnableConf(editConfig) && isEnableConf(editRender)) {
410
+ // 激活编辑
411
+ if (!$xeTable.isPendingByRow(row) && !$xeTable.isAggregateRecord(row)) {
412
+ if (actived.row !== row || (mode === 'cell' ? actived.column !== column : false)) {
413
+ // 判断是否禁用编辑
414
+ let type: 'edit-disabled' | 'edit-activated' = 'edit-disabled'
415
+ if (!beforeEditMethod || beforeEditMethod({ ...params, $table: $xeTable, $grid: $xeGrid, $gantt: $xeGantt })) {
416
+ if (mouseConfig) {
417
+ $xeTable.clearSelected()
418
+ if ($xeTable.clearCellAreas) {
419
+ $xeTable.clearCellAreas()
420
+ $xeTable.clearCopyCellArea()
421
+ }
422
+ }
423
+ $xeTable.closeTooltip()
424
+ if (actived.column) {
425
+ handleClearEdit(evnt)
426
+ }
427
+ type = 'edit-activated'
428
+ column.renderHeight = cell.offsetHeight
429
+ actived.args = params
430
+ actived.row = row
431
+ actived.column = column
432
+ $xeTable.handlePushStack()
433
+ if (isClear) {
434
+ setCellValue(row, column, null)
435
+ }
436
+ if (mode === 'row') {
437
+ tableColumn.forEach((column: any) => getEditColumnModel(row, column))
438
+ } else {
439
+ getEditColumnModel(row, column)
440
+ }
441
+ const afterEditMethod = editOpts.afterEditMethod
442
+ nextTick(() => {
443
+ if (isFocus) {
444
+ $xeTable.handleFocus(params, evnt)
445
+ }
446
+ if (afterEditMethod) {
447
+ afterEditMethod({ ...params, $table: $xeTable, $grid: $xeGrid, $gantt: $xeGantt })
448
+ }
449
+ })
450
+ }
451
+ $xeTable.dispatchEvent(type, {
452
+ row,
453
+ rowIndex: $xeTable.getRowIndex(row),
454
+ $rowIndex: $xeTable.getVMRowIndex(row),
455
+ column,
456
+ columnIndex: $xeTable.getColumnIndex(column),
457
+ $columnIndex: $xeTable.getVMColumnIndex(column)
458
+ }, evnt)
459
+
460
+ // v4已废弃
461
+ if (type === 'edit-activated') {
462
+ $xeTable.dispatchEvent('edit-actived', {
463
+ row,
464
+ rowIndex: $xeTable.getRowIndex(row),
465
+ $rowIndex: $xeTable.getVMRowIndex(row),
466
+ column,
467
+ columnIndex: $xeTable.getColumnIndex(column),
468
+ $columnIndex: $xeTable.getVMColumnIndex(column)
469
+ }, evnt)
470
+ }
471
+ } else {
472
+ const { column: oldColumn } = actived
473
+ if (mouseConfig) {
474
+ $xeTable.clearSelected()
475
+ if ($xeTable.clearCellAreas) {
476
+ $xeTable.clearCellAreas()
477
+ $xeTable.clearCopyCellArea()
478
+ }
479
+ }
480
+ if (oldColumn && oldColumn !== column) {
481
+ const { model: oldModel } = oldColumn
482
+ if (oldModel.update) {
483
+ setCellValue(row, oldColumn, oldModel.value)
484
+ }
485
+ if ($xeTable.clearValidate) {
486
+ $xeTable.clearValidate(row, column)
487
+ }
488
+ }
489
+ column.renderHeight = cell.offsetHeight
490
+ actived.args = params
491
+ actived.column = column
492
+ if (isPos) {
493
+ setTimeout(() => {
494
+ $xeTable.handleFocus(params, evnt)
495
+ })
496
+ }
497
+ }
498
+ focused.column = null
499
+ focused.row = null
500
+ $xeTable.focus()
501
+ }
502
+ }
503
+ return nextTick()
504
+ }
505
+
506
+ const handleEditCell = (row: any, fieldOrColumn: string | VxeTableDefines.ColumnInfo | null, options: {
507
+ isClear?: boolean | undefined;
508
+ isFocus?: boolean | undefined;
509
+ isPos?: boolean | undefined;
510
+ }) => {
511
+ const { editConfig } = props
512
+ const { isPos } = options
513
+ const column = XEUtils.isString(fieldOrColumn) ? $xeTable.getColumnByField(fieldOrColumn) : fieldOrColumn
514
+ if (row && column && isEnableConf(editConfig) && isEnableConf(column.editRender) && !$xeTable.isAggregateRecord(row)) {
515
+ return Promise.resolve(isPos ? $xeTable.scrollToRow(row, column) : null).then(() => {
516
+ const cell = $xeTable.getCellElement(row, column)
517
+ if (cell) {
518
+ handleEditActive({
519
+ row,
520
+ rowIndex: $xeTable.getRowIndex(row),
521
+ column,
522
+ columnIndex: $xeTable.getColumnIndex(column),
523
+ cell,
524
+ $table: $xeTable
525
+ }, null, {
526
+ isFocus: isPos,
527
+ isPos
528
+ })
529
+ internalData._lastCallTime = Date.now()
530
+ }
531
+ return nextTick()
532
+ })
533
+ }
534
+ return nextTick()
535
+ }
536
+
537
+ editMethods = {
538
+ /**
539
+ * 往表格中插入临时数据
540
+ *
541
+ * @param {*} records
542
+ */
543
+ insert (records) {
544
+ return handleInsertRowAt(records, null)
545
+ },
546
+ /**
547
+ * 往表格指定行中插入临时数据
548
+ * 如果 row 为空则从插入到顶部,如果为树结构,则插入到目标节点顶部
549
+ * 如果 row 为 -1 则从插入到底部,如果为树结构,则插入到目标节点底部
550
+ * 如果 row 为有效行则插入到该行的位置,如果为树结构,则有插入到效的目标节点该行的位置
551
+ */
552
+ insertAt (records, targetRowOrRowid) {
553
+ return handleInsertRowAt(records, targetRowOrRowid)
554
+ },
555
+ insertNextAt (records, targetRowOrRowid) {
556
+ return handleInsertRowAt(records, targetRowOrRowid, true)
557
+ },
558
+ insertChild (records, parentRowOrParentId) {
559
+ (window as any).aa = internalData
560
+ return handleInsertChildRowAt(records, parentRowOrParentId, null)
561
+ },
562
+ insertChildAt (records, parentRowOrParentId, targetRow) {
563
+ return handleInsertChildRowAt(records, parentRowOrParentId, targetRow)
564
+ },
565
+ insertChildNextAt (records, parentRowOrParentId, targetRow) {
566
+ return handleInsertChildRowAt(records, parentRowOrParentId, targetRow, true)
567
+ },
568
+ /**
569
+ * 删除指定行数据
570
+ * 如果传 row 则删除一行
571
+ * 如果传 rows 则删除多行
572
+ * 如果为空则删除所有
573
+ */
574
+ remove (rows: any) {
575
+ const { treeConfig } = props
576
+ const { editStore, isRowGroupStatus } = reactData
577
+ const { tableFullTreeData, selectCheckboxMaps, afterFullData, mergeBodyList, tableFullData, pendingRowMaps, insertRowMaps, removeRowMaps } = internalData
578
+ const checkboxOpts = computeCheckboxOpts.value
579
+ const treeOpts = computeTreeOpts.value
580
+ const { transform, mapChildrenField } = treeOpts
581
+ const childrenField = treeOpts.children || treeOpts.childrenField
582
+ const { actived } = editStore
583
+ const { checkField } = checkboxOpts
584
+ let delList: any[] = []
585
+ if (!rows) {
586
+ rows = tableFullData
587
+ } else if (!XEUtils.isArray(rows)) {
588
+ rows = [rows]
589
+ }
590
+ // 如果是新增,则保存记录
591
+ rows.forEach((row: any) => {
592
+ if (!$xeTable.isInsertByRow(row)) {
593
+ const rowid = getRowid($xeTable, row)
594
+ removeRowMaps[rowid] = row
595
+ }
596
+ })
597
+ // 如果绑定了多选属性,则更新状态
598
+ if (!checkField) {
599
+ rows.forEach((row: any) => {
600
+ const rowid = getRowid($xeTable, row)
601
+ if (selectCheckboxMaps[rowid]) {
602
+ delete selectCheckboxMaps[rowid]
603
+ }
604
+ })
605
+ reactData.updateCheckboxFlag++
606
+ }
607
+ // 从数据源中移除
608
+ if (tableFullData === rows) {
609
+ rows = delList = tableFullData.slice(0)
610
+ internalData.tableFullData = []
611
+ internalData.afterFullData = []
612
+ $xeTable.clearMergeCells()
613
+ } else {
614
+ // 如果为虚拟树
615
+ if (treeConfig && transform) {
616
+ rows.forEach((row: any) => {
617
+ const rowid = getRowid($xeTable, row)
618
+ const matchMapObj = XEUtils.findTree(tableFullTreeData, item => rowid === getRowid($xeTable, item), { children: mapChildrenField })
619
+ if (matchMapObj) {
620
+ const rItems = matchMapObj.items.splice(matchMapObj.index, 1)
621
+ delList.push(rItems[0])
622
+ }
623
+ const matchObj = XEUtils.findTree(tableFullTreeData, item => rowid === getRowid($xeTable, item), { children: childrenField })
624
+ if (matchObj) {
625
+ matchObj.items.splice(matchObj.index, 1)
626
+ }
627
+ const afIndex = $xeTable.findRowIndexOf(afterFullData, row)
628
+ if (afIndex > -1) {
629
+ afterFullData.splice(afIndex, 1)
630
+ }
631
+ })
632
+ } else if (isRowGroupStatus) {
633
+ // 如果分组
634
+ warnLog(getI18n('vxe.error.noGroup', ['remove']))
635
+ } else {
636
+ rows.forEach((row: any) => {
637
+ const tfIndex = $xeTable.findRowIndexOf(tableFullData, row)
638
+ if (tfIndex > -1) {
639
+ const rItems = tableFullData.splice(tfIndex, 1)
640
+ delList.push(rItems[0])
641
+ }
642
+ const afIndex = $xeTable.findRowIndexOf(afterFullData, row)
643
+ if (afIndex > -1) {
644
+ // 刷新单元格合并
645
+ mergeBodyList.forEach((mergeItem) => {
646
+ const { row: mergeRowIndex, rowspan: mergeRowspan } = mergeItem
647
+ if (mergeRowIndex > afIndex) {
648
+ mergeItem.row = mergeRowIndex - 1
649
+ } else if (mergeRowIndex + mergeRowspan > afIndex) {
650
+ mergeItem.rowspan = mergeRowspan - 1
651
+ }
652
+ })
653
+ afterFullData.splice(afIndex, 1)
654
+ }
655
+ })
656
+ }
657
+ }
658
+ // 如果当前行被激活编辑,则清除激活状态
659
+ if (actived.row && $xeTable.findRowIndexOf(rows, actived.row) > -1) {
660
+ editMethods.clearEdit()
661
+ }
662
+ // 从新增中移除已删除的数据
663
+ rows.forEach((row: any) => {
664
+ const rowid = getRowid($xeTable, row)
665
+ if (insertRowMaps[rowid]) {
666
+ delete insertRowMaps[rowid]
667
+ }
668
+ if (pendingRowMaps[rowid]) {
669
+ delete pendingRowMaps[rowid]
670
+ }
671
+ })
672
+ reactData.removeRowFlag++
673
+ reactData.insertRowFlag++
674
+ reactData.pendingRowFlag++
675
+ $xeTable.handleClearStack()
676
+ $xeTable.cacheRowMap(false)
677
+ $xeTable.handleTableData(treeConfig && transform)
678
+ $xeTable.updateFooter()
679
+ $xeTable.handleUpdateBodyMerge()
680
+ if (!(treeConfig && transform)) {
681
+ $xeTable.updateAfterDataIndex()
682
+ }
683
+ $xeTable.checkSelectionStatus()
684
+ if (reactData.scrollYLoad) {
685
+ $xeTable.updateScrollYSpace()
686
+ }
687
+ return nextTick().then(() => {
688
+ $xeTable.updateCellAreas()
689
+ return $xeTable.recalculate(true)
690
+ }).then(() => {
691
+ return { row: delList.length ? delList[delList.length - 1] : null, rows: delList }
692
+ })
693
+ },
694
+ /**
695
+ * 删除复选框选中的数据
696
+ */
697
+ removeCheckboxRow () {
698
+ return editMethods.remove($xeTable.getCheckboxRecords()).then((params: any) => {
699
+ $xeTable.clearCheckboxRow()
700
+ return params
701
+ })
702
+ },
703
+ /**
704
+ * 删除单选框选中的数据
705
+ */
706
+ removeRadioRow () {
707
+ const radioRecord = $xeTable.getRadioRecord()
708
+ return editMethods.remove(radioRecord || []).then((params: any) => {
709
+ $xeTable.clearRadioRow()
710
+ return params
711
+ })
712
+ },
713
+ /**
714
+ * 删除当前行选中的数据
715
+ */
716
+ removeCurrentRow () {
717
+ const currentRecord = $xeTable.getCurrentRecord()
718
+ return editMethods.remove(currentRecord || []).then((params: any) => {
719
+ $xeTable.clearCurrentRow()
720
+ return params
721
+ })
722
+ },
723
+ /**
724
+ * 获取表格数据集,包含新增、删除、修改、标记
725
+ */
726
+ getRecordset () {
727
+ const removeRecords = editMethods.getRemoveRecords()
728
+ const pendingRecords = $xeTable.getPendingRecords()
729
+ const delRecords = removeRecords.concat(pendingRecords)
730
+ // 如果已经被删除,则无需放到更新数组
731
+ const updateRecords = editMethods.getUpdateRecords().filter(row => {
732
+ return !delRecords.some(item => $xeTable.eqRow(item, row))
733
+ })
734
+ return {
735
+ insertRecords: editMethods.getInsertRecords(),
736
+ removeRecords,
737
+ updateRecords,
738
+ pendingRecords
739
+ }
740
+ },
741
+ /**
742
+ * 获取新增的临时数据
743
+ */
744
+ getInsertRecords () {
745
+ const { fullAllDataRowIdData, insertRowMaps } = internalData
746
+ const insertRecords: any[] = []
747
+ XEUtils.each(insertRowMaps, (row, rowid) => {
748
+ if (fullAllDataRowIdData[rowid]) {
749
+ insertRecords.push(row)
750
+ }
751
+ })
752
+ return insertRecords
753
+ },
754
+ /**
755
+ * 获取已删除的数据
756
+ */
757
+ getRemoveRecords () {
758
+ const { removeRowMaps } = internalData
759
+ const removeRecords: any[] = []
760
+ XEUtils.each(removeRowMaps, (row) => {
761
+ removeRecords.push(row)
762
+ })
763
+ return removeRecords
764
+ },
765
+ /**
766
+ * 获取更新数据
767
+ * 只精准匹配 row 的更改
768
+ * 如果是树表格,子节点更改状态不会影响父节点的更新状态
769
+ */
770
+ getUpdateRecords () {
771
+ const { keepSource, treeConfig } = props
772
+ const { tableFullData } = internalData
773
+ const treeOpts = computeTreeOpts.value
774
+ if (keepSource) {
775
+ syncActivedCell()
776
+ if (treeConfig) {
777
+ return XEUtils.filterTree(tableFullData, row => $xeTable.isUpdateByRow(row), treeOpts)
778
+ }
779
+ return tableFullData.filter((row: any) => $xeTable.isUpdateByRow(row))
780
+ }
781
+ return []
782
+ },
783
+ getActiveRecord () {
784
+ warnLog('vxe.error.delFunc', ['getActiveRecord', 'getEditCell'])
785
+ const { editStore } = reactData
786
+ const { fullAllDataRowIdData } = internalData
787
+ const { args, row } = editStore.actived
788
+ if (args && row && fullAllDataRowIdData[getRowid($xeTable, row)]) {
789
+ return Object.assign({}, args, { row })
790
+ }
791
+ return null
792
+ },
793
+ getEditRecord () {
794
+ warnLog('vxe.error.delFunc', ['getEditRecord', 'getEditCell'])
795
+ const { editStore } = reactData
796
+ const { fullAllDataRowIdData } = internalData
797
+ const { args, row } = editStore.actived
798
+ if (args && row && fullAllDataRowIdData[getRowid($xeTable, row)]) {
799
+ return Object.assign({}, args, { row })
800
+ }
801
+ return null
802
+ },
803
+ getEditCell () {
804
+ const { editStore } = reactData
805
+ const { row, column } = editStore.actived
806
+ if (column && row) {
807
+ return {
808
+ row,
809
+ rowIndex: $xeTable.getRowIndex(row),
810
+ column,
811
+ columnIndex: $xeTable.getColumnIndex(column)
812
+ }
813
+ }
814
+ return null
815
+ },
816
+ /**
817
+ * 获取选中的单元格
818
+ */
819
+ getSelectedCell () {
820
+ const { editStore } = reactData
821
+ const { row, column } = editStore.selected
822
+ if (row && column) {
823
+ return {
824
+ row,
825
+ column
826
+ }
827
+ }
828
+ return null
829
+ },
830
+ clearActived (row) {
831
+ // 即将废弃
832
+ warnLog('vxe.error.delFunc', ['clearActived', 'clearEdit'])
833
+ return $xeTable.clearEdit(row)
834
+ },
835
+ /**
836
+ * 清除激活的编辑
837
+ */
838
+ clearEdit (row) {
839
+ return handleClearEdit(null, row)
840
+ },
841
+ /**
842
+ * 清除所选中源状态
843
+ */
844
+ clearSelected () {
845
+ const { editStore } = reactData
846
+ const { selected } = editStore
847
+ selected.row = null
848
+ selected.column = null
849
+ removeCellSelectedClass()
850
+ return nextTick()
851
+ },
852
+ isActiveByRow (row) {
853
+ warnLog('vxe.error.delFunc', ['isActiveByRow', 'isEditByRow'])
854
+ // 即将废弃
855
+ return $xeTable.isEditByRow(row)
856
+ },
857
+ /**
858
+ * 判断行是否为激活编辑状态
859
+ * @param {Row} row 行对象
860
+ */
861
+ isEditByRow (row) {
862
+ const { editStore } = reactData
863
+ return editStore.actived.row === row
864
+ },
865
+ setActiveRow (row) {
866
+ warnLog('vxe.error.delFunc', ['setActiveRow', 'setEditRow'])
867
+ // 即将废弃
868
+ return editMethods.setEditRow(row)
869
+ },
870
+ /**
871
+ * 激活行编辑
872
+ */
873
+ setEditRow (row, fieldOrColumn, options) {
874
+ const { visibleColumn } = internalData
875
+ let column: any = XEUtils.find(visibleColumn, column => isEnableConf(column.editRender))
876
+ let isPos = false
877
+ if (fieldOrColumn) {
878
+ isPos = true
879
+ if (fieldOrColumn !== true) {
880
+ column = XEUtils.isString(fieldOrColumn) ? $xeTable.getColumnByField(fieldOrColumn) : fieldOrColumn
881
+ }
882
+ }
883
+ return handleEditCell(row, column, Object.assign({
884
+ isPos,
885
+ isFocus: isPos
886
+ }, options))
887
+ },
888
+ setActiveCell (row, fieldOrColumn) {
889
+ warnLog('vxe.error.delFunc', ['setActiveCell', 'setEditCell'])
890
+ // 即将废弃
891
+ return editMethods.setEditCell(row, fieldOrColumn)
892
+ },
893
+ /**
894
+ * 激活单元格编辑
895
+ */
896
+ setEditCell (row, fieldOrColumn, options) {
897
+ return handleEditCell(row, fieldOrColumn, Object.assign({
898
+ isFocus: true,
899
+ isPos: true
900
+ }, options))
901
+ },
902
+ /**
903
+ * 只对 trigger=dblclick 有效,选中单元格
904
+ */
905
+ setSelectCell (row, fieldOrColumn) {
906
+ const { tableData } = reactData
907
+ const editOpts = computeEditOpts.value
908
+ const column = XEUtils.isString(fieldOrColumn) ? $xeTable.getColumnByField(fieldOrColumn) : fieldOrColumn
909
+ if (row && column && editOpts.trigger !== 'manual') {
910
+ const rowIndex = $xeTable.findRowIndexOf(tableData, row)
911
+ if (rowIndex > -1 && column) {
912
+ const cell = $xeTable.getCellElement(row, column)
913
+ const params = {
914
+ row,
915
+ rowIndex,
916
+ column,
917
+ columnIndex: $xeTable.getColumnIndex(column),
918
+ cell
919
+ }
920
+ $xeTable.handleSelected(params, {})
921
+ }
922
+ }
923
+ return nextTick()
924
+ }
925
+ }
926
+
927
+ editPrivateMethods = {
928
+ /**
929
+ * 处理激活编辑
930
+ */
931
+ handleEdit (params, evnt, options) {
932
+ return handleEditActive(params, evnt, Object.assign({
933
+ isFocus: true,
934
+ isPos: true
935
+ }, options))
936
+ },
937
+ /**
938
+ * @deprecated
939
+ */
940
+ handleActived (params, evnt) {
941
+ return editPrivateMethods.handleEdit(params, evnt)
942
+ },
943
+ /**
944
+ * 处理取消编辑
945
+ * @param evnt
946
+ * @returns
947
+ */
948
+ handleClearEdit,
949
+ /**
950
+ * 处理聚焦
951
+ */
952
+ handleFocus (params) {
953
+ const { row, column, cell } = params
954
+ const { editRender } = column
955
+ const editOpts = computeEditOpts.value
956
+ if (isEnableConf(editRender)) {
957
+ const compRender = renderer.get(editRender.name)
958
+ let autoFocus = editRender.autofocus || editRender.autoFocus
959
+ let autoSelect = editRender.autoSelect || editRender.autoselect
960
+ let inputElem
961
+ // 是否启用聚焦
962
+ if (editOpts.autoFocus) {
963
+ if (!autoFocus && compRender) {
964
+ autoFocus = compRender.tableAutoFocus || compRender.tableAutofocus || compRender.autofocus
965
+ }
966
+ if (!autoSelect && compRender) {
967
+ autoSelect = compRender.tableAutoSelect || compRender.autoselect
968
+ }
969
+ // 如果指定了聚焦 class
970
+ if (XEUtils.isFunction(autoFocus)) {
971
+ inputElem = autoFocus(params)
972
+ } else if (autoFocus) {
973
+ if (autoFocus === true) {
974
+ // 自动匹配模式,会自动匹配第一个可输入元素
975
+ inputElem = cell.querySelector('input,textarea')
976
+ } else {
977
+ inputElem = cell.querySelector(autoFocus)
978
+ }
979
+ if (inputElem) {
980
+ inputElem.focus()
981
+ }
982
+ }
983
+ }
984
+ if (inputElem) {
985
+ if (autoSelect) {
986
+ inputElem.select()
987
+ } else {
988
+ // 保持一致行为,光标移到末端
989
+ if (browseObj.msie) {
990
+ const textRange = inputElem.createTextRange()
991
+ textRange.collapse(false)
992
+ textRange.select()
993
+ }
994
+ }
995
+ } else {
996
+ // 是否自动定位
997
+ if (editOpts.autoPos) {
998
+ if (!column.fixed) {
999
+ // 显示到可视区中
1000
+ $xeTable.scrollToRow(row, column)
1001
+ }
1002
+ }
1003
+ }
1004
+ }
1005
+ },
1006
+ /**
1007
+ * 处理选中源
1008
+ */
1009
+ handleSelected (params, evnt) {
1010
+ const { mouseConfig } = props
1011
+ const { editStore } = reactData
1012
+ const mouseOpts = computeMouseOpts.value
1013
+ const editOpts = computeEditOpts.value
1014
+ const { actived, selected } = editStore
1015
+ const { row, column } = params
1016
+ const isMouseSelected = mouseConfig && mouseOpts.selected
1017
+ const selectMethod = () => {
1018
+ if (isMouseSelected && (selected.row !== row || selected.column !== column)) {
1019
+ if (actived.row !== row || (editOpts.mode === 'cell' ? actived.column !== column : false)) {
1020
+ handleClearEdit(evnt)
1021
+ $xeTable.clearSelected()
1022
+ if ($xeTable.clearCellAreas) {
1023
+ $xeTable.clearCellAreas()
1024
+ $xeTable.clearCopyCellArea()
1025
+ }
1026
+ selected.args = params
1027
+ selected.row = row
1028
+ selected.column = column
1029
+ if (isMouseSelected) {
1030
+ editPrivateMethods.addCellSelectedClass()
1031
+ }
1032
+ $xeTable.focus()
1033
+ if (evnt) {
1034
+ $xeTable.dispatchEvent('cell-selected', params, evnt)
1035
+ }
1036
+ }
1037
+ }
1038
+ return nextTick()
1039
+ }
1040
+ return selectMethod()
1041
+ },
1042
+ addCellSelectedClass () {
1043
+ const { editStore } = reactData
1044
+ const { selected } = editStore
1045
+ const { row, column } = selected
1046
+ removeCellSelectedClass()
1047
+ if (row && column) {
1048
+ const cell = $xeTable.getCellElement(row, column)
1049
+ if (cell) {
1050
+ addClass(cell, 'col--selected')
1051
+ }
1052
+ }
1053
+ }
1054
+ }
1055
+
1056
+ return { ...editMethods, ...editPrivateMethods }
1057
+ },
1058
+ setupGrid ($xeGrid) {
1059
+ return $xeGrid.extendTableMethods(tableEditMethodKeys)
1060
+ },
1061
+ setupGantt ($xeGantt) {
1062
+ return $xeGantt.extendTableMethods(tableEditMethodKeys)
1063
+ }
1064
+ })