Vue select change event firing before I trigger any action - javascript

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.

Related

Getting the value of an select in Vue.js

Well, I am trying to get the selected value of a select. This is the html code for the select:
<select id="employee">
<option v-bind:key="employee" v-for="employee of employees" v-bind:value="{id: employee.id}">{{ employee.name }}</option>
</select><br><br>
This is the JavaScript code where I would like to print the value of the select to the console.
console.log(document.getElementById('employee')[0].value)
First off, I don't think you need to access the 0th element when calling getElementById.
console.log(document.getElementById('employee').value).
Then, you are using vue! Make use of v-model.
The code below is not tested, use it as a guide only.
<template>
<select id="employee" v-model="selectedEmployee">
<option v-bind:key="employee" v-for="employee of employees" v-bind:value="{id: employee.id}">{{ employee.name }}</option>
</select>
</template>
<script>
export default {
data: {
selectedEmployee: null
},
watch: {
selectedEmployee: (newVal) => { console.log(newVal) }
}
}
</script>
If you are not aware of v-model, you don't know Vue.
Read about Form Input Bindings in Vue

Vue.js 2 Multiple Properties defined in one Single-File component

I am working on a Laravel 5.5 & Vue.js 2.x project, after several digging searchs and questions I came to components. But still I have a warning message when the page renders:
[Vue warn]: Property or method "trimestral" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property. See: https://v2.vuejs.org/v2/guide/reactivity.html#Declaring-Reactive-Properties.
(found in < Root >)
I have the following Single-File component in a Vue file: FormExpenses.vue:
<template>
<div class="input-group">
<input class="form-control" type="number" min="0" name="expenses" id="expenses" v-model="expenses">
<div class="input-group-btn">
<select class="form-control" name="expenses_range" id="expenses_range" v-model="expensesRange" :disabled="expenses < 1">
<option value="" disabled="">Elija el rango de expensas</option>
<option value="mensual">Mensual</option>
<option value="trimestral">Trimestral</option>
<option value="cuatrimestral">Cuatrimestral</option>
<option value="semestral">Semestral</option>
<option value="anual">Anual</option>
</select>
</div>
</div>
</template>
<script>
module.exports = {
props: {
amount: {
type: Number,
default: 0
},
range: {
type: String,
default: '',
}
},
data: function() {
return {
expenses: this.amount,
expensesRange: this.range,
}
},
}
</script>
I have registered the component "correctly" since some data seems to work. This is in the Vue instance file. Besides, I have defined the following element which seems it renders well in the form:
<expenses-form
:amount="#if(old('expenses')) {{ old('expenses') }}#elseif(isset($property) && $property->expenses) {{ $property->expenses }}#endif"
:range="#if(old('expenses_range')) {{ old('expenses_range') }}#elseif(isset($property) && $property->expenses_range) {{ $property->expenses_range }}#endif"
></expenses-form>
This seems to be working because it shows the following while rendering:
As seen, the first field is being rendered with their functions and data, but not the second one, despite according to Vue.js documentatiob seems to be ok.
Any comment is appreciated.
Vue expects range to be a string, but you're using v-bind (:range and Vue treats trimestral as variable, which is not defined), when passing a prop, instead of :range="..." use range="".
More you can read in docs here: https://v2.vuejs.org/v2/guide/components.html#Literal-vs-Dynamic

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>

VueJS checkbox update

I'm a little wired with VueJS states.
This is my simple app :
new Vue({
el: '#media-app',
data: {
activeTypes: [],
activeCategories: [],
medias: []
},
methods: {
getFilteredData: function () {
// some computing needed
// refresh vue
Vue.set(me, "medias", []);
},
filterMedia: function () {
console.debug(this.activeCategories);
console.debug(this.activeTypes);
this.getFilteredData();
}
}
});
And some HTML stuff:
<input type="checkbox" id="i1" value="i1" class="filter categories" v-model="activeCategories" v-on:click="filterMedia()">
<label for='i1'>My cat 1</label>
</div>
#{{ activeCategories }}
When I check the checkbox, the template displays #{{ activeCategories }} correctly with "i1". But the console.debug(this.activeCategories) displays an empty array. I have to put that debug into an updated method to get the correct value. But if I do that, I cannot call a method which change the data or I'll get into an infinity loop…
So, where should I call my filterMedia function to be able to access updated values from activeCategories ?
Thanks for your help.
Try the onchange event:
<input type="checkbox" id="i1" value="i1" class="filter categories"
v-model="activeCategories" v-on:change="filterMedia()">

Vue js: Multiple options selection

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>

Categories

Resources