VueJS Multiselect change default for all selects - vue.js

Im using the vue-multiselect.js (https://vue-multiselect.js.org/).
Atm I need to translate all text to german. Atm Im doing it with customs inside the multiselect
<multiselect id="account-selected" #input="selectParent" v-model="account.parent_account" placeholder="Tippen um Suche zu starten" :multiple="false" ... :options="optionsParents">
<span slot="noResult">Suche ergab keine Treffer</span>
<span slot="noOptions">Keine Optionen</span>
</multiselect>
Its working fine, but Im using these multiselects frequently. So its a pain to maintain it. I need to change it at every multiselect in every component. Is there a way to define these "noResult", "noOptions", "placeholder" etc globally? So its the same for every multiselect in every component?

You can make your own Multiselect component based on vue-multiselect
Here is the demonstration I make in codesandbox for your reference:
https://codesandbox.io/s/dazzling-yonath-pjsxt?file=/src/components/CustomMultiSelect.vue
The idea is to make a vue component which only have vue-multiselect and set all fixed settings there, like placeholder, slot. For all dynamic value, it can be retrieved by value/event ($attrs, $listeners) pass though provided by vue.
CustomMutliSelect.vue
<template>
<multiselect
v-bind="$attrs"
v-on="$listeners"
placeholder="Tippen um Suche zu
starten"
>
<span slot="noResult">Suche ergab keine Treffer</span>
<span slot="noOptions">Keine Optionen</span>
<!-- Below template for Testing -->
<template slot="singleLabel" slot-scope="{ option }"
><strong>{{ option }}</strong> is written in<strong>
{{ option }}</strong
></template
>
</multiselect>
</template>
App.vue
<CustomMultiSelect
id="account-selected"
v-model="value"
:multiple="false"
:options="options"
/>
With CustomMultSelect, you can apply it everywhere without duplicating placeholder and slots.

Related

Vue-multiselect - Vue3 - Slots not working

I'm trying to recreate the following example from Vue-multiselect document in Vue 3 but I can't seem to make it work.
<multiselect
v-model="value"
:options="options"
:multiple="true"
:close-on-select="false"
:clear-on-select="false"
:preserve-search="true"
placeholder="Pick some"
label="name"
track-by="name"
:preselect-first="true">
<template slot="selection" slot-scope="{ values, search, isOpen }">
<span
class="multiselect__single"
v-if="values.length"
v-show="!isOpen">
{{ values.length }} options selected
</span>
</template>
</multiselect>`
The documentation states that "Documentation for v3.0.0 is the same as for v2.x as it is mostly backward compatible." As there's no specific examples or notes about using slots in Vue 3 I thought that if I changed the component name from 'multiselect' to 'VueMultiselect' it would work but it's not.
The select part is working just fine but when I close the dropdown the custom template doesn't show. It's just the normal tags.
Am I missing something or is the feature not fully migrated to Vue 3?
VueMultiselect's documentation concerning named slots is out of date when it comes to Vue 3 syntax. slot and slot-scope attributes were deprecated in Vue 2.6 (but will continue to be supported in Vue 2.x going forward), and have been completely removed in Vue 3. Your slot in Vue 3 should be written like so:
<template v-slot:selection="{ values, search, isOpen }">
or short-hand:
<template #selection="{ values, search, isOpen }">
Documentation with more information: Named Scoped Slots in Vue 3

Passing slots through from Parent to Child Components

I have built a user-defined component (async-select) on top of another component (vue mutliselect) like this:
https://jsfiddle.net/2x7n4rL6/4/
Since the original vue-multiselect component offers a couple of slots, I don't want to loose the chance to use them. So my goal is to make these slots available from inside my custom component. In other words, I want to something like this:
https://jsfiddle.net/2x7n4rL6/3/
But that code oes not work.
However, if I add the slot to the child component itself, it works just fine (which you can see from the fact that options become red-colored).
https://jsfiddle.net/2x7n4rL6/1/
After surfing the web, I have come across this article, but it does not seem to work
Is there any way in VueJS to accomplish this ?
Slots can be confusing!
First, you need a template element to define the slot content:
<async-select :value="value" :options="options">
<template v-slot:option-tmpl="{ props }">
<div class="ui grid">
<div style="color: red">{{ props.option.name }}</div>
</div>
</template>
</async-select>
Then, in the parent component, you need a slot element. That slot element itself can be inside of another template element, so its contents can be put in a slot of its own parent.
<multiselect
label="name"
ref="multiselect"
v-model="localValue"
placeholder="My component"
:options="options"
:multiple="false"
:taggable="false">
<template slot="option" slot-scope="props">
<slot name="option-tmpl" :props="props"></slot>
</template>
</multiselect>
Working Fiddle: https://jsfiddle.net/thebluenile/ph0s1jda/

How to pass v-model to parent in vue-multiselect

i have two components.
One is vselect template and wrapper for vue-multiselect.
<template lang="pug">
field-wrapper.field(:label="label" :caption="caption" :error="error")
multiselect(v-model="value" :options="options")
</template>
Second is page.vue where im including it
vselect(v-model="select.value" :options='select.options')
p {{ select.value }}
But v-model works only inside vselect, how i cant pass selected data to page.vue, from vselect? I cant use new method for emit in page.vue. Vue-multiselect works only with v-model i guess?
When i have a case with input, what works for me
<template lang="pug">
field-wrapper.field(:label="label" :caption="caption" :error="error")
input.form-input(:type="computedType" :value="value" :disabled="disabled" :placeholder="placeholder" #keyup="removeError" #input="$emit('input', $event.target.value)")
</template>
#input="$emit('input', $event.target.value) - i solve problem like this, but ints not work with plugin vuemultiselect

Vue-Multiselect Plugin: How to safely remove "add a new" tag functionality?

I am using a plugin called Vue-Multiselect and have it working pretty good on my app. However, there is a functionality in the plugin that I do no want. How can I safely remove it?
Let me explain: CodeSandBox Collaboration Editor .
Note: To see this flow in action, choose EDIT next to ACME Widget and then search for an on existent user in the multiselect input box.
When a user is searched for in the multiselect input box, and if a match is found, the match pops up for the user to select. That is good. However, when a user is NOT found, there's a placeholder text that says the following: Press enter to create a tag . I do NOT want to give my users the ability to create new tags/options if the option does not exist. How can I remove that functionality from this component?
Here is my multi-select component code:
<multiselect
id="customer_last_name_input"
v-model="values"
:options="options"
label="lastname"
placeholder="Select or search for an existing customer"
track-by="uid"
:loading="isLoading"
:custom-label="customerSelectName"
aria-describedby="searchHelpBlock"
selectLabel
:multiple="true"
:taggable="true"
>
<template
slot="singleLabel"
slot-scope="props"
>{{ props.option.lastname }}, {{props.option.firstname}}</template>
<template slot="option" slot-scope="props">
<strong>{{ props.option.lastname }}</strong>
, {{ props.option.firstname }} —
<small>{{ props.option.email }}</small>
</template>
<!-- <template slot="noResult">Looks like this customer doesn't exist yet.<button class="btn btn-primary" type="button" #click="addCustomer">Add Customer</button></template> -->
</multiselect>
I found the answer. I simply remove the taggle=true prop from the multiselect component.

Vue js multiselect hide triangle with empty

I'm using the vue-multiselect library. How can I hide this triangle if the data is empty?
<multiselect v-model="user.majors" id="majorsSearch" label="name" track-by="id" placeholder="Search majors..." select-label="Select" :options="majorsBag" :multiple="true" :loading="isLoadingMajors" :internal-search="false" :clear-on-select="true" :close-on-select="true" #search-change="asyncFindMajors">
<template slot="tag" scope="props"></template>
</multiselect>
You can replace the default dropdown button by providing the caret slot; in your situation you can use an empty <span>, try something like this:
<multiselect v-model="user.majors">
<span slot="caret" v-if="!user.majors.length"></span>
</multiselect>