v-on:change does not work for vue-multiselect - vue.js

I am using vue-multiselect component in my vue.js project, I am using v-on directive to execute a function on the change event ,
<multiselect v-model="selected" :options="projects" :searchable="false" :custom-label="customLabel" track-by="name" v-on:change="executeLoader">
<template slot="customLabel" slot-scope="{ customLabel }"><strong>{{ option.name }}</strong></template>
</multiselect>
I have example full code here: https://codesandbox.io/s/yjjon0vzxj
the v-on:change was working with <select> component but it stopped workigng with vue-multiselect ! I tried with v-on:click="executeLoader" but that too didnt worked either..

#click will not trigger the method executeLoader with vue multiselect. You can use #input - which is similar to v-on:change, #close, #select as in example below:
<multiselect placeholder="Pick at least one"
select-label="Enter doesn’t work here!"
:value="value"
:options="options"
:multiple="true"
:searchable="true"
:allow-empty="false"
:hide-selected="true"
:max-height="150"
:max="3"
:disabled="isDisabled"
:block-keys="['Tab', 'Enter']"
#input="onChange"
#close="onTouch"
#select="onSelect">
</multiselect>
In your case I would try #input="executeLoader"

In vue-multiselect, since it is a component you can't treat it to behave like a simple <select> element.
In components, when you expect them to behave and "listen" to click events just like other html tag, then you should add an event modifier called: .native.
So, you can do on any component:
<... #click.native="executeLoader" />
But that is not what you are looking for I think. You want to trigger a function when you add more and more tags, or in short: when the selected items increase.
for that, vue-multiselect exposes the #input event, so you can handle using:
<... #input="executeLoader" />
And now just call executeLoader and accept the arguments as:
methods: {
executeLoader(selectedItems) {}
}

Related

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/

b-field value is getting updated only #select and not #input?

I am using the Buefy UI components in my VueJS project. I have a drop-down in a page:
<b-field label="Business Unit">
<b-autocomplete
:data="dataBusinessUnit"
placeholder="select a business unit..."
field="businessUnit"
:loading="isFetching"
:value="this.objectData.businessUnit"
#typing="getAsyncDataBusinessUnit"
#select="(option) => {updateValue(option.id,'businessUnit')}"
>
<template slot-scope="props">
<div class="container">
<p>
<b>ID:</b>
{{props.option.id}}
</p>
<p>
<b>Description:</b>
{{props.option.description}}
</p>
</div>
</template>
<template slot="empty">No results found</template>
</b-autocomplete>
</b-field>
As you can see from the above code, the updateValue function is responsible for updating the value, but it will currently be called only when the user selects something from the drop-down suggestions. I want the value to be updated even when the user starts to type something. Example: #input="(newValue)=>{updateValue(newValue,'businessUnit')}". However, there is already a debounce function called getAsyncDataBusinessUnit that I am calling to fetch the filtered autocomplete results based on what the user has typed during the #typing event.
According to the Buefy Autocomplete API documentation found here, you could probably use v-model instead of using value directly.
Alternatively you could actually implement the #input like you wrote yourself, the #typing event shouldn't interfere with it.
Or you could just handle the value updating in #typing:
#typing="onTyping"
// then later in JS...
methods: {
onTyping(value) {
this.updateValue(value, 'businessUnit')
this.getAsyncDataBusinessUnit(value)
},
}

Vuetify custom v-text-field component is not updating the v-model

I’m following this documentation: https://v2.vuejs.org/v2/guide/components.html
I created custom v-text-field component which looks like that:
<template>
<div>
<v-text-field
:label="label"
v-bind:value="value"
v-on:input="$emit('input', $event.target.value)"></v-text-field>
</div>
</template>
<script>
export default {
name: "txtbox",
props: ['value', 'label'],
}
</script>
I implemented it in my main component almost succesfully:
<txtbox
label="Name"
v-model="eventName"
/>
I don’t think it is necessary to paste all the code, but if it is I will edit the post. Here is how it works:
I have a list, when i click on the list element the text-field displays content of it, this works fine. Sadly when I’m editing the content of text-field the v-model value is not updating. I can also add that it works fine with normal (like in the docs) instead of . Is there anything I can do to make it work, or should i use simple input ?
Thanks
When you want to $emit the new value, you just have to emit the $event, and not $event.target.value
<template>
<div>
<v-text-field
:label="label"
v-bind:value="value"
v-on:input="$emit('input', $event)"></v-text-field>
</div>
</template>
v-on:input can also be shortened to just #input

Vue bootstrap on blur event

I am not able to use vue on blur event,
In my component I have a #change directive
<b-input :value="value" #change="validateEmail($event)" #input="$emit('input', $event)" ref="input" :state="state"/>
This is because #blur doesn't seem to work.
Bootstrap vue on:blur handler is not been called
This works partially when I am changing the input and hit tab, then works, but if I focus on the input and click tab without changing the input, it doesn't work.
I want to show a message that email is required in this case but I cannot.
You may use #blur.native with Bootstrap Vue inputs.
<b-input
:value="value"
#change="validateEmail($event)"
#input="$emit('input', $event)"
ref="input"
:state="state"
#blur.native="handleBlur"
/>
https://github.com/bootstrap-vue/bootstrap-vue/issues/1645#issuecomment-369477878
you can use #blur.native="function"

Vue, change native event not working, input native does

I have a question and maybe a Vue bugg.
I have a custom component that needs a #change.native event. But it does not trigger anything and I could not find anything about this issue myself.
So i tried some different stuff and like #click.native and #input.native does work. Even tho #input.native works and do the trick i want to, i still want to know why the change event does not work.
Anybody? Else I should report this.
Vue version: 2.5.2
<custom-input type="search"
placeholder="search"
v-model="search"
#input.native="change" />
If the <input /> inside the custom component is a child element of another element, then the event listener bound by the .native modifier will not be reached, since it is listening to the event of a different element.
custom-input.vue:
<template>
<div>
<input :value="someValue" />
</div>
</template>
<script>
export default {
props: ['value']
}
</script>
so if you have this scenario, then the #change.native will be bound on the <div> (the wrapper).
(sadly) You need to manually propagate the event manually.