# Vue-multiselect(v1.1.3)

### The most complete selecting solution for Vue.js

Tag not found. Press semi-colon `;` to create a tag from search query.

- Single / multi select
- Searchable
- Tagging
- Custom option templates (1.1.0+)
- Action dispatcher

- Vuex support by default
- Ajax options
- Fully configurable
- +99% test coverage
- No dependencies

View on GitHub Getting started & examples

- Setup
- Getting Started
- Examples
- Select (primitive)
- Select (object)
- Select with search
- Multiselect with search
- Asynchronous select
- Tagging
- Custom option templates
- Action select
- Custom configuration
- API
- Props
- Events
- Slots

# Getting started

## Installation

    npm install vue-multiselect@1x --save

## Basic usage

    multiselect(
      :selected="selected",
      :options="options",
      @update="updateSelected"
    )

    import Multiselect from 'vue-multiselect'
    export default {
      components: { Multiselect },
      data () {
        return {
          selected: null,
          options: ['list', 'of', 'options']
        }
      },
      methods: {
        updateSelected (newSelected) {
          this.selected = newSelected
        }
      }
    }

## Package content

The package consist of of multiple files: Multiselect.vue which includes the template and styling of the default component. This component extends 2 additional mixins: multiselectMixin.js and pointerMixin.js , which contain the logic behind the multiselect. This way you can actually use the multiselect logic with your own template and styling.

You can import vue-multiselect’s mixins to create your own custom components based on those mixins.

Additionally the package exports the `deepClone` function.

    import { multiselectMixin, pointerMixin, deepClone } from 'vue-multiselect'
    export default {
      mixins: [multiselectMixin, pointerMixin],
      data () {
        return {
          selected: null,
          options: ['list', 'of', 'options']
        }
      }
    }

# Examples

## Single select dropdown (primitive value)

Disabled all highlight label text.

Single select / dropdown

    {{ valuePrimitive | json }}

Code sample

    multiselect(
      :options="options",
      :selected="valuePrimitive",
      :multiple="false",
      :searchable="false",
      :close-on-select="false",
      :show-labels="false"
      @update="updateValuePrimitive"
      placeholder="Select one"
      label="name"
    )

    updateValuePrimitive (value) {
      this.valuePrimitive = value
    }

## Single select dropdown (object)

Can't become empty. Showing custom deselect label.

The selected value is referencing the same object as the next example, to show that dynamic preselection works.

Single select / dropdown

    {{ value | json }}

Code sample

    multiselect(
      :options="source",
      :selected="value",
      :searchable="false",
      :close-on-select="false",
      :allow-empty="false",
      @update="updateValue",
      deselect-label="Can't remove this value"
      key="name"
      label="name"
      placeholder="Select one"
    )

    updateValue (value) {
      this.value = value
    }

## Single select with search

The selected value is referencing the same object as the previous example, to show that dynamic preselection works.

Simple select / dropdown

    {{ value | json }}

Code sample

    multiselect(
      :options="source",
      :selected="value",
      :searchable="true",
      :custom-label="nameWithLang"
      @update="updateValue",
      placeholder="Select one",
      label="name",
      key="name"
    )

    updateValue (value) {
      this.value = value
    },
    nameWithLang ({ name, language }) {
      return `${name} — [${language}]`
    }

## Multiple select with search

`:limit="2"` prop limits the visible results to 2.

Simple select / dropdown

    {{ multiValue | json }}

Code sample

    multiselect(
      :options="source",
      :selected="multiValue",
      :multiple="true",
      :searchable="true",
      :close-on-select="false",
      :clear-on-select="false",
      :limit="2"
      @update="updateMultiValue",
      placeholder="Pick some"
      label="name",
      key="name"
    )

    updateMultiValue (value) {
      this.multiValue = value
    },

## Asynchronous dropdown

Changing the search query emits the ``@search-change`` event, passing the search query as 1st param and the id as second.

To show loading indicator (spinner) please set the `:loading` prop to true.

Async multiselect Oops! No elements found. Consider changing the search query.

    {{ selectedCountries | json }}

