Customizing the Bottom of Element-Plus Select Dropdown and Adjusting Maximum Height
Customizing the bottom of an Element-Plus select dropdown allows for adding custom elements like buttons or input fields. This can be useful for implementing features such as adding new options dynamically.
For Element-Plus Vesrions Below 2.4.3
Implementation Code
<template>
<el-select
v-model="selectedItems"
placeholder="Choose items"
style="width: 250px"
multiple
collapse-tags
>
<el-option
v-for="option in itemOptions"
:key="option"
:label="option"
:value="option"
class="custom-option"
>
<span>
{{ option }}
</span>
<span v-show="!selectedItems.includes(option)" @click.stop="removeItem(option)">
×
</span>
</el-option>
<!-- Hidden option to prevent empty dropdown display -->
<el-option
key="hidden"
value="hidden"
label="hidden"
style="position: fixed; top: -100%; z-index: -11; opacity: 0"
></el-option>
<div class="custom-footer">
<el-button v-if="!showInput" bg size="small" @click="toggleInput">
Add new item
</el-button>
<template v-else>
<el-input
v-model.trim="newItem"
type="text"
placeholder="Enter item name"
class="input-field"
maxlength="20"
/>
<div class="footer-buttons">
<el-button type="primary" size="small" @click="addNewItem">
Confirm
</el-button>
<el-button size="small" @click="resetInput">Cancel</el-button>
</div>
</template>
</div>
</el-select>
</template>
<script setup>
import { ref } from "vue";
import { ElMessage } from "element-plus";
const selectedItems = ref([]);
const itemOptions = ref([]);
const newItem = ref("");
const showInput = ref(false);
const toggleInput = () => {
showInput.value = true;
};
const addNewItem = () => {
if (itemOptions.value.includes(newItem.value)) {
return ElMessage.warning("Item already exists");
}
itemOptions.value.push(newItem.value);
newItem.value = "";
showInput.value = false;
};
const resetInput = () => {
newItem.value = "";
showInput.value = false;
};
const removeItem = (item) => {
itemOptions.value = itemOptions.value.filter((el) => el !== item);
selectedItems.value = selectedItems.value.filter((el) => el !== item);
};
</script>
<style lang="scss">
.custom-option {
display: flex;
justify-content: space-between;
}
.custom-footer {
padding: 10px 10px 0;
border-top: 1px solid #cccccc;
.footer-buttons {
margin-top: 8px;
}
}
</style>
Adjusting the Maximum Height of the Dropdown
To change the maximum height of the dropdown, add a custom class to the el-select component and define the style in CSS.
Note: Avoid using scoped styles and ensure class names are unique to prevent conflicts.
<el-select
popper-class="custom-dropdown"
:popper-append-to-body="true"
>
</el-select>
<style>
.custom-dropdown .el-select-dropdown__wrap {
max-height: 400px !important;
}
</style>
For Element-Plus Versions 2.4.3 and Above
Element-Plus version 2.4.3 introduced a built-in slot for customizing the dropdown footer, simplifying the implementation.
Implementation Code
<template>
<el-select v-model="selectedValue" placeholder="Select an option" style="width: 240px">
<el-option
v-for="item in optionList"
:key="item.id"
:label="item.name"
:value="item.id"
/>
<template #footer>
<el-button v-if="!addingMode" text bg size="small" @click="enableAdding">
Add new option
</el-button>
<template v-else>
<el-input
v-model="newOptionName"
class="option-input"
placeholder="Enter option name"
size="small"
/>
<el-button type="primary" size="small" @click="confirmAddition">
Confirm
</el-button>
<el-button size="small" @click="cancelAddition">Cancel</el-button>
</template>
</template>
</el-select>
</template>
<script setup>
import { ref } from 'vue'
const addingMode = ref(false)
const selectedValue = ref('')
const newOptionName = ref('')
const optionList = ref([
{ id: 'opt1', name: 'Option One' },
{ id: 'opt2', name: 'Option Two' },
{ id: 'opt3', name: 'Option Three' },
{ id: 'opt4', name: 'Option Four' },
{ id: 'opt5', name: 'Option Five' },
{ id: 'opt6', name: 'Option Six' },
])
const enableAdding = () => {
addingMode.value = true
}
const confirmAddition = () => {
if (newOptionName.value) {
optionList.value.push({
id: `opt${optionList.value.length + 1}`,
name: newOptionName.value,
})
cancelAddition()
}
}
const cancelAddition = () => {
newOptionName.value = ''
addingMode.value = false
}
</script>
<style lang="scss" scoped>
.option-input {
width: 100%;
margin-bottom: 8px;
}
</style>