SAMPLE https://stackblitz.com/edit/usjgwp?file=index.html
to show a number of kendo dropdownlist(s) on a page. The exact number depends on an API call. This API call will give me an array of stakeholder objects. Stakeholder objects have the following properties: Id, name, type, role and isSelected.
The number of dropdownlist that has to be shown on this page should be equal to the number of unique type values in the API response array. i.e,
numberOfDropdowns = stakeholders.map(a => a.type).distinct().count().
Now, each dropdown will have a datasource based on the type property. i.e, For a dropdown for type = 1, dataSource will be stakeholders.filter(s => s.type == 1).
Also the default values in the dropdowns will be based on the isSelected property. For every type, only one object will have isSelected = true.
there is achieved these things by using the following code:
<template>
<div
v-if=”selectedStakeholders.length > 0”
v-for=”(stakeholderLabel, index) in stakeholderLabels”
:key=”stakeholderLabel.Key”
\>
<label>{ stakeholderLabel.Value }:</label>
<kendo-dropdownlist
v-model=”selectedStakeholders[index].Id”
:data-source=”stakeholders.filter(s => s.type == stakeholderLabel.Key)”
data-text-field=”name”
data-value-field=”Id”
\></kendo-dropdownlist>
<button @click=”updateStakeholders”>Update form</button>
</div>
</template>
<script>
import STAKEHOLDER_SERVICE from “somePath”;
export default {
name: “someName”,
props: {
value1: String,
value2: String,
},
data() {
return {
payload: {
value1: this.value1,
value2: this.value2
},
stakeholders: [],
selectedStakeholders: [],
stakeholderLabels: [] // [{Key: 1, Value: “Stakeholder1”}, {Key: 2, Value: “Stakeholder2”}, … ]
};
},
mounted: async function() {
await this.setStakeholderLabels();
await this.setStakeholderDataSource();
this.setSelectedStakeholdersArray();
},
methods: {
async setStakeholderLabels() {
let kvPairs = await STAKEHOLDER_SERVICE.getStakeholderLabels();
kvPairs = kvPairs.sort((kv1, kv2) => (kv1.Key > kv2.Key ? 1 : -1));
kvPairs.forEach(kvPair => this.stakeholderLabels.push(kvPair));
},
async setStakeholderDataSource() {
this.stakeholders = await STAKEHOLDER_SERVICE.getStakeholders(
this.payload
);
}
setSelectedStakeholdersArray() {
const selectedStakeholders = this.stakeholders
.filter(s => s.isSelected === true)
.sort((s1, s2) => (s1.type > s2.type ? 1 : -1));
selectedStakeholders.forEach(selectedStakeholder =>
this.selectedStakeholders.push(selectedStakeholder)
);
},
async updateStakeholders() {
console.log(this.selectedStakeholders);
}
}
};
</script>
The problem is that when not able to change the selection in the dropdownlist the selection always remains the same as the default selected values. Even when I choose a different option in any dropdownlist, the selection does not actually change.
I’ve also tried binding like this:
<kendo-dropdownlist
v-model=”selectedStakeholders[index]“
value-primitive=”false”
:data-source=”stakeholders.filter(s => s.type == stakeholderLabel.Key)”
data-text-field=”name”
data-value-field=”Id”
\></kendo-dropdownlist>
If I bind like this, when able to change selection but then the default selection does not happen, the first option is always the selection option i.e, default selection is not based on the isSelected property.
My requirement is that there is to show the dropdown with some default selections, allow the user to choose different options in all the different dropdowns and then retrieve all the selection then the update button is clicked.
UPDATE:
When I use the first method for binding, The Id property of objects in the selectedStakeholders array is actually changing, but it does not reflect on the UI, i.e, on the UI, the selected option is always the default option even when user changes selection.
Also when I subscribe to the change and select events, I see that only select event is being triggered, change event never triggers.
Solution :
So it turns out that it was a Vue.js limitation (or a JS limitation which vue.js inherited),
Link
I had to explicitly change the values in selectedStakeholders array like this:
SAMPLE https://stackblitz.com/edit/usjgwp?file=index.html
to show a number of kendo dropdownlist(s) on a page. The exact number depends on an API call. This API call will give me an array of stakeholder objects. Stakeholder objects have the following properties: Id, name, type, role and isSelected.
The number of dropdownlist that has to be shown on this page should be equal to the number of unique type values in the API response array. i.e, numberOfDropdowns = stakeholders.map(a => a.type).distinct().count().
Now, each dropdown will have a datasource based on the type property. i.e, For a dropdown for type = 1, dataSource will be stakeholders.filter(s => s.type == 1).
Also the default values in the dropdowns will be based on the isSelected property. For every type, only one object will have isSelected = true.
there is achieved these things by using the following code:
<template>
<div
v-if=”selectedStakeholders.length > 0”
v-for=”(stakeholderLabel, index) in stakeholderLabels”
:key=”stakeholderLabel.Key”
\>
<label>{ stakeholderLabel.Value }:</label>
<kendo-dropdownlist
v-model=”selectedStakeholders[index].Id”
:data-source=”stakeholders.filter(s => s.type == stakeholderLabel.Key)”
data-text-field=”name”
data-value-field=”Id”
@select=”selected”
\></kendo-dropdownlist>
<button @click=”updateStakeholders”>Update form</button>
</div>
</template>
And in methods:
selected(e) {
const stakeholderTypeId = e.dataItem.type;
const selectedStakeholderIndexForTypeId = this.selectedStakeholders.findIndex(
s => s.type == stakeholderTypeId
);
this.$set(
this.selectedStakeholders,
selectedStakeholderIndexForTypeId,
e.dataItem
);
}