Git Product home page Git Product logo

vueform / multiselect Goto Github PK

View Code? Open in Web Editor NEW
783.0 4.0 148.0 2.65 MB

Vue 3 multiselect component with single select, multiselect and tagging options (+Tailwind CSS support).

Home Page: https://vueform.com

License: MIT License

JavaScript 86.12% Vue 5.62% SCSS 6.48% CSS 1.77%
vue select vueselect vue-select dropdown vue3 vue2 multiselect autocomplete tailwindcss tailwind select2 selectbox select-multiple vuejs multiselectdropdown

multiselect's Issues

filterResults not work

<template>
  <div>
    <multiselect2
      mode="single"
      :value="selectedCountries"
      label="entityName"
      trackBy="entityName"
      @select="select"
      :object="true"
      :placeholder="placeholder"
      open-direction="bottom"
      :options="countries"
      :searchable="true"
      :loading="isLoading"
      :internal-search="false"
      :clear-on-select="false"
      :close-on-select="false"
      :filterResults="false"
      :options-limit="300"
      :limit-text="limitText"
      :max-height="200"
      @search-change="asyncFind"
    >
      <template #noResult>
        <span>Oops! No elements found.</span>
      </template>
    </multiselect2>
  </div>
</template>

<script lang="ts">
import { defineComponent, ref, nextTick } from "vue";
import _ from "lodash";
import Multiselect from "@vueform/multiselect";
import { useStore } from "../../../../store/modules";
import {
  ActionTypes,
  AirPortType,
} from "../../../../../src/store/modules/avia/contract";
const MIN_LEN_SEARCH = 2;
export default defineComponent({

  name: "SearchAirPort",
  props:{
    placeholder: String
  },
  components: {
    Multiselect2: Multiselect,
  },
  setup(props, { emit }) {
    // пока так не могу обойти фильтра селекта
    type extendAirPort = {
      entityId: number;
      languageId: number;
      entityCode: string;
      entityName: string;
      complexName: string;
    };
    type searchCity = Array<extendAirPort>;
    const selectedCountries = ref<AirPortType | null>(null);
    const countries = ref<searchCity>([]);
    const isLoading = ref<boolean>(false);
    const store = useStore();
    const limitText = (count) => {
      return `and ${count} other countries`;
    };

    const asyncFindFunc = _.debounce(async (query: string) => {
      console.log("search");
      isLoading.value = true;
      const paramsIn = {
        searhAirport: query,
      };
      const res = await store.dispatch(ActionTypes.SEARH_AIRPORT, paramsIn);

      if (res) {
        countries.value = res.map((item) => {
          return {
            ...item,
            complexName: item.entityCode + " " + item.entityName,
          };
        });
      }
      isLoading.value = false;
    }, 500);

    const asyncFind = (query: string) => {
      if (query && query.length > MIN_LEN_SEARCH) {
        asyncFindFunc(query);
      }
    };

    const select = (selectedOption: null | AirPortType) => {
      selectedCountries.value = selectedOption;
      let convetData: AirPortType | null = null;
      if (selectedOption) {
        convetData = {
          entityId: selectedOption.entityId,
          languageId: selectedOption.languageId,
          entityCode: selectedOption.entityCode,
          entityName: selectedOption.entityName,
        };
      }

      emit("select-data", convetData);
    };
    return {
      selectedCountries,
      countries,
      isLoading,
      limitText,
      asyncFind,
      select,
    };
  },
});
</script>

<style scoped></style>

пришлось пойти на хитрость изобретать extendAirPort что бы все норм было.
но проблема в том что фильтрация не отключается как показано в документации

I had to go to the trick of inventing extendAirPort that everything would be normal.
but the problem is that filtering is not disabled as shown in the documentation

Add input support for submitting forms in regular way

Hi guys,

I using Laravel and Vue and in some cases i have regular point to point form submission without ajax request.

When i place request to my controller, i can't see selected options in tag mode.

I found some work-around with @ change event to populate some hidden input, but it will be better if vue-multiselect package can handle this case.

my final work-around;
add this somewhere in vue component
<input v-for="id in v-model" type="hidden" name="variable_name[]" :value="id" />

Thanks.

Right click trigger undesired actions

Version

  • Vue version: 3
  • Plugin version: 1.2.5

Description

Because the component listen to mousedown events, right clicks trigger actions just like a normal click.