Code sample

    multiselect(
      :options="countries",
      :selected="selectedCountries",
      :multiple="multiple",
      :local-search="false",
      :clear-on-select="false",
      :close-on-select="false",
      :loading="isLoading",
      id="ajax",
      @search-change="asyncFind",
      @update="asyncUpdate",
      label="name"
      key="code"
      placeholder="Type to search"
    )
      span(slot="noResult").
        Oops! No elements found. Consider changing the search query.

    asyncFind (query) {
      if (query.length === 0) {
        this.countries = []
      } else {
        this.isLoading = true
        setTimeout(() => {
          this.countries = countries.filter((element, index, array) => {
            return element.name.toLowerCase().includes(query.toLowerCase())
          })
          this.isLoading = false
        }, 1000)
      }
    },
    asyncUpdate (newVal) {
      this.selectedCountries = newVal
    }

## Tagging

To enable tagging you have to set up 2 props. `:taggable="true"` and `:on-tag="callback"` which should add the tag to both Options and Selected arrays.

Tagging Oops! No elements found. Consider changing the search query.

    {{ taggingSelected | json }}

Code sample

    multiselect(
      :options="taggingOptions",
      :selected="taggingSelected",
      :multiple="true",
      :searchable="searchable",
      :taggable="true",
      @tag="addTag",
      @update="updateSelectedTagging",
      tag-placeholder="Add this as new tag"
      placeholder="Type to search or add tag"
      label="name"
      key="code"
    )
      span(slot="noResult").
        Oops! No elements found. Consider changing the search query.

    addTag (newTag) {
      const tag = {
        name: newTag,
        // Just for example needs as we use Array of Objects that should have other properties filled.
        // For primitive values you can simply push the tag into options and selected arrays.
        code: newTag.substring(0, 2) + Math.floor((Math.random() * 10000000))
      }
      this.taggingOptions.push(tag)
      this.taggingSelected.push(tag)
    },
    updateSelectedTagging (value) {
      console.log('@tag: ', value)
      this.taggingSelected = value
    }

## v1.1.0+Custom option templates

You can provide the name of a registered custom partial to use as a template for elements in the option list.

If no partial is provided it will use the default one: `<span v-text="getOptionLabel(option)"></span>`

To ensure the keyboard navigation works properly, remember to set the `:option-height` to equal the height of the option template. By default, the component assumes an option height of 40px.

Fav No Man’s Sky path

    {{ selectedStyle | json }}

Code sample

    multiselect(
      :options="styleList",
      :selected="selectedStyle",
      :option-height="130",
      :custom-label="styleLabel",
      :show-labels="false",
      @update="updateSelectedStyle",
      option-partial="customOptionPartial"
      placeholder="Fav No Man’s Sky path"
      label="title"
      key="title"
    )

    import customOptionPartial from './partials/customOptionPartial.html'
    Vue.partial('customOptionPartial', customOptionPartial)

    // ...Inside Vue component
    methods: {
      styleLabel ({ title, desc }) {
        return `${title} – ${desc}`
      },
      updateSelectedStyle (style) {
        this.selectedStyle = style
      }
    }

    <!-- customOptionPartial.html -->
    <div>
      <img class="option__image" :src="option.img" alt="Poster" />
      <div class="option__desc">
        <span class="option__title">{‌{ option.title }}</span>
        <span class="option__small">
          {‌{ option.desc }}
        </span>
      </div>
    </div>

## Action dispatcher

Multiselect may also act as dispatcher for different actions, like in this example. No need for `:selected` prop.

Emits the `@select` after selecting an option.

Set `:reset-after` prop to true, to clear the value after each change.

Open console to see logs.
Code sample

    multiselect(
      :options="actions",
      :searchable="false",
      :reset-after="true",
      @select="dispatchAction",
      placeholder="Pick action",
    )

    dispatchAction (actionName) {
      switch (actionName) {
        case 'alert':
          window.alert('You just dispatched "alert" action!')
          break
        case 'console.log':
          console.log('You just dispatched "console.log" action!')
          break
        case 'scrollTop':
          window.scrollTo(0, 0)
          break
      }
    }

## Custom configuration

Can't remove the last value and only allow up to 5 selected options.

Hides already selected options.

Shows error when touched, but nothing is selected.

