I have a rather simple component. Basically it is a dropdown select
and I need to run some custom code that is in an external javascript function. However, this prop is not required on every instance of the component. So sometimes there may be nothing in the prop. Other times it might do one thing, others might do something else.
<template id="drop-list-template">
<select class="form-control"
v-model="value"
v-bind:class="{ required: isRequired, invalid: !isValid }"
v-on:blur="validate"
v-on:change="changed"> <-- This is the Prop I want to use
<option v-if="showEmptyOption" value="">{{ emptyOption }}</option>
<option v-for="i in items"
v-bind:value="i.value"
v-bind:selected="i.checked === value"
v-bind:disabled="i.enabled === false">
{{ i.text }}
</option>
</select>
</template>
So in the on-change
event, it will call the changed
method. That was not working. I then added a special
prop to the code file:
Vue.component("drop-list", {
template: "#drop-list-template",
props: {
dataset: { type: Array, required: true },
isRequired: { type: Boolean, required: false, default: false },
emptyOption: { type: String, required: false, default: "*Select an Option *" },
showEmptyOption: { type: Boolean, required: false, default: true },
special: { required: false }
},
data: function () {
return {
items: this.dataset,
isValid: true,
value: ""
}
},
methods: {
validate: function (event) {
var Result = true;
if ((this.isRequired === true) && (this.value === ""))
Result = false;
this.isValid = Result;
return Result;
},
changed: function (event) {
if (this.special) {
AbnormalitiesAndImpressions(); <-- Obviously this works
alert("After");
this.special(); <-- Would want this to run AbnormalitiesAndImpressions
}
}
}
});
And implement it via:
<drop-list ref="lstAbnormalities"
v-bind:dataset="Abnormalities"
v-bind:is-required="true"
special="AbnormalitiesAndImpressions">
</drop-list>
Where AbnormalitiesAndImpressions
is just dumb right now:
function AbnormalitiesAndImpressions(lstAbs, lstImps) {
alert("Got to here");
}
When I run it, the "Got to here" alert pops up and so does the "After" alert. It then fails because this.special();
is not a function.
Bottom line is I am trying to let the user (myself in this case) create as many of these lists as needed. What will happen on some of them is they tweak what is available in other controls. So a sort of validation is going on. I just want this to be customizable per each use of the component.
I would even be fine with an anonymous function like the following:
<drop-list ref="lstAbnormalities"
v-bind:dataset="Abnormalities"
v-bind:is-required="true"
special="function () { AbnormalitiesAndImpressions(); }">
</drop-list>
Update I have updated my component slightly:
<template id="drop-list-template">
<select class="form-control"
v-model="value"
v-bind:class="{ required: isRequired, invalid: !isValid }"
v-on:blur="validate"
v-on:change="change">
<option v-if="showEmptyOption" value="">{{ emptyOption }}</option>
<option v-for="i in items"
v-bind:value="i.value"
v-bind:selected="i.checked === value"
v-bind:disabled="i.enabled === false">
{{ i.text }}
</option>
</select>
</template>
And the corresponding javascript:
Vue.component("drop-list", {
template: "#drop-list-template",
props: {
dataset: { type: Array, required: true },
isRequired: { type: Boolean, required: false, default: false },
emptyOption: { type: String, required: false, default: "*Select an Option *" },
showEmptyOption: { type: Boolean, required: false, default: true },
special: { type: Function, required: false }
},
data: function () {
return {
items: this.dataset,
isValid: true,
value: ""
}
},
methods: {
change: function (event) {
if (this.special)
this.special();
}
}
});
And the implementation:
<drop-list ref="lstAbnormalities"
v-bind:dataset="Abnormalities"
v-bind:is-required="true"
:special="AbnormalitiesAndImpressions">
</drop-list>
And here is the page's Vue code:
var vm = new Vue({
el: "#app",
data: {
Result: {},
Defaults: {},
Errors: [],
Abnormalities: [],
Impressions: []
},
methods: {
AbnormalitiesAndImpressions: function () {
alert("Should get overridden");
}
}
});
vm.AbnormalitiesAndImpressions = function (lstAbs, lstImps) {
alert("Got to here: " + lstAbs + "\n" + lstImps);
}
I found that if I did not add the methods
short version of AbnormalitiesAndImpressions
that it would give me a Vue warning that the property did not exist. However, the version of AbnormalitiesAndImpressions
at the bottom of that file actually runs. I like this as each implementation could change and they should be on the page and not on the component.
When I change the dropdown item, I do get the Got to here
message. And of course it has two undefined
as the lstAbs
and lspImps
were not passed in.
New Question
Is it possible then to pass values to my props function? In this case, they can be strings
. But if I do the code below...
<drop-list ref="lstAbnormalities"
v-bind:dataset="Abnormalities"
v-bind:is-required="true"
:special="AbnormalitiesAndImpressions('test')">
</drop-list>
When the page loads, the alert
is popped right away and Does have the test
parameter. And when I actually change the select
the alert
does not fire at all.