Skip to content

Instantly share code, notes, and snippets.

@InToSSH
Last active July 26, 2023 20:32
Show Gist options
  • Save InToSSH/d4a3b21fc86dd0b54b6ee4559378bc22 to your computer and use it in GitHub Desktop.
Save InToSSH/d4a3b21fc86dd0b54b6ee4559378bc22 to your computer and use it in GitHub Desktop.
PrimeVue AutoComplete wrapper to accept array of objects for items with 'label' and 'value' props and return only the 'value' prop value in the v-model. It now also supports the multiple version - return an array of values (IDs) and also accepts array of values as v-model and converts them back to objects for the OG Autocomplete
<template>
<div class="field">
<label :for="id" :class="{'p-error':(v && v.$invalid && v.$dirty)}">{{ label }} {{ v && 'required' in v ? '*' : ''}}</label>
<AutoComplete
:model-value="modelItem"
@update:modelValue="(selected) => valueUpdated(selected)"
:suggestions="filteredItems"
@complete="searchItems($event)"
:dropdown="true"
:multiple="multiple"
optionLabel="label"
forceSelection
input-class="p-inputtext-sm w-full"
class="p-inputtext-sm w-full "
>
</AutoComplete>
<small v-if="(v && v.$invalid && v.$dirty)" class="p-error">{{v.$errors[0].$message.replace('Value', label)}}</small>
</div>
</template>
<style scoped>
label {
display: block !important;
}
.p-autocomplete:deep(.p-button-icon-only) {
padding: 0.3rem 0;
}
.field {
margin-bottom: 0.25rem;
}
.p-autocomplete:deep(.p-autocomplete-multiple-container) {
width: 100%;
}
</style>
<script setup>
import {computed, ref, defineEmits} from 'vue';
import AutoComplete from "primevue/autocomplete";
const emit = defineEmits(['update:modelValue']);
const props = defineProps([
'id',
'label',
'modelValue',
'items',
'v',
'multiple',
])
const modelItem = computed(() => {
if (props.multiple) {
if (props.modelValue && props.modelValue.length) {
return props.items.filter(item => props.modelValue.includes(item.value));
}
return [];
}
return props.items.find(item => item.value == props.modelValue) ?? props.modelValue;
})
const filteredItems = ref();
const searchItems = (event) => {
setTimeout(() => {
if (!event.query.trim().length) {
filteredItems.value = [...props.items];
}
else {
filteredItems.value = props.items.filter((item) => {
return item.label.toLowerCase().startsWith(event.query.toLowerCase());
});
}
}, 100);
};
const valueUpdated = (selected) => {
if (selected && typeof selected === 'object' && 'value' in selected) {
emit('update:modelValue', selected.value);
} else if (props.multiple && selected && selected.length && selected[0].hasOwnProperty('value')) {
let selectedIds = selected.flatMap(i => i.value);
emit('update:modelValue', selectedIds);
} else {
console.log('skocili jsme sem', typeof selected);
emit('update:modelValue', selected );
}
}
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment