Vue js: Multiple options selection - javascript

Objective: To Select multiple options of a select tag.
Attempt: The documentation says: to implement a multi-select input, the property to be bound using v-model should be an array.
Errors: [Vue warn]: expects an Array value for its binding, but got String.
The value bound to (multipleSelections), is an array, so what is the reason for this?
Here is the jsfiddle.
script:
new Vue({
el:'#app',
data: function() {
return {
multipleSelections: ["Mr Potato (Manager)"],
data: null,
multiple: "true",
assets:["Mr Potato (Manager)", "Mr Blade (Manager)", "Mrs Spice (Manager)"]
}
},
created() {
console.log("selections: ",this.multipleSelections);
}
});
html:
<script src="https://unpkg.com/vue#2.0.6/dist/vue.js"></script>
<div class='container' id='app'>
<h2>{{"title".toUpperCase()}}</h2>
<p class='center help-text' v-if="multiple === 'true'">(Use ctrl or cmd to select multiple)</p>
<select
:multiple="multiple === 'true'"
v-bind:class="{ 'fix-height': multiple === 'true' }"
v-model="multipleSelections"
>
<option
v-for="asset in assets"
:value="asset">
{{asset}}
</option>
</select>
{{ multipleSelections }}

Just giving multiple="true" in select works. Here is jsfiddle link.
<select
multiple="true"
v-bind:class="{ 'fix-height': multiple === 'true' }"
v-model="multipleSelections"
>

I found this plug-in did the trick if your looking for something full featured. It also has great documentation (see links below).
https://vue-multiselect.js.org/
After you install the library check out the example straight from the documentation:
https://vue-multiselect.js.org/#sub-getting-started
<!-- Vue component -->
<template>
<div>
<multiselect v-model="value" :options="options"></multiselect>
</div>
</template>
<script>
import Multiselect from 'vue-multiselect'
// register globally
Vue.component('multiselect', Multiselect)
export default {
// OR register locally
components: { Multiselect },
data () {
return {
value: null,
options: ['list', 'of', 'options']
}
}
}
</script>
<!-- New step!
Add Multiselect CSS. Can be added as a static asset or inside a component. -->
<style src="vue-multiselect/dist/vue-multiselect.min.css"></style>
<style>
your styles
</style>

Related

How to use vue-multiselect tagging inside asp .net solution using VS 2017?

I'm trying to use vue-multiselect tagging, but im getting some errors like:
"vue.js:634 [Vue warn]: Unknown custom element: - did you register the component correctly? For recursive components, make sure to provide the "name" option."
And:
"SyntaxError: The requested module 'https://unpkg.com/vue-multiselect#2.1.0' does not provide an export named 'default'"
Can Anyone helps me?
my script:
<script type="module">
import Multiselect from 'https://unpkg.com/vue-multiselect#2.1.0'
export default {
components: {
Multiselect
},
data() {
return {
value: [
{ name: 'Javascript', code: 'js' }
],
options: [
{ name: 'Vue.js', code: 'vu' },
{ name: 'Javascript', code: 'js' },
{ name: 'Open Source', code: 'os' }
]
}
},
methods: {
addTag(newTag) {
const tag = {
name: newTag,
code: newTag.substring(0, 2) + Math.floor((Math.random() * 10000000))
}
this.options.push(tag)
this.value.push(tag)
}
}
}
</script>
my html code:
<div>
<label class="typo__label">Tagging</label>
<multiselect v-model="value" tag-placeholder="Add this as new tag" placeholder="Search or add a tag" label="name" track-by="code" :options="options" :multiple="true" :taggable="true"></multiselect>
<pre class="language-json"><code>{{ value }}</code></pre>
</div>
First include the files:
<script src="https://unpkg.com/vue-multiselect#2.0.6"></script>
<link rel="stylesheet" href="https://unpkg.com/vue-multiselect#2.0.6/dist/vue-multiselect.min.css">
Then, register the component:
components: {
Multiselect: window.VueMultiselect.default
},
I found the solution here:
https://github.com/shentao/vue-multiselect/issues/643
I think using a custom control like vue-multiselect with support for tagging is what you are looking for. See here.
To render the list of "Exporters" you must set the select options to be dynamic. According to the Vue.js docs you need to do something like:
<select v-model="selected_exporter">
<option v-for="exporter in exporters" v-bind:value="exporter.value">
{{ exporter.description }}
</option>
</select>
<span>Selected: {{ selected_exporter }}</span>
Then you want to put a input if the exporter does not exists yet, you can use the v-if to show or hide the input.

Vue select change event firing before I trigger any action

I have a Vue app that seems to fire the change event even before I change the selection, recently tried the #input instead but still the same thing happens(as shown below)
Please note I have tried #change and #input and the event still fires on loading of the controls
Now this was working before I made css changes to scope the component, so that it doesn't effect the surrounding css. But cant fathom why this would make any difference.
Does anyone know why when adding the options tag and contents would make the change event fire?
<div class="form-group" :class="{formError: errors.has('formSection')}">
<label for="formSection">Section*</label>
{{ formModel }}
<select
v-model="formModel.idSection1"
class="form-control"
id="formSection"
name="formSection"
#input="onChangeSectionLevel1">
<option v-for="sectionLevel1 in formModel.sectionLevel1"
v-bind:value="sectionLevel1.value"
v-bind:key="sectionLevel1.id">
{{ sectionLevel1.value }}
</option>
</select>
<span v-if="errors.has('formSection')">This field is required</span>
</div>
As soon as I add in the options tag which loops through the items the onChangeSectionLevel1 function gets called. I thought it might be vee-validate but taken this out and still happens.
methods: {
onChangeSectionLevel1() {
alert("changed");
...
}
}
Update:
I have noticed that if I print out the object that is being bound, I get this which missing the idSection1 item.
{
"idSection2": null,
"idSection3": null,
}
If I then just put a dummy option as below then I can see my 3 data items including the idSection1 that is missing if I loop through with the v-for
<select
v-model="formModel.idSection1"
class="form-control"
id="formSection"
name="formSection"
#change="onChangeSectionLevel1">
<option>Hello World</option>
</select>
The data item still has the idSection1 listed
{
"idSection1": null,
"idSection2": null,
"idSection3": null
}
Many thanks in advance
Not really an answer, but the code above is find and works as expected in js fiddle
https://jsfiddle.net/andrewp37/a4obkhd5/1/
Code:
<div id="app">
<label for="formSection">Section*</label>
{{ formModel }}
<select
v-model="formModel.idSection1"
class="form-control"
id="formSection"
name="formSection"
#change="onChangeSectionLevel1">
<option v-for="sectionLevel1 in formModel.sectionLevel1"
v-bind:value="sectionLevel1.value"
v-bind:key="sectionLevel1.id">
{{ sectionLevel1.value }}
</option>
</select>
</div>
new Vue({
el: "#app",
data: {
formModel: {
idSection1: null,
sectionLevel1: [
{
id: 1,
value: "Section 1"
}
]
}
},
methods: {
onChangeSectionLevel1() {
alert("changed");
}
}
})
I had noticed that with lots of breakpoints added, the model was being replaces after the page was mounted.

Element Ui component is not rerendering on vue component prop change

I have a parent component and multiple child components, which use the same prop. This prop is an array of keys for a dropdown menu in element.js.
When the children render the first time, they contain no data. However, once the keys from arrive using vuefire the children get the dropdown menu items. However, the element dropdown menu is not rerendered as it should have been.
However using the vue dev tools, I can see that the dropdown menu entries have been passed down as a key. When vue does a hot reload, because of a file change, the keys will load.
Once the entries are loaded, I can select the entry and everything works as expected.
I also had the same results using the vuetify dropdown and the HTML dropdown. Both have the same issue.
parent
<template>
<div class="setup">
<h1>Setup</h1>
<div class="selectIngredients" v-for="number in 6">
<setupSelection :bottle="number" :ingredients="options" />
</div>
</div>
</template>
<script>
import {db} from "#/firebaseConfig"
import setupSelection from '#/components/setupSelection';
export default {
components: {
setupSelection,
},
firestore: {
options: db.collection('ingredients'),
},
};
</script>
child
<template>
<div class="ingredientSelector">
<h3>Select for Pump <span>{{bottle}}</span></h3>
<el-select v-model="selected" clearable placeholder="Select" >
<el-option
v-for="ingredient in ingredients"
v-bind:key="ingredient.text"
v-bind:label="ingredient.text"
v-bind:value="ingredient">
</el-option>
</el-select>
<!-- <v-select
v-model="selected"
:items="ingredients"
label="Select a favorite activity or create a new one"
></v-select> -->
<!-- <select v-model="selected" v-for="ingredient in ingredients">
<option :value="ingredient.value">{{ingredient.text}}</option>
</select> -->
</div>
</template>
<script>
import {db} from "#/firebaseConfig";
export default {
props: {
ingredients: { required: true },
bottle: { type: Number, required: true },
},
data() {
return {
selected: ''
}
},
},
};
</script>
I expected the dropdown menu to update once the client received them.
Thank you!
I haven't used Vuefire myself but I read the following in the documentation:
Make sure to create any property added to firestore in data as well
https://github.com/vuejs/vuefire/tree/master/packages/vuefire#firestore-option
Similar advice is given here:
https://vuefire.vuejs.org/vuefire/binding-subscriptions.html#declarative-binding
In your example you don't have options in the parent's data. This would, presumably, leave it non-reactive, leading to the symptoms you describe.
Use a data property for your items, and set them after the options are loaded.
data() {
return {
options: []
}
},
created() {
db.collection('ingredients').then(data=> this.options = data}
}
The promise returned from db.collection('ingredients') is not reactive.
Even better approach would be to set options: null, and show a loading indicator until it is an array.

How can i make a click event on v-select?

I am using vue-select and I wanna make a click event when i select a item from the select list. I tried with #change="changedValue" #selected="changedLabel" but that does not works for me.
Vue select
<v-select placeholder="Add administrator" class="form-control-select" label="displayName" :options="items"></v-select>
Does anyone know how to trigger an event? Thanks
Since you did not provide a link to the component library you are using I'll assume you are using vue-select.
A quick look trough its source shows the component has an onChange prop which is called when the selected value changes and defaults to emitting the input event.
You can simply attach your changedLabel to #input:
Vue.component('v-select', VueSelect.VueSelect)
new Vue({
el: '#app',
data: {
items: [
'foo',
'bar'
],
selected: null
},
methods: {
changedLabel(event) {
this.selected = event;
}
}
})
<script src="https://unpkg.com/vue-select#2.4.0/dist/vue-select.js"></script>
<script src="https://unpkg.com/vue#2.5.16/dist/vue.js"></script>
<div id="app">
<v-select
placeholder="Add administrator"
class="form-control-select"
label="displayName"
:options="items"
#input="changedLabel"
></v-select>
<span>{{ selected }}</span>
</div>

vue.js v-bind:value is not working with select option form element

I have a strange problem, watching at the tutorials of vue.js here: https://v2.vuejs.org/v2/guide/forms.htmlthe the following code should work:
<div class="input-field">
<select v-model="selected">
<option v-for="couponType in couponTypes" v-bind:value="couponType" value="">{{ couponType }}</option>
</select>
<label>Tipo de cupon</label>
</div>
this template works with the following script:
<script>
export default {
data: function () {
return {
couponTypes: [ "V333333333333é",
"Vasdasdasd",
"V211111111Café",
"444444444444444444"
],
selected: "",
newCoupon: {
couponTypeSelected: "",
userId: ""
}
}
},
methods: {
SendCoupon: function () {
console.log(this.newCoupon)
console.log(this.selected)
}
},
created: function () {
$(document).ready(function() {
$('select').material_select();
$('.modal').modal();
});
}
}
When sendCoupon() is triggered it supposedly selected variable should print the value of the selected option in the select element, but it only prints an empty string that is the initial setted value.
I cannot reproduce your issue. Adding a button with a click event that calls your SendCoupon() method clearly demonstrates that each selected item is correctly output. See this working JSFiddle.
Template:
<div id="app">
<div class="input-field">
<select v-model="selected">
<option v-for="couponType in couponTypes" v-bind:value="couponType" value="">
{{ couponType }}
</option>
</select>
<label>Tipo de cupon</label>
<button #click="SendCoupon">Send</button>
</div>
</div>
JavaScript:
new Vue({
el: '#app',
data: function () {
return {
couponTypes: [ "V333333333333é",
"Vasdasdasd",
"V211111111Café",
"444444444444444444"
],
selected: "",
newCoupon: {
couponTypeSelected: "",
userId: ""
}
}
},
methods: {
SendCoupon: function () {
console.log(this.newCoupon)
console.log(this.selected)
}
},
created: function () {
}
})
Note that it is the selected property that is updated, not the newCoupon property since your select v-model is bound to the selected property.
After days searching about a solution I found that the cause of this error is the use of materializecss with vue.js on the templates. According to this reported issue ( github reported isssue ), materialize css modify the DOM when there is a select or ul (list) on the template of a .vue component. In the reported issue on Github there is a workaround: add browser-default as a class to the select element,this disables to materialize to modify the DOM element, then binding of vue could work. Here I drop an example.
<div class="input-field">
<select class="browser-default" id="selectoption" v-model="newCoupon.coupon">
<option v-for="selected in couponTypes" v-bind:value="selected">{{ selected }}</option>
<label for="selectoption">Cupon</label>
</select>
</div>

Categories

Resources