JSFiddle - React, Tailwind, and code Playground
by Daedalus
HTML
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css">
<div id="app">
<div class="row">
<div class="col">
Item Selection
<select class="custom-select" multiple size="5" v-model="selected">
<option :value="1">1</option>
<option :value="2">2</option>
<option :value="3">3</option>
<option :value="4">4</option>
<option :value="5">5</option>
</select>
<button type="button" class="btn btn-primary" @click="addItem">
Add item at selected size
</button>
</div>
<div class="col">
Max selections: <input type="number" v-model.number="max" :max="4" :min="1" /><br />
Remaining selections: {{remaining}}
<div>
Active Item:
</div>
<div v-if="item !== null">
<select class="custom-select" multiple size="5" v-model="item.selected" @mousedown.left="prepareFix" @mouseup.left="fixSelected">
<option :value="1">1</option>
<option :value="2">2</option>
<option :value="3">3</option>
<option :value="4">4</option>
<option :value="5">5</option>
</select>
</div>
</div>
</div>
</div>
JavaScript
window.addEventListener('DOMContentLoaded', () => {
const app = new Vue({
el: "#app",
data: {
item: null,
selected: [],
max: 4
},
methods: {
addItem() {
if (this.item === null) {
let selected = this.selected.slice(0);
if (this.remaining - selected.length < 0) {
selected = selected.slice(0, this.remaining);
}
this.item = {
selected
}
}
},
prepareFix() {
this.item.currentlySelected = this.item.selected.length;
},
fixSelected() {
if (this.remaining - (this.currentlySelected + this.item.selected.length) < 0) {
this.item.selected.slice(0, this.remaining);
}
}
},
computed: {
remaining() {
if (this.item === null) {
return this.max;
} else {
return this.max - this.item.selected.length;
}
}
}
})
});