Select fields
Dynamic Select Component
A select component that supports both single and multiple selection modes using PrimeVue's Dropdown and MultiSelect components. The component provides a consistent interface for handling selection inputs with various configuration options.
Props
| Prop Name | Type | Default | Required | Description |
|---|---|---|---|---|
options | Array | Yes | Array of options to select from | |
itemText | String | "name" | No | Property name for option label |
itemValue | String | "name" | No | Property name for option value |
multiple | Boolean | false | No | Label Enable multiple selection |
filter | Boolean | false | No | Enable filtering options |
display | String | "comma" | No | Display mode for multiple selection |
showClear | Boolean | false | No | Show clear selection button |
<!-- component FormSelect.vue -->
<template>
<div class="flex flex-col gap-1 rounded-lg">
<label v-if="label" class=" body-xsmall text-neutral-500 mb-2"
>{{ label }}
</label>
<MultiSelect
:name="name"
v-model="value"
:options="options"
:optionLabel="itemText"
:optionValue="itemValue"
class="h-[48px] bg-card-light dark:bg-card-dark"
:showClear="showClear"
:placeholder="placeholder"
@change="onChange"
v-if="multiple"
:disabled="disabled"
/>
<Dropdown
:name="name"
v-model="value"
:options="options"
:optionLabel="itemText"
:optionValue="itemValue"
:optionLogo="itemLogo"
class="w-full h-[48px] px-3 dark:bg-[transparent]"
:showClear="showClear"
:placeholder="placeholder"
@change="onChange"
:option-disabled="isOptionDisabled"
v-else
>
<template v-if="action" #option="slotProps">
<div class=" flex items-center w-full gap-1">
<div class=" ">
<img
:src="slotProps.option.logo"
alt="logo"
class="rounded-[100px] w-6 h-6"
/>
</div>
<div>
<p class=" body-small">{{ slotProps.option.name }}</p>
<p class="body-small text-neutral-200">{{ slotProps.option.value }}</p>
</div>
</div>
</template>
</Dropdown>
</div>
</template>
<script setup>
const props = defineProps({
name: { type: String, required: true },
placeholder: { type: String, required: false },
required: { type: Boolean, default: false },
action: { type: Boolean, default: false },
options: { type: Array, default: () => [] },
value: { type: [String, Array, Object], required: true },
itemText: { type: String, default: "name" },
itemValue: { type: String, default: "value" },
itemLogo: { type: String, default: "logo" },
label: { type: String },
multiple: { type: Boolean, default: false },
hideError: { type: Boolean, default: false },
showClear: { type: Boolean, default: false },
disabled: { type: Boolean, default: false },
});
const value = ref(props.multiple ? [] : props.value);
const errorMessage = ref("");
const emit = defineEmits(["update:modelValue", "change", "onAction"]);
const onChange = (e) => {
if (props.multiple) {
// If in multiple mode, update value directly
value.value = e.value;
} else {
// If in single mode, update value as a string
value.value = e.value;
}
emit("update:modelValue", value.value);
emit("change");
};
watch(
() => props.value,
(newValue) => {
value.value = newValue;
}
);
const isOptionDisabled = (option) => {
return option[props.itemText] === props.disabledOption; // Disable specific option
};
// Delete Option API Call
const actionOption = async (optionValue) => {
emit("onAction", optionValue);
};
</script>
Example Usage
.p-select-label {
margin-top: auto;
margin-bottom: auto;
}
.p-placeholder {
color: #97989a !important;
font-size: 14px;
font-weight: 600;
}
.p-select {
border-radius: 8px !important;
border-color: transparent !important;
background: #fafafa !important;
box-shadow: none !important;
font-size: 14px !important;
.p-select-label {
padding: 0 !important;
/* color: #121212 !important; */
font-weight: 600;
}
&::placeholder {
color: #97989a !important;
}
}
.p-select-list {
font-size: 14px;
}
Example Usage
<FormSelect
label="Plan Status"
v-model="status"
placeholder="Select option"
:options="statusOption"
type="text"
name="status"
item-text="name"
item-value="value"
/>