No More Posting New Topics!

If you have a question or an issue, please start a thread in our Github Discussions Forum.
This forum is closed for new threads/ topics.

Navigation

    Quasar Framework

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search

    q-select with select all option

    Framework
    2
    2
    3091
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • D
      darkslategrey last edited by darkslategrey

      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

      1 Reply Last reply Reply Quote 0
      • rstoenescu
        rstoenescu Admin last edited by

        Will try to squeeze this feature in v0.14.

        1 Reply Last reply Reply Quote 0
        • First post
          Last post