Fixed #6671 - maxSelectedLabels for TreeSelect

pull/6697/head
tugcekucukoglu 2024-10-31 16:56:36 +03:00
parent 4949d22eb9
commit 2ffe80f4f3
3 changed files with 83 additions and 37 deletions

View File

@ -23,6 +23,14 @@ export default {
type: String, type: String,
default: 'single' default: 'single'
}, },
selectedItemsLabel: {
type: String,
default: null
},
maxSelectedLabels: {
type: Number,
default: null
},
appendTo: { appendTo: {
type: [String, Object], type: [String, Object],
default: 'body' default: 'body'

View File

@ -207,33 +207,6 @@ export interface TreeSelectProps {
* @defaultValue 20rem * @defaultValue 20rem
*/ */
scrollHeight?: string | undefined; scrollHeight?: string | undefined;
/**
* Label to display when there are no selections.
*/
placeholder?: string | undefined;
/**
* Defines the size of the component.
*/
size?: 'small' | 'large' | undefined;
/**
* When present, it specifies that the component should have invalid state style.
* @defaultValue false
*/
invalid?: boolean | undefined;
/**
* When present, it specifies that the component should be disabled.
* @defaultValue false
*/
disabled?: boolean | undefined;
/**
* Specifies the input variant of the component.
* @defaultValue outlined
*/
variant?: 'outlined' | 'filled' | undefined;
/**
* Index of the element in tabbing order.
*/
tabindex?: string | undefined;
/** /**
* Defines the selection mode. * Defines the selection mode.
*/ */
@ -248,16 +221,20 @@ export interface TreeSelectProps {
* @defaultValue body * @defaultValue body
*/ */
appendTo?: HintedString<'body' | 'self'> | undefined | HTMLElement; appendTo?: HintedString<'body' | 'self'> | undefined | HTMLElement;
/**
* Text to display when there are no options available. Defaults to value from PrimeVue locale configuration.
* @defaultValue No available options
*/
emptyMessage?: string | undefined;
/** /**
* Defines how the selected items are displayed. * Defines how the selected items are displayed.
* @defaultValue comma * @defaultValue comma
*/ */
display?: 'comma' | 'chip' | undefined; display?: 'comma' | 'chip' | undefined;
/**
* Label to display after exceeding max selected labels.
* @defaultValue null
*/
selectedItemsLabel?: string | undefined;
/**
* Decides how many selected item labels to show at most.
*/
maxSelectedLabels?: number | undefined;
/** /**
* Defines how multiple items can be selected, when true metaKey needs to be pressed to select or unselect an item and when set to false selection of each item can be toggled individually. * Defines how multiple items can be selected, when true metaKey needs to be pressed to select or unselect an item and when set to false selection of each item can be toggled individually.
* On touch enabled devices, metaKeySelection is turned off automatically. * On touch enabled devices, metaKeySelection is turned off automatically.
@ -301,6 +278,38 @@ export interface TreeSelectProps {
* Locale to use in filtering. The default locale is the host environment's current locale. * Locale to use in filtering. The default locale is the host environment's current locale.
*/ */
filterLocale?: string | undefined; filterLocale?: string | undefined;
/**
* Text to display when there are no options available. Defaults to value from PrimeVue locale configuration.
* @defaultValue No available options
*/
emptyMessage?: string | undefined;
/**
* Label to display when there are no selections.
*/
placeholder?: string | undefined;
/**
* Defines the size of the component.
*/
size?: 'small' | 'large' | undefined;
/**
* When present, it specifies that the component should have invalid state style.
* @defaultValue false
*/
invalid?: boolean | undefined;
/**
* When present, it specifies that the component should be disabled.
* @defaultValue false
*/
disabled?: boolean | undefined;
/**
* Specifies the input variant of the component.
* @defaultValue outlined
*/
variant?: 'outlined' | 'filled' | undefined;
/**
* Index of the element in tabbing order.
*/
tabindex?: string | undefined;
/** /**
* Identifier of the underlying input element. * Identifier of the underlying input element.
*/ */

View File

@ -29,10 +29,15 @@
{{ label || 'empty' }} {{ label || 'empty' }}
</template> </template>
<template v-else-if="display === 'chip'"> <template v-else-if="display === 'chip'">
<div v-for="node of selectedNodes" :key="node.key" :class="cx('chipItem')" v-bind="ptm('chipItem')"> <template v-if="chipSelectedItems">
<Chip :class="cx('pcChip')" :label="node.label" :unstyled="unstyled" :pt="ptm('pcChip')" /> <span>{{ label }}</span>
</div> </template>
<template v-if="emptyValue">{{ placeholder || 'empty' }}</template> <template v-else>
<div v-for="node of selectedNodes" :key="node.key" :class="cx('chipItem')" v-bind="ptm('chipItem')">
<Chip :class="cx('pcChip')" :label="node.label" :unstyled="unstyled" :pt="ptm('pcChip')" />
</div>
<template v-if="emptyValue">{{ placeholder || 'empty' }}</template>
</template>
</template> </template>
</slot> </slot>
</div> </div>
@ -253,6 +258,16 @@ export default {
this.$emit('update:expandedKeys', this.d_expandedKeys); this.$emit('update:expandedKeys', this.d_expandedKeys);
}, },
getSelectedItemsLabel() {
let pattern = /{(.*?)}/;
const selectedItemsLabel = this.selectedItemsLabel || this.$primevue.config.locale.selectionMessage;
if (pattern.test(selectedItemsLabel)) {
return selectedItemsLabel.replace(selectedItemsLabel.match(pattern)[0], Object.keys(this.d_value).length + '');
}
return selectedItemsLabel;
},
onFirstHiddenFocus(event) { onFirstHiddenFocus(event) {
const focusableEl = event.relatedTarget === this.$refs.focusInput ? getFirstFocusableElement(this.overlay, ':not([data-p-hidden-focusable="true"])') : this.$refs.focusInput; const focusableEl = event.relatedTarget === this.$refs.focusInput ? getFirstFocusableElement(this.overlay, ':not([data-p-hidden-focusable="true"])') : this.$refs.focusInput;
@ -517,8 +532,22 @@ export default {
}, },
label() { label() {
let value = this.selectedNodes; let value = this.selectedNodes;
let label;
return value.length ? value.map((node) => node.label).join(', ') : this.placeholder; if (value.length) {
if (isNotEmpty(this.maxSelectedLabels) && value.length > this.maxSelectedLabels) {
label = this.getSelectedItemsLabel();
} else {
label = value.map((node) => node.label).join(', ');
}
} else {
label = this.placeholder;
}
return label;
},
chipSelectedItems() {
return isNotEmpty(this.maxSelectedLabels) && this.d_value && Object.keys(this.d_value).length > this.maxSelectedLabels;
}, },
emptyMessageText() { emptyMessageText() {
return this.emptyMessage || this.$primevue.config.locale.emptyMessage; return this.emptyMessage || this.$primevue.config.locale.emptyMessage;