File: D:/HostingSpaces/SBogers10/shop.komma.nl/resources/js/components/vue/forms/multiselect.vue
<template>
<div :class="['multiselect', this.isFlyout ? 'multiselect--flyout' : '']">
<div class="select" v-if="!disabled" @click="toggle()">{{displaySelectText}}</div>
<div class="items" ref="checkboxes">
<label v-for="(name, value) in values">
<span>{{ name }}</span>
<input type="checkbox" :name="name" :value="value" v-model="selection" @change="changed"/>
</label>
</div>
</div>
</template>
<style lang="scss" scoped>
.multiselect {
position: relative;
}
.select {
position: relative;
width: 100%;
box-sizing: border-box;
display: block;
height: auto;
min-height: 40px;
padding: 8px;
font-size: .75rem;
margin-left: 0;
line-height: 1.6;
color: #9ba0ae;
background: #fff;
text-indent: 0;
border: 1px solid #d8dae2;
border-radius: 3px;
transition: border-color .25s ease-in-out,box-shadow .25s ease-in-out;
cursor: pointer;
&::before {
content: '';
position: absolute;
right: 0;
top: 0;
width: 40px;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
background-color: rgba(224,230,236,.5);
border-radius: 0 3px 3px 0;
}
&::after {
content: "";
position: absolute;
top: 17px;
right: 14px;
display: block;
border-color: #2b2f83 transparent transparent;
border-style: solid;
border-width: 4px 5px 0;
opacity: .5;
}
}
.items {
display: none;
border: 1px #dadada solid;
border-top: none;
margin-bottom: 24px;
label {
display: flex;
justify-content: space-between;
padding: 4px 8px;
font-size: 0.75rem;
color: #70778c;
&:hover {
color: #fff;
background-color: #1e90ff;
}
}
}
.multiselect--flyout {
.items {
position: absolute;
width: 100%;
background-color: #fff;
}
}
</style>
<script>
export default {
data: function() {
return {
isOpen: false,
selection: []
}
},
props: {
name: {
required: true,
type: String
},
selectText: {
required: false,
default: 'Select an option',
type: String
},
disabled: {
required: false,
default: false,
},
selected: { //The values to select when mounted
required: false,
default: () => { return [] },
type: Array
},
values: { //The properties will be displayed, their values will be the values for each select option (which actually will be a checkbox)
required: false,
default: () => { return {} },
type: Object
},
isFlyout: {
required: false,
default: false,
type: Boolean
}
},
watch: {
disabled: function(newVal, oldVal) {
if(!!newVal === true) this.close();
}
},
computed: {
displaySelectText() {
if(this.selection.length === 0) return this.selectText;
return this.selection.map((key) => {
return this.values[key]
}).join(', ')
},
},
methods: {
toggle() {
if (!this.isOpen && !this.disabled) {
this.open()
} else {
this.close()
}
},
open() {
this.$refs.checkboxes.style.display = "block";
this.isOpen = true;
},
close() {
this.$refs.checkboxes.style.display = "none";
this.isOpen = false;
},
changed() {
this.$emit('change', this.selection);
}
},
mounted() {
this.selection = this.selected.filter((item) => item.length > 0);
}
}
</script>