Newer
Older
:class="{ multiple }"
:options="options"
:allow-empty="true"
track-by="label"
label="label"
:reset-after="false"
select-label=""
selected-label=""
deselect-label=""
:searchable="false"
:placeholder="placeholder"
:clear-on-select="false"
:preserve-search="true"
:multiple="multiple"

Timothee P
committed
:disabled="loading"
@remove="remove"
<template
slot="option"
slot-scope="props"
>
<span :title="props.option.label">{{ props.option.label }}</span>
</template>
<template
v-if="multiple"
slot="selection"
slot-scope="{ values }"
>
<span
v-if="values && values.length > 1"
class="multiselect__single"
>
{{ values.length }} options sélectionnées
</span>

Timothee P
committed
>{{ currentSelectionLabel || selection.label }}</span>
</template>
</Multiselect>
</template>
<script>
import Multiselect from 'vue-multiselect';
export default {
name: 'DropdownMenuItem',
props: {
placeholder: {
type: String,
default: 'Sélectionnez une valeur'
},
options: {
type: Array,
default: () => {
return [];
}
},

Timothee P
committed
loading: {
type: Boolean,
default: false
},
multiple: {
type: Boolean,
default: false
},
currentSelection: {
type: [String, Array, Boolean],
default: null,

Timothee P
committed
},
defaultFilter: {
type: [String, Array, Boolean],
default: null,

Timothee P
committed
computed: {
/**
* Get the label of an option to work with project attributes options as JSON
*/
currentSelectionLabel() {
const option = this.options.find(opt => opt.value === this.currentSelection);
return option ? option.label : '';
}
},
watch: {
selection: {
deep: true,
handler(newValue) {
if (!newValue) {
this.selection = this.options[0];
this.$emit('filter', this.selection);
}
}
},

Timothee P
committed
currentSelection(newValue) {
this.updateSelection(newValue);
},
this.selection = this.options.find(opt => opt.value === this.currentSelection);
} else {
this.selection = this.options[0];

Timothee P
committed
}
remove(e) {
this.$emit('remove', e);
},
},
/**
* Normalizes the input value(s) to an array of strings.
* This handles both single string inputs and comma-separated strings, converting them into an array.
*
* @param {String|Array} value - The input value to normalize, can be a string or an array of strings.
* @return {Array} An array of strings representing the input values.
*/
normalizeValues(value) {
// If the value is a string and contains commas, split it into an array; otherwise, wrap it in an array.
return typeof value === 'string' ? (value.includes(',') ? value.split(',') : [value]) : value;

Timothee P
committed
},
/**
* Updates the current selection based on new value, ensuring compatibility with multiselect.
* This method processes the new selection value, accommodating both single and multiple selections,
* and updates the internal `selection` state with the corresponding option objects from `options`.
*
* @param {String|Array} value - The new selection value(s), can be a string or an array of strings.
*/
// Check if the component is in multiple selection mode and the new value is provided.
updateSelection(value) {
if (this.multiple && value) {
// Normalize the value to an array format, accommodating both single and comma-separated values.
const normalizedValues = this.normalizeValues(value);
// Map each value to its corresponding option object based on the 'value' field.
this.selection = normalizedValues.map(value =>
this.options.find(option => option.value === value)
);
} else {
// For single selection mode or null value, find the option object that matches the value.
this.selection = this.options.find(option => option.value === value);
}
<style>
#filters-container .multiple .multiselect__option--selected:not(:hover) {
background-color: #e8e8e8 !important;
}
#filters-container .multiselect--disabled .multiselect__select {
background: 0, 0 !important;
}