https://iendeavor.github.io/vue-next-select/
Please make sure to read the contributing guide before making a pull request.
# build package
pnpm run build
# run linter
pnpm run lint
# run tests
pnpm run test
The selecting solution for Vue 3
Home Page: https://iendeavor.github.io/vue-next-select
License: MIT License
https://iendeavor.github.io/vue-next-select/
Please make sure to read the contributing guide before making a pull request.
# build package
pnpm run build
# run linter
pnpm run lint
# run tests
pnpm run test
Would be nice to add property 'clearable' to allow user clear input
Describe the bug A clear and concise description of what the bug is.
I have 2 tables.
1st holds all the categories
2nd holds my settings with 3 fields connected to the category_id.
I have 3 vue-next-select boxes that are using the values from DB (1st to fill in all the options, 2nd to determine what's the selected value each time)
My issue is that on initialization the "Selected" value is not there.
How should I set up my vue-next-select instances to work with?
The value that they should get pre-selected is:
"v-model="store_cats.store_cat1"" (for 1st select box for example)
To Reproduce A reproduce link:
https://codesandbox.io/s/github/iendeavor/vue-next-select/tree/develop/examples?file=/src/views/Playground.vue
Expected behavior A clear and concise description of what you expected to happen.
Select box to have the pre-selected options bound from DB.
Screenshots If applicable, add screenshots to help explain your problem.
See my full component code:
`
<div class="card card-style">
<form action="javascript:void(0)" method="post">
<div class="content mb-0">
<h4>Bargain settings</h4>
<p>
Setup limits around bargains in your store.
</p>
<div class="row">
<div class="col-6">
<div class="mx-auto">
<div class="float-start">
<h6>Store Limit</h6>
</div>
<div class="stepper rounded-s float-start">
<a @click="red_store_limit()"><i class="fa fa-minus color-red-dark"></i></a>
<input type="number" ref="number" min="1" max="99" id="store_limit" name="store_limit" v-model="bargain_settings.store_limit">
<a @click="incr_store_limit()"><i class="fa fa-plus color-green-dark"></i></a>
</div>
<div class="clearfix"></div>
</div>
</div>
<div class="col-6">
<div class="mx-auto">
<div class="mx-auto float-end">
<h6>Bargain Limit</h6>
</div>
<div class="stepper rounded-s float-end">
<a @click="red_bargain_limit()"><i class="fa fa-minus color-red-dark"></i></a>
<input type="number" ref="number" min="1" max="99" id="bargain_limit" name="bargain_limit" v-model="bargain_settings.bargain_limit">
<a @click="incr_bargain_limit()"><i class="fa fa-plus color-green-dark"></i></a>
</div>
<div class="clearfix"></div>
</div>
</div>
</div>
<a href="#" @click="updBargain" :disabled="processing" class="btn btn-m btn-full rounded-sm shadow-l bg-green-dark text-uppercase font-900 mt-4">{{ processing ? "Please wait" : "Update" }}</a>
<br/>
</div>
</form>
</div>
<div class="card card-style">
<form action="javascript:void(0)" method="post">
<div class="content mb-0">
<h4>Store settings</h4>
<p>
Setup your store details.
</p>
<div class="input-style input-style-always-active has-borders no-icon mb-4">
<textarea id="store_descr" name="store_descr" v-model="store_settings.store_descr" placeholder=""></textarea>
<label for="store_descr" class="color-highlight">Store small description</label>
<em class="mt-n3">(required)</em>
</div>
<div class="input-style input-style-always-active has-borders no-icon mb-4">
<textarea id="oper_details" name="oper_details" v-model="store_settings.oper_details" placeholder=""></textarea>
<label for="store_descr" class="color-highlight">Store operation details</label>
<em class="mt-n3">(required)</em>
</div>
<a href="#" @click="updStoreDetails" :disabled="processing" class="btn btn-m btn-full rounded-sm shadow-l bg-green-dark text-uppercase font-900 mt-4">{{ processing ? "Please wait" : "Update" }}</a>
<br/>
</div>
</form>
</div>
<div class="card card-style">
<form action="javascript:void(0)" method="post">
<div class="content mb-0">
<h4>Store Categories</h4>
<p>
Select up to 3 categories for your store.
</p>
<div class="row">
<div class="col">
<label for="store_cat1" class="color-highlight">Store Category 1</label>
<vue-next-select
v-model="store_cats.store_cat1"
:options="avail_store_cats"
label-by="description"
value-by="store_cat_id"
close-on-select
:min="1"
class="max-size mt-1"
></vue-next-select>
</div>
</div>
<div class="row">
<div class="col">
<label for="store_cat1" class="color-highlight">Store Category 2</label>
<vue-next-select
v-model="store_cats.store_cat2"
:options="avail_store_cats"
label-by="description"
value-by="store_cat_id"
close-on-select
:min="1"
class="max-size mt-1"
></vue-next-select>
</div>
</div>
<div class="row">
<div class="col">
<label for="store_cat1" class="color-highlight">Store Category 3</label>
<vue-next-select
v-model="store_cats.store_cat3"
:options="avail_store_cats"
label-by="description"
value-by="store_cat_id"
close-on-select
:min="1"
class="max-size mt-1"
></vue-next-select>
</div>
</div>
<a href="#" @click="updStoreCats" :disabled="processing" class="btn btn-m btn-full rounded-sm shadow-l bg-green-dark text-uppercase font-900 mt-4">{{ processing ? "Please wait" : "Update" }}</a>
<br/>
</div>
</form>
</div>
Then the script part:
` import { mapActions } from 'vuex'
import VueNextSelect from 'vue-next-select'
import 'vue-next-select/dist/index.min.css'
export default {
name:'settings',
components: {
'vue-next-select' : VueNextSelect,
},
data(){
return {
bargain_settings:{
user_id: this.$store.state.auth.user.id,
store_limit:this.$store.state.auth.user.store.store_limit,
bargain_limit:this.$store.state.auth.user.store.bargain_limit
},
store_settings:{
user_id: this.$store.state.auth.user.id,
store_descr:this.$store.state.auth.user.store.store_descr,
oper_details:this.$store.state.auth.user.store.oper_details,
},
store_cats:{
store_cat1:this.$store.state.auth.user.store.cat1_id,
store_cat2:this.$store.state.auth.user.store.cat2_id,
store_cat3:this.$store.state.auth.user.store.cat3_id,
},
avail_store_cats:[],
processing:false
}
},
created(){
this.getAvailStoreCats()
},
methods:{
...mapActions({
signIn:'auth/getUser'
}),
incr_bargain_limit(field) {
this.bargain_settings.bargain_limit += 1
},
red_bargain_limit() {
this.bargain_settings.bargain_limit -= 1
},
incr_store_limit() {
this.bargain_settings.store_limit += 1
},
red_store_limit() {
this.bargain_settings.store_limit -= 1
},
async updBargain(){
this.processing = true
await axios.post('/api/updstore_limits',this.bargain_settings).then(({data}) => {
if (!data.success) {
this.do_show_popup_error(data.message)
} else {
this.do_show_popup_success(data.message)
this.signIn() // refresh local data
}
}).catch(({response:{data}})=>{
this.do_show_popup_error(data.message)
}).finally(()=>{
this.processing = false
})
},
async updStoreDetails(){
this.processing = true
await axios.post('/api/updstore_settings',this.store_settings).then(({data}) => {
if (!data.success) {
this.do_show_popup_error(data.message)
} else {
this.do_show_popup_success(data.message)
this.signIn() // refresh local data
}
}).catch(({response:{data}})=>{
this.do_show_popup_error(data.message)
}).finally(()=>{
this.processing = false
})
},
async updStoreCats() {
this.processing = true
await axios.post('/api/updstore_cats',this.store_cats).then(({data}) => {
if (!data.success) {
this.do_show_popup_error(data.message)
} else {
this.do_show_popup_success(data.message)
this.signIn() // refresh local data
}
}).catch(({response:{data}})=>{
this.do_show_popup_error(data.message)
}).finally(()=>{
this.processing = false
})
},
async getAvailStoreCats(){
this.processing = true
await axios.get('/api/get_avail_store_cats').then(({data}) => {
if (!data.success) {
} else {
this.avail_store_cats = data.avail_store_cats
}
}).catch(({response:{data}})=>{
this.do_show_popup_error(data.message)
}).finally(()=>{
this.processing = false
})
}
}
}`
Desktop (please complete the following information):
Smartphone (please complete the following information):
Additional context Add any other context about the problem here.
The code sandbox examples just shows error for me.
I'm on mobile safari.
Describe the bug
./node_modules/vue-next-select/dist/vue-next-select.es.prod.js 1:5557
Module parse failed: Unexpected token
Hi,
I used vue-next-select by writing this "Single select (object)" example
https://iendeavor.github.io/vue-next-select/#single-select-object-header
However, "options" variable has an 'id' property that contains numbers.
`
<vue-select
v-model="model"
:options="options"
:visible-options="visibleOptions"
label-by="id"
track-by="id"
searchable
clear-on-select
close-on-select
@search:input="handleSearchInput" />
...
// Example options variable
const options = [
{ id: 1, language: 'JavaScript' },
{ id: 2, language: 'Python' },
{ id: 3, language: 'PHP' }
]
`
The following warning will be thrown if I select an item from the dropdown.
[Vue warn]: Invalid prop: type check failed for prop "placeholder". Expected String with value "2", got Number with value 2. at <VueInput key=0 ref="input" modelValue="" ... >
I tried passing type="number"
to the element, but this warning's still existed.
It would be great if this warning disappears.
Thank you.
In select with search : https://iendeavor.github.io/vue-next-select/#select-with-search-header
is it possible to select an item with the keyboard keys ?
I am trying to use the tag slot but I don't see a way to create the "x" delete button for a selected tag. Is there some way to emit this or include the addOrRemoveOption
method as part of the slot scope so we can call it inside the slot?
I would like to add property to set maxlength of searchable text box.
https://github.com/iendeavor/vue-next-select/blob/main/src/components/input.vue
Hi I was wondering if a "custom Scrollbar" is on the roadmap?
It does not worked with vuejs 3.
How to make this options="hospitals"
to like this
<select class="form-control" v-model="patient.hospital_id" name="hospital_id" required >
<option value="" selected>Select Hospital</option>
<option v-for="hos in hospitals" :key="hos.id" :value="hos.id">{{ hos.name }}</option>
</select>
where hospitals = [ { "id": 1, "name": "BPKIHS" }, { "id": 2, "name": "Dhulabari Help post" } ]
- more object of array.
I wish it worked like bootstrap select.
8e6aee1 indroduced the usage of teleport
I see now a warning in the console:
Failed to locate Teleport target ...
It seems that teleport is intended to be connected to HTML-tags existing outside of the Vue app:
vuejs/core#1705
Why do you use teleport
in this context? Might a slot
be enough?
browser hangs/freezes after using the arrow key (down) to scroll through items, using chrome browser
Steps to reproduce the behavior:
Expected behavior
browser should not hang/freeze
Desktop (please complete the following information):
I'm facing the problem in my own app, but I noticed it was also happening in the demo page with the birds.
Is your feature request related to a problem? Please describe.
When no space at bottom popup opened and have very low height.
Describe the solution you'd like
When no space at bottom - show popup at top direction
The current repository directory structure prevents cloning the repository on a Windows PC because some directories contain colons (:
) in their path.
Renaming these directories using underscore (_
) or dashe (-
) would allow the project to be cloned and worked on in a Windows environments.
Is it possible to add in a flag to the component that would close the dropdown when an item is selected?
I stumble on a problem with the searchable setting, when this is turned on I can search though the available options, but when an option has a character with a accent e.g. (é, ë, á, ä) this won't show up and you need to add the accent to the e to get the results you want.
Describe the solution you'd like
It should be nice if this is included inside the code of searchable so when you type a letter without the accent options with accents do show up.
Describe alternatives you've considered
For now I need to find a way to do this with @search:input and @search:change
Describe the bug
Bug with the plugin, with a certain set of options
To Reproduce
A reproduce link:
https://codesandbox.io/s/adoring-grass-xi7de?file=/src/views/BasicUsage.vue
Steps to reproduce the behavior:
Expected behavior
No critical errors
Desktop (please complete the following information):
Additional context
Its unusual behaivor, but it bug happen only when:
I have this:
<vue-select :options="suppliers" v-model="supplier" label-by="supplier" track-by="id" value-by="id" close-on-select="true"/>
and in the data()
suppliers: [
{id: 1, supplier: 'Test 1'},
{id: 2, supplier: 'Test 2'}
],
supplier: ''
and I get the
app.js:66481 Uncaught (in promise) TypeError: Cannot read property 'id' of undefined
What I have understood from docs, I have to use track-by and value-by to tell the select that the value is the "id" and the label is "supplier".
So when select a value it should pass the id to the model "supplier"
Am I wrong ?
Describe the bug
When setting "value-by" (string or function) on multiselect with pre-populated v-model, getting "Cannot read property 'x' of undefined". Error is happening in "createComputedForGetterFunction". It's getting some additional item (outside of the provided options) which is undefined. Maybe I'm misunderstanding the usage, but it looks like you should be able to pass one array of objects to the v-model (which represents selected items) and another array of objects to options. When I use just strings it works (ex. v-model: ["apple", "orange"], :options=["apple", "orange", "strawberry"]).
To Reproduce
A reproduce link:
https://codesandbox.io/s/shy-lake-h96nh?file=/src/views/CustomEmptyModelValue.vue
Steps to reproduce the behavior:
Expected behavior
Renders the control without error and shows v-model item selected.
Desktop (please complete the following information):
Smartphone (please complete the following information):
Additional context
Add any other context about the problem here.
I think there is an issue here using this example: https://iendeavor.github.io/vue-next-select/#creatable-header
I attached some captures with the issue.
If using taggable the input with the search field is not "replacing" the select, the input with "Type to search" is going down (under "Select option").
If you not using taggable and you click "select option" the field is "replaced" with "Type to search" which is supposed to do if using taggable too.
Is this a bug or this is supposed to work if using taggable ?
You should add something similar:
.vue-select {
position: relative;
}
.vue-dropdown {
position: absolute;
background: #fff;
border: 1px solid #000;
z-index: 3;
max-height: 200px;
overflow-x: auto;
top: 14px;
}
It would be good if an option can be created if its not available in the available in the searched options.
Describe the bug
An error occurs when entering the examples on codesandbox.io.
Container Error
Error fetching sandbox.
To Reproduce
Link to Codesandbox
Sandbox of Vue-Next-Select
Additional context
Just as a hint cause it might prevent people from using vue-next-select even tho it's just awesome.
Hello,
I am sorry if it is wrong to post here.
I want to use this package in my application and I am using options api vue.js 3 and only JavaScript not Type script, so I don't need defineComponent too. I want to filter the options list by typing on select like search. I've gone through the documentation, I tried, still it is not working. I have set up the on main.js/app.js as on document. But on document I have not found for options api - javascript, I am not using typescript.
Below is my code, which is working without select and search. I want to select/search/filter the options like other we see. I have used bootstap jquery before, it was really easy integrate on application.
HTML code on template is -
<label class="col-lg-2 my-1 col-form-label" for="hospital_id">Select Hospital: </label>
<select class="form-control" v-model="patient.hospital_id" name="hospital_id" required >
<option value="" selected>Select Hospital</option>
<option v-for="hos in hospitals" :key="hos.id" :value="hos.id">{{ hos.name }}</option>
</select>
Vue Js code is -
<script>
export default {
data() {
return {
patient: {
hospital_id:'',
},
hospitals:{},
}
},
created() {
this.$axios.get('/sanctum/csrf-cookie').then(response => {
this.$axios.get('/api/users/getHospital')
.then(response => {
this.hospitals = response.data;
// console.log(this.hospitals)
})
.catch(function (error) {
console.error(error);
});
})
},
methods: {
addTelePatient() {
this.$axios.get('/sanctum/csrf-cookie').then(response => {
this.$axios.post('/api/tele-patients', {patient:this.patient})
.then(response => {
console.log(response.data)
this.$router.push({name: 'telePatients'})
})
.catch(function (error) {
console.error(error);
alert(error.message)
});
})
}
},
beforeRouteEnter(to, from, next) {
if (!window.Laravel.isLoggedin) {
window.location.href = "/admin/login";
}
next();
}
}
</script>
The performance of vue-next-select
is relatively poor when reaching thousand of options.
This can be experienced on this tweak of the playground
demo with 6000 options:
https://codesandbox.io/s/vue-next-select-performance-n93oq
Just open/close the select and hover on dropdown items, latency should be quite obvious.
Better performance - possibly by allowing the user to disable some event listeners? From the profiler view, a lot of time is spent dealing with mousemove
events when hovering options.
Profiler view. Red time span is during select dropdown open, yellow ones are during options hover. See how rendering speed collapses from 60 to 1/2 FPS.
When searchable is set to false the cursor is still "text" on the input.
And when searchable is true it's exact matching the labels you set, for example when you have the label "English", and you type "english" no options are found.
I am trying to use vue-next-select with multiple and taggable (i want to display the selected options)
<vue-select
:options="cats"
v-model="modelCats"
label-by="category"
track-by="id"
value-by="id"
close-on-select
multiple
taggable
hide-selected
/>
an in data() i have this:
cats: [
{id: 1, category: 'Cat 1'},
{id: 2, category: 'Cat 2'},
{id: 3, category: 'Cat 3'},
{id: 4, category: 'Cat 4'},
{id: 5, category: 'Cat 5'},
{id: 6, category: 'Cat 6'},
{id: 7, category: 'Cat 7'},
{id: 8, category: 'Cat 8'}
],
modelCats: [1,4]
and it apears all 8 cats as tags (see the picture)
What I did wrong?
Describe the bug
When an options is computed object, the dropdown will not updated when it changes.
To Reproduce
A reproduce link: https://codesandbox.io/s/vue-next-select-issue-207-u54hc
Steps to reproduce the behavior:
Expected behavior
There should only have three option.
Firstly - great component, thanks!
Idea/Issue
It feels natural to be able to close the dropdown by clicking on the main element (e.g. the input) again.
Currently, doing so causes a 'flash' where the dropdown closes on mouseDown but then opens again on mouseUp.
Secondly, if you use the 'Toggle' slot for a custom toggle icon, clicking this no longer works to close the dropdown.
Solution
Either make it the default behaviour or provide an option to make clicking anywhere on the main element close the dropdown.
GIF to show what I mean
Thanks again.
Feature
Support customization for adoption look and feel of bootstrap, or may be any other css library.
Solution
Do component withe label
Describe the bug
The dropdown doesn't automatically scroll to the selected item on page load when you open it.
To Reproduce
Go to https://codesandbox.io/s/wonderful-snowflake-ywwzb?file=/src/App.vue
Click on the select.
Expected behavior
The dropdown should be scrolled to the selected item "Netherlands".
Hi all,
one feature the vue-select-package was (and is!) missing is the possibility to have option groups (similar to the html select). Anyone thought about this yet?
Feature wishlist:
Cheers! :)
First of all, thank you for your work :)
Describe the bug
I'm not sure if this a bug or I'm just missing something. But is it possible that vue-next-select fields can't handle the required property? I haven't found it in the api reference, and setting a vue-next-select field to required will not trigger html5 validation.
Expected behavior
Trigger html5 validation
Describe the bug
When searchable is turned on, and you type for example "ca" and select the option "cars" ca is put as value in the select.
this looks like to be the model value of the input. But when you change the "modelvalue" attribute on the input using @selected
the value stays "ca"
OR is it something i'm doing wrong and do I need to change something else to see the selected option value inside the input?
Describe the bug
Property "searchable" was accessed during render but is not defined on instance.
Steps to reproduce the behavior
1)
import 'vue-next-select/dist/index.css'
import 'vue-next-select/dist/vue-next-select.cjs.js'
import VueNextSelect from 'vue-next-select'
component registeration: 'vue-select': VueNextSelect,
HTML: <vue-select v-model="searchable" :options="[{ color: 'Red' }, { color: 'Green' }]" label-by="color" type="checkbox"> </vue-select>
@iendeavor @akolov @schelmo @emargareten
Describe the bug
Is not possible to change the view when item selected and input is searchable.
Expected behavior
When item selected show custom label slot. On focus switch to the search input
Screenshots
Result:
Expected result:
Code:
<vue-select
:options="getCustomers"
v-model="form.customer_id"
:closeOnSelect="true"
:clearOnSelect="true"
:clearOnClose="true"
labelBy="name"
value-by="id"
placeholder="Select customer"
@selected="selectCustomer"
>
<template #label="{ selected }">
<div class="flex flex-1 items-center gap-2 leading-4 px-2 py-1 text-sm">
<div :class="'color-' + selected.color || ''" class="flex justify-center items-center w-7 h-7 text-xs font-medium rounded-lg">
{{ selected.initial }}
</div>
<div>
{{ selected.name }}
</div>
</div>
</template>
<template #dropdown-item="{ option }">
<div class="flex items-center gap-2">
<div :class="'color-' + option.color" class="flex justify-center items-center w-7 h-7 text-xs font-medium rounded-lg -my-0.5">
{{ option.initial }}
</div>
<div>{{ option.name }}</div>
</div>
</template>
</vue-select>
Firstly, great component, easy to integrate and gets the job done.
Issue:
I am using this as an item selector for an invoicing web app, and would like to be able to edit the invoice, and load the saved items. However, I am unable to pre-select the saved item with this component, and I can't find my case in the documentation.
Is your feature request related to a problem? Please describe.
I would like to use vue-next-select in vuejs 3.2 project in a script tag in lang typescript
<script lang="ts">
import { computed, ref } from "vue";
import VueNextSelect from "vue-next-select";
...
</script>
But when i do so i get the error:
Describe the solution you'd like
So dunno if it a bug or feature request,
but i would like to hav a declaration file for the module vue-next-select.
Describe the bug
vue-use-popperjs only support 14 version
Steps to reproduce the behavior:
Additional context
Maybe you can add support some different library
Describe the bug
When the select component is disposed with the select drawer open, an Uncaught TypeError
is thrown.
Steps to reproduce the behavior:
vue-next-select
component nested inside.Expected behavior
There should be no error thrown.
Desktop (please complete the following information):
Smartphone (please complete the following information):
Additional context
Problem seems to be related to the wrapper
ref value being called on line 342
being null
.
https://github.com/iendeavor/vue-next-select/blob/9fe934b12c684766093aa2239c48e8b0870969d9/src/index.vue#L341-L349
New prop: clear on close: boolean
, default is false
(backward compatible)
您好!正在尋找 Vue 3.x 的 select 方案時看到這個專案,great work! The single-page documentation is also excellent!
想請教一下:Single select,若重複點選同一個 option,會有 toggle 的效果,這似乎與一般 html 的 select 效果有所差異,可能也和一般使用者期待的體驗不同。是否考慮在 props 中增加此開關(目前我在 props 中並未發現……)?
本來 issue 要用英文寫的,看到閣下同樣來自台灣,有點高興!請容許我用中文表達(可能比較順)……
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.