For example if you right click on the button to delete an item — let’s say to inspect it — the item gets removed.

It would be better to listen to the click event to avoid this unexpected behavior.

Custom "valueProp" not working in single mode

Hello together. Happy new year.

When I select a option, modelValue changed but the input stays empty.

Here my code example:

<template>
  <div>
    <Multiselect
      v-model="value"
      :options="options"
      value-prop="customer"
      label="bezeichnung1"
    />
  </div>
</template>

<script>
import Multiselect from "@vueform/multiselect";

export default {
  components: {
    Multiselect,
  },
  data() {
    return {
      value: null,
      options: [
        { bezeichnung1: "test", customer: "1" },
        { bezeichnung1: "test2", customer: "2" },
        { bezeichnung1: "test3", customer: "3" },
        { bezeichnung1: "test4", customer: "4" },
      ],
    };
  },
};
</script>

<style src="@vueform/multiselect/themes/default.css"></style>

When I change "customer" to "value" in template and script, it's working.
This problem is only in "single" mode.

@keydown.prevent.enter issue

Currently I set :add-tag-on="[]" and handle tagging carefully by testing every key typed with regex before addition.

Unfortunately I cannot implement features like on enter jump to next input, on enter do other stuff like add tag manually or display html5 validation message if something is wrong.

Could you provide option to turn @keydown.prevent.enter off so developers can handle this feature by themselves?

I think this won't take much time to implement and will make your component much more flexible.

html5 validation - missing required

We use html5 validation in our project and consider using the library, but we miss one feature the "required" attribute. Is there any way to get it?

Return values, not keys

Is it possible to get the selected values as ['kia', 'mazda'] and not [1, 2] as it is now?

options: ['ford', 'kia', 'mazda'] and mode is tags

Problem when searching in component "tags with async options"

Version

  • Vue version: 3

Description

Hi,

I'm having some trouble when doing some search in the "tags with async options". When the user do some search, pick an option and do another search that does not contain the first picked option, the component stop working. I'm not sure, but I suspect the problem is that the component try to retrieve some information about the tag in the options list but the option array doesn't have it on the second search.

Demo

