vue-multiselect 0,12,1,1 editorconfig Bower npm

Universal select/multiselect/tagging component for Vue.js

vue-multiselect Build StatusNo DependenciesCurrent ReleaseLicense

The most complete selecting solution for Vue.js, without jQuery.

Current version: 1.1.4

For Vue 2.0 users:

Vue-multiselect 2.0-beta is available: npm install [email protected]. API changes: * Instead of Vue.partial for custom option templates you can use a custom render function. * The :key props has changed to :track-by, due to conflicts with Vue 2.0. * Added support for v-model * @update has changed to @input to also work with v-model * :selected has changed to :value for the same reason

Features & characteristics:

  • NO dependencies
  • Single select
  • Multiple select
  • Tagging
  • Custom option templates (1.1.0+)
  • Dropdowns
  • Filtering
  • Search with suggestions
  • Logic split into mixins
  • Basic component and support for custom components
  • Vuex support
  • Async options support
  • > 99% test coverage
  • Fully configurable (see props list below)

Demo & docs

http://monterail.github.io/vue-multiselect/

Install & basic usage

npm install vue-multiselect
<template>
  <div>
    <multiselect
      :selected="selected"
      :options="options"
      @update="updateSelected">
    </multiselect>
  </div>
</template>
import Multiselect from 'vue-multiselect'
export default {
  components: { Multiselect },
  data () {
    return {
      selected: null,
      options: ['list', 'of', 'options']
    }
  },
  methods: {
    updateSelected (newSelected) {
      this.selected = newSelected
    }
  }
}

You can now author custom components based on vue-multiselect mixins.

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

Roadmap:

  • Grouping
  • Examples of custom components / templates ready to use in project

Examples

in jade-lang/pug-lang

Single select / dropdown

multiselect(
  :options="source",
  :selected="value",
  :searchable="false",
  :close-on-select="false",
  :allow-empty="false",
  @update="updateSelected",
  label="name",
  placeholder="Select one",
  key="name"
)

Single select with search

multiselect(
  :options="source",
  :selected="value",
  :close-on-select="true",
  :clear-on-select="false",
  @update="updateValue",
  placeholder="Select one",
  label="name",
  key="name"
)

Multiple select with search

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

Tagging

with @tag event

multiselect(
  :options="taggingOptions",
  :selected="taggingSelected",
  :multiple="true",
  :taggable="true",
  @tag="addTag",
  @update="updateSelectedTagging",
  tag-placeholder="Add this as new tag",
  placeholder="Type to search or add tag",
  label="name",
  key="code"
)
addTag (newTag) {
  const tag = {
    name: newTag,
    code: newTag.substring(0, 2) + Math.floor((Math.random() * 10000000))
  }
  this.taggingOptions.push(tag)
  this.taggingSelected.push(tag)
},

Custom option template

Using partial API

multiselect(
  :options="styleList",
  :selected="selectedStyle",
  :option-height="130",
  :custom-label="styleLabel",
  @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
  }
}
<div>
  <img class="option__image" :src="option.img" alt="No Man’s Sky" />
  <div class="option__desc">
    <span class="option__title">{{ option.title }}</span>
    <span class="option__small">
      {{ option.desc }}
    </span>
  </div>
</div>

Asynchronous dropdown

multiselect(
  :options="countries",
  :selected="selectedCountries",
  :multiple="multiple",
  :searchable="searchable",
  @search-change="asyncFind",
  placeholder="Type to search",
  label="name"
  key="code"
)
  span(slot="noResult").
    Oops! No elements found. Consider changing the search query.
methods: {
  asyncFind (query) {
    this.countries = findService(query)
  }
}

Props config

// multiselectMixin.js

