q-select with select all option
-
Hi,
I need a ‘select all’ option in the q-select checkbox type. So started to hack
the legacy q-select component.The problem I have is when the ‘all’ must be checked (when all other options are selected) the last selected one still get checked.
For readability, I omitted other types but checkbox.
Here my custom q-select implementation :
<template> <q-picker-textfield :disable="disable" :readonly="readonly" :label="label" :placeholder="placeholder" :static-label="staticLabel" :value="actualValue" @keydown.native.enter="open" > <q-popover ref="popover" :disable="disable || readonly" fit> <div class="q-select-popover list highlight"> <label v-if="type === 'checkbox'" v-for="(checkbox, index) in options" :key="checkbox" class="item" > <div class="item-primary"> <q-checkbox :value="optModel[index]" @click.prevent="onClick" @input="toggleValue(checkbox.value)"></q-checkbox> </div> <div class="item-content"> <div v-html="checkbox.label"></div> </div> </label> </div> </q-popover> </q-picker-textfield> </template> <script> export default { props: { value: { required: true }, options: { type: Array, required: true, validator (options) { return !options.some(opt => typeof opt.label === 'undefined' || typeof opt.value === 'undefined' ) } }, type: { type: String, default: 'list', validator (value) { return ['radio', 'list', 'checkbox', 'toggle'].includes(value) } }, label: String, placeholder: String, staticLabel: String, readonly: Boolean, disable: Boolean, all: Boolean, /// <= all boolean props delimiter: Boolean }, computed: { model: { get () { if (this.multipleSelection && !Array.isArray(this.value)) { console.error('Select model needs to be an array when using multiple selection.') } return this.value }, set (value) { this.$emit('input', value) } }, optModel () { /* Used by multiple selection only */ if (this.multipleSelection) { let options = this.options.map(opt => this.model.includes(opt.value)) return options } }, multipleSelection () { return ['checkbox', 'toggle'].includes(this.type) }, actualValue () { if (!this.multipleSelection) { let option = this.options.find(option => option.value === this.model) return option ? option.label : '' } let options = this.options .filter(opt => this.model.includes(opt.value)) .map(opt => opt.label) return !options.length ? '' : options.join(', ') } }, created () { // <= ADD ALL OPTION WHEN ALL IS TRUE (French 'Tous' = 'All') if (this.all) { this.options.unshift({ label: 'Tous', value: 'all' }) } }, methods: { open (event) { if (!this.disable && !this.readonly) { this.$refs.popover.open(event) } }, close () { this.$refs.popover.close() }, toggleValue (value) { /// <= MY HACK let index = this.model.indexOf(value) // model copy to trigger the emit input let model = this.model.slice(0) if (index >= 0) { model.splice(index, 1) this.model = model } else { if (value === 'all') { this.model = ['all'] } else { let indexAll = this.model.indexOf('all') if (indexAll >= 0) { model.splice(indexAll, 1) this.model = model } if (this.model.length + 1 === this.options.length - 1) { this.model = ['all'] } else { model.push(value) this.model = model } } } }, __setAndClose (val) { this.model = val this.close() } } } </script>
My component usage :
<my-select all class="column" label="hotels" type="checkbox" v-model="hotels" @input="onInput" :options="selectOptions3"></my-select>
My model :
{ selectOptions3: [ { label: 'Google', value: 'goog' }, { label: 'yahoo', value: 'ya' }, { label: 'Facebook', value: 'fb' }] }
I will be really interested if someone has any idea about this or any advise on how to get a ‘select all’ feature on q-select
thanks
-
Will try to squeeze this feature in v0.14.