This issue can be easily reproduced in example number 6 - Tags with async options (https://jsfiddle.net/q6Lnpr7a/).

 To reproduce this error:

 1 - Search for 'a';
 2 - Choose '@Formula' option;
 3 - Search for 'b';

image

Thank you very much.

Search containing spaces in single mode

Hi,

I'm having some trouble when the component is searcheable and the search term contains spaces. When the user types space, the first option of the combo is selected / deselected, making it impossible to search for more than one term. This can be seen in demo number 5 - Autocomplete with async options (https://jsfiddle.net/q6Lnpr7a/). I'm not sure, but I suspect the problem is onKeyup event.

image

Could you check it, please?

Thank you very much.

Failing to get initial value (Vue 3)

This is my code. It works just fine, except when "restaurantId" has initial value, it doesn't pre-select the option.

<restaurant-autocomplete v-model="filters.restaurantId" /> //Int

RestaurantAutocomplete.vue:

<template>
    <Multiselect
		    :delay="500"
		    :resolveOnLoad="!!$attrs.modelValue"
		    :options="async (q) => await autocomplete(q)" // [{value: Int, label: String}]
		    :searchable="true"
		    :filterResults="false"
		    :clearOnSearch="true"
		    :clearOnSelect="false"
		    placeholder="Restaurant"
		    :loading="loading"
		    @select="$emit('update:modelValue', $event)"/>
</template>

Add event on `nooptions` or `noresults` click

Hi there folks,

If the title is not already clear I try to explain what I mean and what I am trying to achieve. I am using Vue3 by the way.

I would like to have an event when the user clicks on the nooptions and noresults slots - just like the @select event. At the moment it doesn't work if I add a @click on the custom template slot as per below example:

<multiselect ...>
    <template v-slot:noresults>
        <div class="multiselect-option" @click="openModal">
            Create New
        </div>
    </template>
</multiselect>

Am I missing something or at the current stage it should not work until a custom event within the package is added?

Missing features

Hello, is it possible to add these features?

  1. clear button to remove all values in v-model. It's not very user friendly to remove 200 tags manually
  2. close prop, so that I can close options list when I pick value from multiple/tags mode
  3. limit options list to given length

Prefilled tags without providing options

As mentioned in #33 I would like to be able to prefill tags by only using the v-model. Currently (v1.3.3) I need to provide :options with matching tags to prefill the tags input even when setting the new showOptions/show-options property to false.
That's redundant imo.

Pre-populate tags

In using multiselect in tags mode is it possible to pre-populate tags with existing values when showing the control.

See https://jsfiddle.net/57okrzx2/3/ which sets the v-model value on creation but it isn't reflected on the control

Thanks

Question: How can I give focus to the input field in an elegant way?

I need to programmatically focus the input field. Before, we used a normal <input> element and were able to simply this.$refs.input.focus(). This is not possible when using multiselect and I couldn't find anything in the docs or code that would allow it.

My current workaround is this:

const input = this.$refs.input.$el.getElementsByTagName("input")[0]
input && input.focus()

Is there are more elegant way of solving this? Thanks!

Select first option on enter when search is enabled

I stumbled upon this in my project but could reproduce in the demo with "example #5 - Autocomplete with async options" as well:

  1. Type in "perl"
  2. An async list is loaded with a single entry "Perl"
  3. Press Enter
  4. Nothing happens, but the first list entry should be selected

Note this issue is not about case-insensitive search! The async backend function could also return "Practical Extraction and Report Language" when searching for "perl". My use case is a search for languages where searching for the language names or codes returns language names, e.g. search "de" will show first list entry "German".

Open direction - UP

Hi, many thanks for implementing html5 required feature. I think your project is going to be very popular because everybody who uses vue-multiselect and plans to migrate to vue3 looks for alternatives and your project stands out from the rest.

I'm writing for another feature request. Currently if multiselect is near the bottom of modal , or near the bottom of page it opens to bottom and user has to scroll down to see available options. This is very unpleasant experience, especially if user uses mobile phone. Is there any way to get open direction to top?

Unable to close dropdown after select

If :object="true" the dropdown doesn't close after selecting an option. This might be intended for mode="multiselect", but it happens also for single select.

Placeholder in input

Hi!

Using v1.2.5 multiselect in the single mode with searchable: true

When i set placeholder option i see it in html markup in div.multiselect-placeholder
Is there any way to move placeholder into input field (div.multiselect-search > input)?

Thanks.

Bug cross and arrow

Version

  • Vue version:
    Vue 3

Description

The cross and arrow when you select a person is a bit confusing to use.
I was retouching it, and I have seen that it is due to the heigth default of the images, but I think that the optimal solution instead of hiding it due to overflow, hide it with a v-if if it detects that there is a selected value the arrow that disappears and becomes the cross and the other way around. regards!

Demo

Please use our JSFiddle template to reproduce the bug. Issues without working reproduction might be ignored.
https://jsfiddle.net/2rnhytpg/
I don't know how that website works, but I think it's already here

<Multiselect
v-model="value"
mode="tags"
placeholder="Select employees"
trackBy="name"
label="name"
:search="true"
:options="[
{
value: 'judy',
name: 'Judy',
image: 'https://randomuser.me/api/portraits/med/women/1.jpg',
},
{
value: 'jane',
name: 'Jane',
image: 'https://randomuser.me/api/portraits/med/women/2.jpg',
},
{
value: 'john',
name: 'John',
image: 'https://randomuser.me/api/portraits/med/men/1.jpg',
},
{
value: 'joe',
name: 'Joe',
image: 'https://randomuser.me/api/portraits/med/men/2.jpg',
},
]"

<template v-slot:tag="{ option, handleTagRemove, disabled }">
  <div class="multiselect-tag is-user">
    <img :src="option.image" />
    {{ option.name }}
    <i
      v-if="!disabled"
      @click.prevent
      @mousedown.prevent.stop="handleTagRemove(option, $event)"
    />
  </div>
</template>
<template v-slot:option="{ option }">
  <img class="character-option-icon" :src="option.image" />
  {{ option.name }}