props: {
  /**
   * Array of available options: Objects, Strings or Integers.
   * If array of objects, visible label will default to option.label.
   * If `label` prop is passed, label will equal option['label']
   * @type {Array}
   */
  options: {
    type: Array,
    required: true
  },
  /**
   * Equivalent to the `multiple` attribute on a `<select>` input.
   * @default false
   * @type {Boolean}
   */
  multiple: {
    type: Boolean,
    default: false
  },
  /**
   * Presets the selected options value.
   * @type {Object||Array||String||Integer}
   */
  selected: {},
  /**
   * Key to compare objects
   * @default 'id'
   * @type {String}
   */
  key: {
    type: String,
    default: false
  },
  /**
   * Label to look for in option Object
   * @default 'label'
   * @type {String}
   */
  label: {
    type: String,
    default: false
  },
  /**
   * Enable/disable search in options
   * @default true
   * @type {Boolean}
   */
  searchable: {
    type: Boolean,
    default: true
  },
  /**
   * Clear the search input after select()
   * @default true
   * @type {Boolean}
   */
  clearOnSelect: {
    type: Boolean,
    default: true
  },
  /**
   * Hide already selected options
   * @default false
   * @type {Boolean}
   */
  hideSelected: {
    type: Boolean,
    default: false
  },
  /**
   * Equivalent to the `placeholder` attribute on a `<select>` input.
   * @default 'Select option'
   * @type {String}
   */
  placeholder: {
    type: String,
    default: 'Select option'
  },
  /**
   * Sets maxHeight style value of the dropdown
   * @default 300
   * @type {Integer}
   */
  maxHeight: {
    type: Number,
    default: 300
  },
  /**
   * Allow to remove all selected values
   * @default true
   * @type {Boolean}
   */
  allowEmpty: {
    type: Boolean,
    default: true
  },
  /**
   * Reset this.value, this.search, this.selected after this.value changes.
   * Useful if want to create a stateless dropdown, that fires the this.onChange
   * callback function with different params.
   * @default false
   * @type {Boolean}
   */
  resetAfter: {
    type: Boolean,
    default: false
  },
  /**
   * Enable/disable closing after selecting an option
   * @default true
   * @type {Boolean}
   */
  closeOnSelect: {
    type: Boolean,
    default: true
  },
  /**
   * Function to interpolate the custom label
   * @default false
   * @type {Function}
   */
  customLabel: {
    type: Function,
    default: false
  },
  /**
   * Disable / Enable tagging
   * @default false
   * @type {Boolean}
   */
  taggable: {
    type: Boolean,
    default: false
  },
  /**
   * String to show when highlighting a potential tag
   * @default 'Press enter to create a tag'
   * @type {String}
  */
  tagPlaceholder: {
    type: String,
    default: 'Press enter to create a tag'
  },
  /**
   * Number of allowed selected options. No limit if false.
   * @default False
   * @type {Number}
  */
  max: {
    type: Number,
    default: false
  },
  /**
   * Will be passed with all events as second param.
   * Useful for identifying events origin.
   * @default null
   * @type {String|Integer}
  */
  id: {
    default: null
  },
  /**
   * Limits the options displayed in the dropdown
   * to the first X options.
   * @default 1000
   * @type {Integer}
  */
  optionsLimit: {
    type: Number,
    default: 1000
  }
}

// pointerMixin.js

props: {
  /**
   * Enable/disable highlighting of the pointed value.
   * @type {Boolean}
   * @default true
   */
  showPointer: {
    type: Boolean,
    default: true
  }
},

// Multiselect.vue

props: {
  /**
   * String to show when pointing to an option
   * @default 'Press enter to select'
   * @type {String}
   */
  selectLabel: {
    type: String,
    default: 'Press enter to select'
  },
  /**
   * String to show next to selected option
   * @default 'Selected'
   * @type {String}
  */
  selectedLabel: {
    type: String,
    default: 'Selected'
  },
  /**
   * String to show when pointing to an alredy selected option
   * @default 'Press enter to remove'
   * @type {String}
  */
  deselectLabel: {
    type: String,
    default: 'Press enter to remove'
  },
  /**
   * Decide whether to show pointer labels
   * @default true
   * @type {Boolean}
  */
  showLabels: {
    type: Boolean,
    default: true
  },
  /**
   * Limit the display of selected options. The rest will be hidden within the limitText string.
   * @default 'label'
   * @type {String}
   */
  limit: {
    type: Number,
    default: 99999
  },
  /**
   * Function that process the message shown when selected
   * elements pass the defined limit.
   * @default 'and * more'
   * @param {Int} count Number of elements more than limit
   * @type {Function}
   */
  limitText: {
    type: Function,
    default: count => `and ${count} more`
  },
  /**
   * Set true to trigger the loading spinner.
   * @default False
   * @type {Boolean}
  */
  loading: {
    type: Boolean,
    default: false
  },
  /**
   * Disables the multiselect if true.
   * @default false
   * @type {Boolean}
  */
  disabled: {
    type: Boolean,
    default: false
  }
}

Contributing

# serve with hot reload at localhost:8080
npm run dev

