Skip to content

Commit d813685

Browse files
committed
primefaces#4273 Add support for dataKey on TreeTable
1 parent 170f4c3 commit d813685

File tree

6 files changed

+59
-29
lines changed

6 files changed

+59
-29
lines changed

api-generator/components/treetable.js

+6
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,12 @@ const TreeTableProps = [
55
default: 'null',
66
description: 'An array of treenodes.'
77
},
8+
{
9+
name: 'dataKey',
10+
type: 'string|function',
11+
default: 'null',
12+
description: 'Name of the field that uniquely identifies the a record in the data.'
13+
},
814
{
915
name: 'expandedKeys',
1016
type: 'array',

components/lib/treetable/BaseTreeTable.vue

+4
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ export default {
1010
type: null,
1111
default: null
1212
},
13+
dataKey: {
14+
type: [String, Function],
15+
default: 'key'
16+
},
1317
expandedKeys: {
1418
type: null,
1519
default: null

components/lib/treetable/TreeTable.d.ts

+5
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,11 @@ export interface TreeTableProps {
391391
* An array of treenodes.
392392
*/
393393
value?: TreeNode[] | undefined;
394+
/**
395+
* Name of the field that uniquely identifies the a record in the data.
396+
* @defaultValue "key"
397+
*/
398+
dataKey?: string | ((item: any) => string) | undefined;
394399
/**
395400
* A map of keys to represent the state of the tree expansion state in controlled mode.
396401
* @see TreeTableExpandedKeys

components/lib/treetable/TreeTable.vue

+14-9
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,8 @@
8383
<template v-if="!empty">
8484
<TTRow
8585
v-for="(node, index) of dataToRender"
86-
:key="node.key"
86+
:key="nodeKey(node)"
87+
:dataKey="dataKey"
8788
:columns="columns"
8889
:node="node"
8990
:level="0"
@@ -252,8 +253,7 @@ export default {
252253
};
253254
},
254255
onNodeToggle(node) {
255-
const key = node.key;
256-
256+
const key = this.nodeKey(node);
257257
if (this.d_expandedKeys[key]) {
258258
delete this.d_expandedKeys[key];
259259
this.$emit('node-collapse', node);
@@ -273,9 +273,13 @@ export default {
273273
this.$emit('update:selectionKeys', _selectionKeys);
274274
}
275275
},
276+
nodeKey(node) {
277+
return ObjectUtils.resolveFieldData(node, this.dataKey);
278+
},
276279
handleSelectionWithMetaKey(event) {
277280
const originalEvent = event.originalEvent;
278281
const node = event.node;
282+
const nodeKey = this.nodeKey(node);
279283
const metaKey = originalEvent.metaKey || originalEvent.ctrlKey;
280284
const selected = this.isNodeSelected(node);
281285
let _selectionKeys;
@@ -285,7 +289,7 @@ export default {
285289
_selectionKeys = {};
286290
} else {
287291
_selectionKeys = { ...this.selectionKeys };
288-
delete _selectionKeys[node.key];
292+
delete _selectionKeys[nodeKey];
289293
}
290294
291295
this.$emit('node-unselect', node);
@@ -296,14 +300,15 @@ export default {
296300
_selectionKeys = !metaKey ? {} : this.selectionKeys ? { ...this.selectionKeys } : {};
297301
}
298302
299-
_selectionKeys[node.key] = true;
303+
_selectionKeys[nodeKey] = true;
300304
this.$emit('node-select', node);
301305
}
302306
303307
return _selectionKeys;
304308
},
305309
handleSelectionWithoutMetaKey(event) {
306310
const node = event.node;
311+
const nodeKey = this.nodeKey(node);
307312
const selected = this.isNodeSelected(node);
308313
let _selectionKeys;
309314
@@ -313,18 +318,18 @@ export default {
313318
this.$emit('node-unselect', node);
314319
} else {
315320
_selectionKeys = {};
316-
_selectionKeys[node.key] = true;
321+
_selectionKeys[nodeKey] = true;
317322
this.$emit('node-select', node);
318323
}
319324
} else {
320325
if (selected) {
321326
_selectionKeys = { ...this.selectionKeys };
322-
delete _selectionKeys[node.key];
327+
delete _selectionKeys[nodeKey];
323328
324329
this.$emit('node-unselect', node);
325330
} else {
326331
_selectionKeys = this.selectionKeys ? { ...this.selectionKeys } : {};
327-
_selectionKeys[node.key] = true;
332+
_selectionKeys[nodeKey] = true;
328333
329334
this.$emit('node-select', node);
330335
}
@@ -572,7 +577,7 @@ export default {
572577
return matched;
573578
},
574579
isNodeSelected(node) {
575-
return this.selectionMode && this.selectionKeys ? this.selectionKeys[node.key] === true : false;
580+
return this.selectionMode && this.selectionKeys ? this.selectionKeys[this.nodeKey(node)] === true : false;
576581
},
577582
isNodeLeaf(node) {
578583
return node.leaf === false ? false : !(node.children && node.children.length);

components/lib/treetable/TreeTableRow.vue

+27-19
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,8 @@
4141
<template v-if="expanded && node.children && node.children.length">
4242
<TreeTableRow
4343
v-for="childNode of node.children"
44-
:key="childNode.key"
44+
:key="nodeKey(childNode)"
45+
:dataKey="dataKey"
4546
:columns="columns"
4647
:node="childNode"
4748
:parentNode="node"
@@ -76,6 +77,10 @@ export default {
7677
type: null,
7778
default: null
7879
},
80+
dataKey: {
81+
type: [String, Function],
82+
default: 'key'
83+
},
7984
parentNode: {
8085
type: null,
8186
default: null
@@ -150,6 +155,9 @@ export default {
150155
onTouchEnd() {
151156
this.nodeTouched = true;
152157
},
158+
nodeKey(node) {
159+
return ObjectUtils.resolveFieldData(node, this.dataKey);
160+
},
153161
onKeyDown(event, item) {
154162
switch (event.code) {
155163
case 'ArrowDown':
@@ -320,8 +328,8 @@ export default {
320328
});
321329
},
322330
propagateDown(node, check, selectionKeys) {
323-
if (check) selectionKeys[node.key] = { checked: true, partialChecked: false };
324-
else delete selectionKeys[node.key];
331+
if (check) selectionKeys[this.nodeKey(node)] = { checked: true, partialChecked: false };
332+
else delete selectionKeys[this.nodeKey(node)];
325333
326334
if (node.children && node.children.length) {
327335
for (let child of node.children) {
@@ -336,19 +344,19 @@ export default {
336344
let childPartialSelected = false;
337345
338346
for (let child of this.node.children) {
339-
if (_selectionKeys[child.key] && _selectionKeys[child.key].checked) checkedChildCount++;
340-
else if (_selectionKeys[child.key] && _selectionKeys[child.key].partialChecked) childPartialSelected = true;
347+
if (_selectionKeys[this.nodeKey(child)] && _selectionKeys[this.nodeKey(child)].checked) checkedChildCount++;
348+
else if (_selectionKeys[this.nodeKey(child)] && _selectionKeys[this.nodeKey(child)].partialChecked) childPartialSelected = true;
341349
}
342350
343351
if (check && checkedChildCount === this.node.children.length) {
344-
_selectionKeys[this.node.key] = { checked: true, partialChecked: false };
352+
_selectionKeys[this.nodeKey(this.node)] = { checked: true, partialChecked: false };
345353
} else {
346354
if (!check) {
347-
delete _selectionKeys[this.node.key];
355+
delete _selectionKeys[this.nodeKey(this.node)];
348356
}
349357
350-
if (childPartialSelected || (checkedChildCount > 0 && checkedChildCount !== this.node.children.length)) _selectionKeys[this.node.key] = { checked: false, partialChecked: true };
351-
else _selectionKeys[this.node.key] = { checked: false, partialChecked: false };
358+
if (childPartialSelected || (checkedChildCount > 0 && checkedChildCount !== this.node.children.length)) _selectionKeys[this.nodeKey(this.node)] = { checked: false, partialChecked: true };
359+
else _selectionKeys[this.nodeKey(this.node)] = { checked: false, partialChecked: false };
352360
}
353361
354362
this.$emit('checkbox-change', {
@@ -364,19 +372,19 @@ export default {
364372
let childPartialSelected = false;
365373
366374
for (let child of this.node.children) {
367-
if (_selectionKeys[child.key] && _selectionKeys[child.key].checked) checkedChildCount++;
368-
else if (_selectionKeys[child.key] && _selectionKeys[child.key].partialChecked) childPartialSelected = true;
375+
if (_selectionKeys[this.nodeKey(child)] && _selectionKeys[this.nodeKey(child)].checked) checkedChildCount++;
376+
else if (_selectionKeys[this.nodeKey(child)] && _selectionKeys[this.nodeKey(child)].partialChecked) childPartialSelected = true;
369377
}
370378
371379
if (check && checkedChildCount === this.node.children.length) {
372-
_selectionKeys[this.node.key] = { checked: true, partialChecked: false };
380+
_selectionKeys[this.nodeKey(this.node)] = { checked: true, partialChecked: false };
373381
} else {
374382
if (!check) {
375-
delete _selectionKeys[this.node.key];
383+
delete _selectionKeys[this.nodeKey(this.node)];
376384
}
377385
378-
if (childPartialSelected || (checkedChildCount > 0 && checkedChildCount !== this.node.children.length)) _selectionKeys[this.node.key] = { checked: false, partialChecked: true };
379-
else _selectionKeys[this.node.key] = { checked: false, partialChecked: false };
386+
if (childPartialSelected || (checkedChildCount > 0 && checkedChildCount !== this.node.children.length)) _selectionKeys[this.nodeKey(this.node)] = { checked: false, partialChecked: true };
387+
else _selectionKeys[this.nodeKey(this.node)] = { checked: false, partialChecked: false };
380388
}
381389
382390
this.$emit('checkbox-change', {
@@ -402,19 +410,19 @@ export default {
402410
return [this.node.styleClass, this.cx('row')];
403411
},
404412
expanded() {
405-
return this.expandedKeys && this.expandedKeys[this.node.key] === true;
413+
return this.expandedKeys && this.expandedKeys[this.nodeKey(this.node)] === true;
406414
},
407415
leaf() {
408416
return this.node.leaf === false ? false : !(this.node.children && this.node.children.length);
409417
},
410418
selected() {
411-
return this.selectionMode && this.selectionKeys ? this.selectionKeys[this.node.key] === true : false;
419+
return this.selectionMode && this.selectionKeys ? this.selectionKeys[this.nodeKey(this.node)] === true : false;
412420
},
413421
checked() {
414-
return this.selectionKeys ? this.selectionKeys[this.node.key] && this.selectionKeys[this.node.key].checked : false;
422+
return this.selectionKeys ? this.selectionKeys[this.nodeKey(this.node)] && this.selectionKeys[this.nodeKey(this.node)].checked : false;
415423
},
416424
partialChecked() {
417-
return this.selectionKeys ? this.selectionKeys[this.node.key] && this.selectionKeys[this.node.key].partialChecked : false;
425+
return this.selectionKeys ? this.selectionKeys[this.nodeKey(this.node)] && this.selectionKeys[this.nodeKey(this.node)].partialChecked : false;
418426
},
419427
getAriaSelected() {
420428
return this.selectionMode === 'single' || this.selectionMode === 'multiple' ? this.selected : null;

doc/treetable/selection/CheckboxRowSelectionDoc.vue

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
<template>
22
<DocSectionText v-bind="$attrs">
33
<p>Selection of multiple nodes via checkboxes is enabled by configuring <i>selectionMode</i> as <i>checkbox</i>.</p>
4-
<p>In checkbox selection mode, value binding should be a key-value pair where key is the node key and value is an object that has <i>checked</i> and <i>partialChecked</i> properties to represent the checked state of a node.</p>
4+
<p>
5+
In checkbox selection mode, value binding should be a key-value pair where key (or the dataKey) is the node key and value is an object that has <i>checked</i> and <i>partialChecked</i> properties to represent the checked state of a node.
6+
</p>
57
</DocSectionText>
68
<DocSectionCode :code="introCode" hideToggleCode importCode hideCodeSandbox hideStackBlitz />
79
<div class="card">

0 commit comments

Comments
 (0)