</template>
---- ![image](https://user-images.githubusercontent.com/40855265/114036201-293c8500-9880-11eb-983b-7fa0d71d57ac.png) ![image](https://user-images.githubusercontent.com/40855265/114036240-30fc2980-9880-11eb-8424-d6fa1dccc21e.png) ![image](https://user-images.githubusercontent.com/40855265/114036282-3b1e2800-9880-11eb-823a-2ac8c1133d94.png) ![image](https://user-images.githubusercontent.com/40855265/114036330-45d8bd00-9880-11eb-9fbf-f445499b7f3a.png)

.select() after .refreshOptions() race

Version

  • Vue version: 3

Description

I'm using a callback in refreshOptions to update the options for a rendered multi-select. Providing an option via this update that matches the value in modelValue isn't selected automatically, and I cannot select it via the .select() api as there is no promise or similar to respond to.

Is there a work-around or something I'm missing?

Demo

this.$refs.input.refreshOptions(
          this.getItems().then(() => {
            this.$refs.input.select(this.modelValue); // this fails because the multi-select isn't yet up to date with the new options, I probably shouldn't have to do this at all considering the modelValue is already set.
          })
        );

Unable to scroll multiselect component dropdown within modal

Version

  • Vue version: 3

Description

Unable to scroll through dropdown options whenever multiselect component is inside div element with tabindex value assigned.

I need to use such component inside a modal whose tabindex value is set to "-1" by default. When I try scrolling through dropdown options by clicking anywhere in the scrollbar, the dropdown list is immediately closes, losing focus. Any parent div element with any tabindex value assigned (not empty) causes this behavior. It's important to note that scrolling works by using the keyboard or mouse wheel. I'm able to select items in this dropdown list by clicking them, it's only a scrollbar issue.

Demo

https://jsfiddle.net/x5yhzou2/1/

Show previously added options recieved from server when using async options search

Show previously added options when using async options search

I`m using the select for async search options

      v-model="cities"
      mode="tags"
      :searchable="true"
      :options="async (query) => {
        return await fetchCities(query)
      }"
      :minChars="1"
      :resolveOnLoad="true"
      :delay="0"

I set resolveOnLoad="true", but how can I show tags, that asynchronously comes to v-model on form init, in the select field? Is there any way to set something like 'defaultOptions / initialOptions' when I`m "searching" for options and adding them as tags?

Adding tag by 'Space'

For now, we add a tag by 'Enter'. Is there any way to add a tag (via creating) by 'Space'?
E.g. typing 'tagNumber1', pressing 'Space', boom, tag created.

Label text doesn't change if options updated

Version

  • Vue version: 3

Description

We have typical use case: country select, translated to several locales. Options is array of objects:

const options = [{code: 'au', name: 'Autstralia'}]

If we have selected value au for example in English locale, our label shows Australia. But when change locale for example to Russian (ru), and update options, label will remain the same

I wrote test-case for this to clear our problem:

it('should reactively changes label when options has been changed', () => {
  let select = createSelect({
    value: 'ru',
    label: 'name',
    valueProp: 'code',
    options: [{ code: 'au', name: 'Australia' }, { code: 'ru', name: 'Russia' }, { code: 'us', name: 'USA' }],
  })

  select.vm.options = [{ code: 'au', name: 'Австралия' }, { code: 'ru', name: 'Россия' }, { code: 'us', name: 'США' }]

  expect(select.find('.multiselect-single-label').element).toBeVisible()
  expect(select.find('.multiselect-single-label').html()).toContain('Россия') // <---- Fails here, but shouldn't
})

Demo

https://jsfiddle.net/cubk7z50/13/

Unable to output array of object

Hello and Happy new year.
Probably the solution is very easy but I just can't make it work.
My problem is
when i trying to use Multiselect with an array of objects from api.

.get("/strategy/g") .then((response) => { this.strategies = response.data; })

in 'strategies' is stored the data
the output looks like this:
[ { "id": 2, "name": "Test one", "user_id": 1, }, { "id": 1, "name": "Test two ", "user_id": 2 } ]

Now when i try to output this in Multiselect

<Multiselect v-model="form.strategy_id" label="name" valueProp="id" trackBy="name" :searchable="true" :createTag="true" :object="true" :options="strategies" />

i get nothing

I also have tried like this but unfortunately without success

<Multiselect v-model="form.strategy_id" label="label" valueProp="value" trackBy="label" :searchable="true" :createTag="true" :object="true" :options="strategies.map((item) => { return { value: item.id, label: item.name }; })" />

Thanks in advance

Disabled for options is not possible

Hi,

need to disable a few options of a filteredList and still need them to be listed in the dropdown (like crossed out).

I tried with:

[ { "value": "1", "label": "de-AT", "disabled": false }, { "value": "2", "label": "de-CH", "disabled": false }, { "value": "3, "label": "en-GB", "disabled": false }, { "value": "4", "label": "en-CA", "disabled": false }, { "value": "5", "label": "de-DE", "disabled": true }, { "value": "6", "label": "en-US", "disabled": false } ]

as options, but this doesn't really do anything.

Is there a possibility to achieve this or is your multiselect designed to display only choosable options?

V-slot:tag remove function not working in 1.3.2?

Version

  • Vue version: 3

Demo

See the simple demo below. It is using 1.3.0. Select a tag, then click it to remove it. It works. Now change the version to 1.3.2. Select a tag, then click to remove it. An error is thrown and the tag isn't removed.

https://jsfiddle.net/do30skf2/1/

Description

It seems like the { remove } option is no longer present or working in v-slot:tag? In my actual project (setup using Vue CLI), I'm getting the error runtime-core.esm-bundler.js?5c40:217 Uncaught TypeError: remove is not a function.

Styling horizontal scrollbar

Hello,

is it intended that there is always a scrollbar at the bottom of the options dropdown?

If not, maybe change:

.multiselect-options{ overflow: scroll }

to:

.multiselect-options{ overflow-y: scroll }

regards,
lux

does not work at all on Android

Version 1.3.5

  • Vue version: 2

Description

This is a pretty big deal.. I just noticed this multiselect is completely unresponsive on my Android phone. It's not only my personal project, your own demo shows the same results https://jsfiddle.net/q6Lnpr7a/

Try the Autocomplete demo #5. I haven't tested it on IOS but on Android if you try to type inside the autocomplete box, the text goes on top of the placeholder, and it doesn't actually perform any search! It appears to perform a search when you tap outside the box, but then I think that also causes your text to disappear to it doesn't actually search.

Works perfectly on desktop. Also you can't reproduce this using Desktop Chrome's "device toolbar". Maybe you can reproduce it with GenyMotion/Xcode simulator.. hopefully you have an Android phone available.

v-model value not respected on start

Hey!

Thank you very much for this very easy to use and customizable component! 🎉

It works very well so far, except showing initial selected values. In the example below I load a list of users and their associated roles and a list of all roles as well.
The user.role_ids property is an array with only one value [ 1 ], but nothing is displayed in the Multiselect component.
When selecting one of the options in the Multiselect dropdown, the user.role_ids changes and the entry is displayed in the components div.

But I can see no difference in the result in user.role_ids.
Is there something I am missing or using the component the wrong way?

Example:

<template>
    <div>
        <div v-for="user in state.users" :key="user.id">
            {{ user }}
            // { "id": 1, "name": "Admin", "email": "....", "created_at": "2017-12-20T09:47:36.000000Z",
            // "updated_at": "2021-01-26T14:19:00.000000Z", "role_ids": [ 1 ],
            // "roles": [ { "id": 1, "name": "admin", "display_name": "Administrator", "description": "Project Administrator",
            // "created_at": "2017-12-20T09:47:35.000000Z", "updated_at": "2017-12-20T09:47:35.000000Z" } ] } 

            {{ user.role_ids }}
            // [ 1 ]

             {{ state.roles }}
             // [ { "id": 1, "name": "admin", "display_name": "Administrator", "description": "Project Administrator",
             // "created_at": "2017-12-20T09:47:35.000000Z", "updated_at": "2017-12-20T09:47:35.000000Z" },
             // { "id": 2, "name": "guest", "display_name": "Guest", "description": "Guest User",
             // "created_at": "2017-12-20T09:47:35.000000Z", "updated_at": "2017-12-20T09:47:35.000000Z" } ] 
             <multiselect
                 v-model="user.role_ids"
                 :label="'display_name'"
                 :track-by="'display_name'"
                 :valueProp="'id'"
                 :mode="'tags'"
                 :searchable="true"
                 :options="state.roles"
                 :placeholder="t('main.user.add-role-placeholder')">
             </multiselect>
         </div>
    </div>
</template>

<script>
import {
    computed,
    reactive,
} from 'vue';

export default {
setup() {
    const state = reactive({
        userList: computed(_ => store.getters.users),
        roles: computed(_ => store.getters.roles),
    });
    return {
        state
    }
}
</script>

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.