# lib distribution build with minification
npm run bundle

# build the docs into gh-pages
npm run docs

# run unit tests
npm run test

# run unit tests watch
npm run unit-watch

For detailed explanation on how things work, checkout the guide and docs for vue-loader.

License

MIT

Copyright © 2016 Damian Dulisz

Related Repositories

vue-multiselect

vue-multiselect

Universal select/multiselect/tagging component for Vue.js ...


Top Contributors

shentao asvae kubakrzempek freakone julesjanssen nicolas-t lionel-bijaoui sleimanx2 Yopadd

Dependencies

package version
dev autoprefixer ^6.7.2
babel-cli ^6.23.0
babel-core ^6.22.1
babel-eslint ^7.1.1
babel-helper-vue-jsx-merge-props ^2.0.2
babel-loader ^6.2.10
babel-plugin-istanbul ^3.1.2
babel-plugin-syntax-jsx ^6.13.0
babel-plugin-transform-es2015-destructuring ^6.23.0
babel-plugin-transform-export-extensions ^6.8.0
babel-plugin-transform-object-rest-spread ^6.23.0
babel-plugin-transform-runtime ^6.0.0
babel-plugin-transform-vue-jsx ^2.0.2
babel-preset-es2015 ^6.6.0
babel-preset-stage-2 ^6.22.0
babel-register ^6.0.0
chai ^3.5.0
chalk ^1.1.3
connect-history-api-fallback ^1.1.0
copy-webpack-plugin ^4.0.0
cross-env ^3.1.4
css-loader ^0.25.0
eslint ^3.14.1
eslint-config-standard ^6.1.0
eslint-friendly-formatter ^2.0.5
eslint-loader ^1.6.1
eslint-plugin-html ^2.0.0
eslint-plugin-promise ^3.4.0
eslint-plugin-standard ^2.0.1
eventsource-polyfill ^0.9.6
express ^4.13.3
extract-text-webpack-plugin ^2.0.0-rc.3
file-loader ^0.10.0
friendly-errors-webpack-plugin ^1.1.3
function-bind ^1.1.0
html-loader ^0.4.4
html-webpack-plugin ^2.28.0
http-proxy-middleware ^0.17.3
inject-loader ^2.0.1
json-loader ^0.5.4
jstransformer-markdown-it ^2.0.0
karma ^1.4.1
karma-coverage ^1.1.1
karma-mocha ^1.3.0
karma-phantomjs-launcher ^1.0.2
karma-sinon-chai ^1.2.4
karma-sourcemap-loader ^0.3.7
karma-spec-reporter 0.0.26
karma-webpack ^2.0.2
lolex ^1.5.2
mocha ^3.2.0
node-sass ^3.13.1
opn ^4.0.2
optimize-css-assets-webpack-plugin ^1.3.0
ora ^0.3.0
phantomjs-prebuilt ^2.1.3
pug ^2.0.0-beta11
pug-loader ^2.3.0
raw-loader ^0.5.1
sass-loader ^6.0.1
semver ^5.3.0
shelljs ^0.7.4
sinon ^1.17.3
sinon-chai ^2.8.0
url-loader ^0.5.7
vue ^2.3.0
vue-hot-reload-api ^1.2.0
vue-html-loader ^1.0.0
vue-loader ^11.0.0
vue-style-loader ^2.0.0
vue-template-compiler ^2.3.4
vue-template-es2015-compiler ^1.4.2
vuex ^2.1.1
webpack ^2.2.1
webpack-bundle-analyzer ^2.2.1
webpack-dev-middleware ^1.10.0
webpack-hot-middleware ^2.16.1
webpack-merge ^2.6.1

Releases

-   v2.0.0-beta.9 zip tar
-   v2.0.0-beta.8 zip tar
-   v1.1.4 zip tar
-   v0.1.7 zip tar
-   v0.1.6 zip tar
-   v0.1.5 zip tar
-   v0.1.4 zip tar
-   v0.1.2 zip tar
-   v0.1.1 zip tar
-   v0.1.0 zip tar
-   next zip tar
-   1.1.3 zip tar
-   1.1.2 zip tar
-   1.1.1 zip tar
-   1.1.0 zip tar
-   1.0.1 zip tar
-   1.0.0 zip tar
-   0.3.1 zip tar
-   0.3.0 zip tar
-   0.2.6 zip tar
-   0.2.5 zip tar