Vue-formulate: SelectAll in checkbox

Created on 7 Jan 2021  路  3Comments  路  Source: wearebraid/vue-formulate

@justin-schroeder Hi, i need create a component with checkbox with a selectAll checkbox. How I can doi t?
rsz_screencapture-astroselling3-test-admin-product-edit-12590-2021-01-07-11_01_38_1
My code:

<template>
    <div>
        <FormulateForm
            name="product-edit-form"
            v-model="attrs"
            v-if="isOpen"
            @submit="handleSubmit"
        >
           <input class="mc-mb-3" v-model="checked" type="checkbox" @change="selectAll()" /> Select All
            <FormulateInput
                name="channels"
                v-model="channels"
                :options="decorate(this.options)"
                type="checkbox"
            />
        </FormulateForm>
    </div>
</template>

<script>

export default {
    data() {
        const asset = this.asset;
        return {
            checked: false,
            attrs: {
               channels: []
            },
            options: this.product ? this.product.channels.map(function(item){
                const src = asset(`/images/macrocatalog/channels/iso-${item.channelIcon}@3x.png`);
                return {
                    value: item.channelId, 
                    label: `<div class="mc-flex mc-items-center mc-ml-1"><img class="mc-w-5 mc-mr-1" title="${item.channelName}" src="${src}">${item.channelType}</div>`
                }
            }) : []
       }
    },
    async mounted() {
    },
    methods: {
        selectAll: function(){
            // Here code for select
        },
        decorate(options) {
            return options.map((option) => ({
                ...option,
                ...{
                    "wrapper-class": "mc-flex mc-items-center",
                    "label-class": "mc-ml-2 mc-text-sm"
                },
            }));
        }
    },
    components: {
    }
}
</script>

<style>
</style>
feature request

Most helpful comment

@justin-schroeder @yanielbf I opted for a slightly different UI, but the functionality was similar:

quick_toggle_checkbox

To do that I create a custom formulate input, "QuickToggleCheckbox" in my case.

<template>
  <div
    :class="`formulate-input-element formulate-input-element--${context.type}`"
    :data-type="context.type"
    class="select-resources-container"
  >
    <div class="quick-toggle-checkbox-grades-controls">
      <a
        :class="!selectAllIsActive && 'inactive'"
        role="button"
        class="quick-toggle-checkbox-select quick-toggle-checkbox-select-select"
        @click.prevent="selectAllIsActive && handleSelectAll()"
      >
        Select all
      </a>
      <a
        :class="context.model.length < 1 && 'inactive'"
        role="button"
        class="quick-toggle-checkbox-select quick-toggle-checkbox-select-deselect"
        @click.prevent="context.model.length > 0 && (context.model = [])"
      >
        De-select all
      </a>
    </div>
    <FormulateInput
      :id="context.attributes.id"
      v-model="context.model"
      :options="context.options"
      :name="context.name"
      :validation-name="context.label"
      validation="required"
      type="checkbox"
    />
  </div>
</template>
<script>
export default {
  name: 'QuickToggleCheckboxInput',
  props: {
    context: {
      type: Object,
      required: true
    }
  },
  computed: {
    selectAllIsActive () {
      return this.context.model.length < this.context.options.length
    }
  },
  methods: {
    handleSelectAll () {
      const newIds = this.context.options.map(option => `${option.value}`)
      this.context.model = newIds
    }
  }
}
</script>
<style lang="scss" scoped>
.quick-toggle-checkbox-select {
  font-size: 14px;
  text-decoration: underline;
  font-weight: 700;
  cursor: pointer;
  &.inactive {
    cursor: initial;
    opacity: 0.5;
  }
}
</style>

Registered it as follows:

import Vue from 'vue'
import VueFormulate from '@braid/vue-formulate'
import QuickToggleCheckboxInput from '../components/inputs/QuickToggleCheckboxInput'

Vue.component('QuickToggleCheckboxInput', QuickToggleCheckboxInput)


Vue.use(VueFormulate, {
  library: {
    'quick-toggle-checkbox': {
      classification: 'checkbox',
      component: 'QuickToggleCheckboxInput'
    }
  }
})

And once you've done that you can use the input like this (pretty much like a standard checkbox input)

<FormulateInput
  v-model="selectedGrades"
  :options="gradeOptions"
  label="Grades"
  validation="required"
  validation-name="Grades"
  type="quick-toggle-checkbox"
/>

If you require a UI that features nested checkboxes like in the image you've provided, you could probably achieve that through a similar process. I personally find simple buttons to be a little less confusing.

All 3 comments

@chris-geelhoed i think you just did this recently correct? Want to weigh in here?

@justin-schroeder @yanielbf I opted for a slightly different UI, but the functionality was similar:

quick_toggle_checkbox

To do that I create a custom formulate input, "QuickToggleCheckbox" in my case.

<template>
  <div
    :class="`formulate-input-element formulate-input-element--${context.type}`"
    :data-type="context.type"
    class="select-resources-container"
  >
    <div class="quick-toggle-checkbox-grades-controls">
      <a
        :class="!selectAllIsActive && 'inactive'"
        role="button"
        class="quick-toggle-checkbox-select quick-toggle-checkbox-select-select"
        @click.prevent="selectAllIsActive && handleSelectAll()"
      >
        Select all
      </a>
      <a
        :class="context.model.length < 1 && 'inactive'"
        role="button"
        class="quick-toggle-checkbox-select quick-toggle-checkbox-select-deselect"
        @click.prevent="context.model.length > 0 && (context.model = [])"
      >
        De-select all
      </a>
    </div>
    <FormulateInput
      :id="context.attributes.id"
      v-model="context.model"
      :options="context.options"
      :name="context.name"
      :validation-name="context.label"
      validation="required"
      type="checkbox"
    />
  </div>
</template>
<script>
export default {
  name: 'QuickToggleCheckboxInput',
  props: {
    context: {
      type: Object,
      required: true
    }
  },
  computed: {
    selectAllIsActive () {
      return this.context.model.length < this.context.options.length
    }
  },
  methods: {
    handleSelectAll () {
      const newIds = this.context.options.map(option => `${option.value}`)
      this.context.model = newIds
    }
  }
}
</script>
<style lang="scss" scoped>
.quick-toggle-checkbox-select {
  font-size: 14px;
  text-decoration: underline;
  font-weight: 700;
  cursor: pointer;
  &.inactive {
    cursor: initial;
    opacity: 0.5;
  }
}
</style>

Registered it as follows:

import Vue from 'vue'
import VueFormulate from '@braid/vue-formulate'
import QuickToggleCheckboxInput from '../components/inputs/QuickToggleCheckboxInput'

Vue.component('QuickToggleCheckboxInput', QuickToggleCheckboxInput)


Vue.use(VueFormulate, {
  library: {
    'quick-toggle-checkbox': {
      classification: 'checkbox',
      component: 'QuickToggleCheckboxInput'
    }
  }
})

And once you've done that you can use the input like this (pretty much like a standard checkbox input)

<FormulateInput
  v-model="selectedGrades"
  :options="gradeOptions"
  label="Grades"
  validation="required"
  validation-name="Grades"
  type="quick-toggle-checkbox"
/>

If you require a UI that features nested checkboxes like in the image you've provided, you could probably achieve that through a similar process. I personally find simple buttons to be a little less confusing.

Great!!!. Thank you. This library is amazing.

Was this page helpful?
0 / 5 - 0 ratings