Must have at least one value
Code sample

    // Template
    div(:class="{ 'invalid': isInvalid }")
      label.typo__label Must have at least one value
      multiselect(
        :options="options",
        :selected="exampleValue6",
        :multiple="true",
        :searchable="true",
        :allow-empty="false",
        :hide-selected="true",
        :close-on-select="false",
        :max-height="400",
        :max="5",
        @close="onTouch",
        @update="updateExampleValue",
        placeholder="Pick at least one"
      )

    // Script
    computed: {
      isInvalid () {
        return this.isTouched && this.exampleValue6.length === 0
      }
    },
    methods: {
      onTouch () {
        this.isTouched = true
      },
      updateExampleValue (value) {
        this.exampleValue6 = value
      }
    }

    // Styles
    .invalid {
      .typo__label {
        color: $error-color;
      }
      .multiselect__tags {
        border-color: $error-color !important;
      }
    }

## Props

Name | Type | Default | Description
--- | --- | --- | ---
multiselectMixin.js
Id | Integer||String |  | Used to identify the component in events.
Options | Array |  | Array of available options: Objects, Strings or Integers.
Selected | Object||Array||String||Integer |  | Presets the selected options.
Multiple | Boolean | `false` | Equivalent to the `multiple` attribute on a <select> input.
Key | String |  | Used to compare objects. Only use if options are objects.
Label | String |  | Label from option Object, that will be visible in the dropdown.
Searchable | Boolean | `true` | Add / removes search input.
LocalSearch | Boolean | `true` | Decide whether to filter the results based on search query. Useful for async filtering, where we search through more complex data.
ClearOnSelect | Boolean | `true` | Clear the search input after `select()`. Use only when multiple is true.
HideSelected | Boolean | `false` | Hide already selected options
Placeholder | String | `'Select option'` | Equivalent to the `placeholder` attribute on a <select> input.
MaxHeight | Integer | `300` | Sets max-height style value of the dropdown
AllowEmpty | Boolean | `true` | Allows to remove all selected values. Otherwise one must be left selected.
ResetAfter | Boolean | `false` | Reset `this.value`, `this.search`, `this.selected` after `this.value` changes.
CloseOnSelect | Boolean | `true` | Enable/disable closing after selecting an option
CustomLabel | Function => String |  | Function used to create a custom label
Taggable | Boolean | `false` | Disable / Enable tagging
TagPlaceholder | String | `'Press enter to create a tag'` | String to show when highlighting a potential tag
Max | Number |  | Number of allowed selected options.
OptionsLimit `v1.1.3+` | Number | `1000` | Limit the elements in the dropdown to the first X options that match the search query. Useful for optimization.
Multiselect.vue
SelectLabel | String | `'Press enter to select'` | String to show when pointing to an option
SelectedLabel | String | `'Selected'` | String to show next to selected option
DeselectLabel | String | `'Press enter to remove'` | String to show when pointing to an alredy selected option
ShowLabels | Boolean | `true` | Decide whether to show labels on highlighted options
Limit | Number | `99999` | Limit the display of selected options. The rest will be hidden within the limitText string.
LimitText | Function => String | `count => `and ${count} more`` | Function that process the message shown when selected elements pass the defined limit.
Loading | Boolean | `false` | Show/hide the loading spinner.
Disabled | Boolean | `false` | Enable/disable the multiselect.
OptionPartial | String | `multiselectBasicOptionPartial` | Name of the registered custom option partial.
pointerMixin.js
ShowPointer | Boolean | `true` | Enable/disable highlighting of the pointed value.
OptionHeight | Number | `40` | Set the height of the option. Used for scroll calculations.

## Events

Name | Attributes | Listen to | Description
--- | --- | --- | ---
Update | `(value, id)` | `@update` | Emitted after `this.value` changes
Select | `(selectedOption, id)` | `@select` | Emitted after selecting an option
Remove | `(removedOption, id)` | `@remove` | Emitted after removing an option
SearchChange | `(searchQuery, id)` | `@search-change` | Emitted after the search query changes
Tag | `(searchQuery, id)` | `@tag` | Emitted after user attemts to add a tag
Open | `(id)` | `@open` | Emitted when the dropdown opens. Useful for detecting when touched.
Close | `(value, id)` | `@close` | Emitted when the dropdown closes

## Slots

Name | Description
--- | ---
MaxElements | Shows when the maximum options have been selected. Defaults to string: Maximum of <max> options selected. First remove a selected option to select another.
NoResult | Shows when no elements match the search query. Defaults to string: No elements found. Consider changing the search query.
BeforeList | Shows before the list, when dropdown is open.
AfterList | Shows after the list, when dropdown is open.

#### Created by Damian Dulisz @DamianDulisz

#### With love from Monterail