Search code examples
vue.jsvue-multiselect

vue multiselect : remove group label if empty


Such as the print screen, i want to remove intended group label if all childs are selected

enter image description here

In the screenshot, "Liège (Province)" is a part of the group label (Province). If i select it, it disappears from the group but the group label remains displayed.

How can I hide or remove the group label or the LI tag if all the child elements have been tagged?

<multiselect
v-model="values"
:options="options"
track-by="label"
label="value"
ref="multiselect"
group-values="datas"
group-label="type"
:custom-label="styleOption"
:placeholder="$trans('common.search.search_placeholder')"
open-direction="bottom"
:multiple="true"
:searchable="true"
:internal-search="false"
:clear-on-select="true"
:close-on-select="false"
:options-limit="10"
:limit="5"
:limit-text="limitText"
:max-height="400"
:show-no-results="false"
:show-no-options="false"
:option-height="0"
:hide-selected="true"
@search-change="getCities"
@close="closeEventHandler">
<template slot="tag" slot-scope="{ option, remove }">
    <div class="custom_tag" @click="remove(option)">
        <span class="tag">{{ option.value }}</span>
        <div class="tag_close">
            <svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" class="tag-close-icon"><path d="M18.3 5.71a.996.996 0 0 0-1.41 0L12 10.59 7.11 5.7A.996.996 0 1 0 5.7 7.11L10.59 12 5.7 16.89a.996.996 0 1 0 1.41 1.41L12 13.41l4.89 4.89a.996.996 0 1 0 1.41-1.41L13.41 12l4.89-4.89c.38-.38.38-1.02 0-1.4z"></path></svg>
        </div>
    </div>
</template>
<template slot="option" slot-scope="props">
    <span v-if="props.option.$isLabel">{{ props.option.$groupLabel }}</span>
    <span v-else>{{ props.option.label }}</span>
</template>
</multiselect>

EDIT: I think we should put a condition "!props.option.length" in the "v-if" like snippet below but it doesn't work.

<template slot="option" slot-scope="props">
<span v-if="props.option.$isLabel && !props.option.length">{{ props.option.$groupLabel }}</span>
<span v-else>{{ props.option.label }}</span>
</template>


Solution

  • You just need a computed property for the option. It will hold the groups which are not included. Here is a working demo that has a filteredOptions property

    var app = new Vue({
      el: '#app',
      components: { Multiselect: window.VueMultiselect.default },
       data () {
        return {
          options: [
            {
              language: 'Javascript',
              libs: [
                { name: 'Vue.js', category: 'Front-end' },
                { name: 'Adonis', category: 'Backend' }
              ]
            },
            {
              language: 'Ruby',
              libs: [
                { name: 'Rails', category: 'Backend' },
                { name: 'Sinatra', category: 'Backend' }
              ]
            },
            {
              language: 'Other',
              libs: [
                { name: 'Laravel', category: 'Backend' },
                { name: 'Phoenix', category: 'Backend' }
              ]
            }
          ],
          value: []
        }
      },
      computed:{
        filteredOptions(){
          return this.options.filter(el => el.libs.some(r=> !this.value.includes(r)))
        }
      }
    })
    body { font-family: 'Arial' } 
    <!DOCTYPE HTML>
    <html>
    <head>
      <title>Timeline</title>
      <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
      <script src="https://unpkg.com/[email protected]"></script>
      <link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/vue-multiselect.min.css">
      <script defer src="https://use.fontawesome.com/releases/v5.3.1/js/all.js"></script>
    </head>
    
    <body>
      <div id="app"> 
      <div>
      <label class="typo__label">Groups</label>
      <multiselect v-model="value" :options="filteredOptions" :multiple="true" group-values="libs" group-label="language" :group-select="false" :hide-selected="true" placeholder="Type to search" track-by="name" label="name"><span slot="noResult">Oops! No elements found. Consider changing the search query.</span></multiselect>
      <pre class="language-json"><code>{{ value  }}</code></pre>
    </div>
      
    </div>
    </body>