This is a migrated thread and some comments may be shown as answers.

Binding kendo multiselect to array of objects

11 Answers 2557 Views
This is a migrated thread and some comments may be shown as answers.
Dennis
Top achievements
Rank 1
Dennis asked on 09 Mar 2018, 08:01 AM

How can I bind a kendo multiselect to a list of objects? The v-model binding only returns an array with the values of data-value-field.

<kendo-multiselect
id="employees"
v-model="selectedEmployees"
:data-source="employeesDataSource"
:data-text-field="'name'"
:data-value-field="'employeeNumber'"
:delay="1000"
:auto-bind="true"
:min-length="2">
</kendo-multiselect>

In the example above selectedEmployees will be set to an array of employee numbers instead of employee objects. How can I get it so work with objects instead?

11 Answers, 1 is accepted

Sort by
0
Veselin Tsvetanov
Telerik team
answered on 15 Mar 2018, 02:07 PM
Hi Dennis,

You can enable the MultiSelect widget to work with objects instead of primitive values by setting its :value-primitive option to false:
<kendo-multiselect
  id="employees"
  v-model="selectedEmployees"
  :data-source="employeesDataSource"
  :data-text-field="'name'"
  :data-value-field="'employeeNumber'"
  :delay="1000"
  :auto-bind="true"
  :min-length="2"
  :value-primitive="false">
</kendo-multiselect>

Regards,
Veselin Tsvetanov
Progress Telerik
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
0
Dennis
Top achievements
Rank 1
answered on 16 Mar 2018, 11:46 AM

I already tried value-primitive, it makes no difference.

I found the following page on your website:

https://www.telerik.com/kendo-vue-ui/components/framework/model-binding/#toc-objects

It mentions:

Kendo UI for Vue does not support the binding of objects directly to the value prop and, consequently, it is not possible to pass a complex object through the v-model directive. 

Is this a limitation of Vue or of the current implementation of the Kendo-Vue bridge? Binding to objects is possible in all other variants of Kendo, are you planning to add this for Vue later on? If yes, when can I expect it to be available?

 

However, you can work around the issue by customizing the code and using the API calls and events of the widget.

I'm not quite sure how to apply the suggested workaround to a multiselect because it works with an array of items instead of a single item. Can you give me an example?

Thanks!

0
Veselin Tsvetanov
Telerik team
answered on 20 Mar 2018, 08:34 AM
Hello Dennis,

Please, excuse me for misleading you with my previous reply. The documentation article referred is correct and currently, the Kendo widgets do not support v-model binding of objects. This is a design decision while implementing the Vue wrappers and it is caused by the intended behaviour of the Vue components to use only primitives for their v-model values. Here you could find some more information on the topic.

As per the Kendo + Vue integration in this respect, potential object v-model binding of widgets would cause conflicts with the internal Kendo observables (created by the Kendo DataSource utility). Nevertheless, if you think, that such feature would add value to the suite, I would suggest you to log your idea on our Feedback portal. Based on the support it receives from the community, we will decide on whether to proceed with its implementation or not.

As per the MultiSelect sample, here you could find a Plunker, which applies the suggested workaround.

Regards,
Veselin Tsvetanov
Progress Telerik
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
0
n/a
Top achievements
Rank 1
answered on 21 Mar 2018, 06:26 PM
v-model binding to the underlying object is a MUST HAVE, Top priority, number one with a bullet. Without it, your components are a PITA to use and my current proof of concept might end here and we won't use your components with some bigger projects coming down the line.
0
Ianko
Telerik team
answered on 23 Mar 2018, 06:24 AM
Hi Dennis,

Thank you for your feedback and thank you for logging this as a feature request here http://kendoui-feedback.telerik.com/forums/127393-kendo-ui-feedback/suggestions/33706393-v-model. I am linking it so that anyone interested in the topic can share a thought and/or vote for it. 

Let me get into more details about the case. During the implementation of the Kendo UI for Vue components we evaluated the possibility to have the native v-model two-way binding for an object. At the time, however, the Vue community stated that this is an anti-pattern for the Vue framework and that such action should be rather separated into components in order to properly update the model bound. 

This, however, is not entirely true, v-model can work with object to a certain extend, but as far as I am aware, it works by cloning the object and not by working with references. And this part is the main difficulty for having it working against the Kendo UI widgets. With Kendo UI widgets, binding objects is possible and the objects are being updated via the Kendo DataSource utility that is built-in. With Vue, you have the v-model directive as an utility to facilitate two-way binding. Both these functionalities combined in a component do not work well. First, there is the v-model that works with a single property and a single event to work with. Whereas, commonly, Kendo widgets return the updated object via different method or property that is especially designed for the objects bound. Due to that, implementing the native v-model directive to work with the widgets causes a circular change event propagation because the value bound is being constantly mutated. Then, there is the Kendo DataSource that is built-in and works with the data items. The problem here is that both Vue and DataSource do similar things, attach observable properties to the object bound so to propagate change events and updated the widget. Using this against the v-model directive tends to cause performance issues because of the object being consonantly mutated by both utilities. 

Due to these two factors the idea of having the v-model directive working for objects and act propely as a two-way binder for the widgets is prone to more harms than benefits. This is why the suggestion from this article (https://www.telerik.com/kendo-vue-ui/components/framework/model-binding/#toc-objects) is the best way (at the moment) to have the objects in a two-way binding scenario. Indeed, it needs a bit more logic implemented to it, but it performs flawless considering the Vue principles and you have much more power and control over what is bound and how. Also, this way of binding is documented in the Vue documentation as well (https://vuejs.org/v2/guide/components.html#Form-Input-Components-using-Custom-Events). 

Another possibility that we had is to implement our own directive that binds the components. This, however, would be not so straight forward way for Vue developers as the v-model is the go for when it comes to two-way binding. Plus, this was the design decision with the Kendo UI for AngularJS (https://docs.telerik.com/kendo-ui/AngularJS/introduction#scope-bindings) and we had a proof of concept that additional binding directives lead to confusion among developers. 

Whether object binding should work without the hassle of writing some more code, yes, it should. And I entirely agree with you on that part. When it comes to native Vue components this is doable. Here, however, the Kendo UI for Vue components are just wrappers of the Kendo UI widgets, which comes with certain limitations. Of course, now that we have that logged as a feature request, we are going to monitor the demand for this feature. And re-evaluate the case whether it is somehow doable with the actual state of Vue and Kendo UI widgets. 

Regards,
Ianko
Progress Telerik
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
0
Robert
Top achievements
Rank 1
answered on 27 Mar 2018, 06:40 AM

Hi Veselin,

Thanks for the example!

I cannot get it to work with a server side filtered datasource however. The setup is identical to your example, except that it has a datasource with a transport defined and serverFiltering: true.

The multiselect allows me to search for people, when I select a person it will also show in the model and modelValue property, but it doesn't show the selected people as tags, the multiselect box remains blank. Additionally, when selecting a second person, the first person disappears from the model and modelValue properties.

I guess the main difference with your example and a server filtered version is that the datasource does not always have the object data available for rendering the tags based on the primitive values. Without this knowledge, how can it render the tags?

Any clue how I can resolve this issue? Thanks!

Regards,
Dennis

0
Ianko
Telerik team
answered on 27 Mar 2018, 09:30 AM
Hello Ferdy,

I am not sure what might be the exact reason for the described issue as it mostly depends on the data structure that is bound and the solution implemented. If, the only problem is with the model bound back to the MultiSelect, then, most probably it is the computed property that should be debugged and examined for possible errors. 

Here you are an example with the MultiSelect, with DataSource, filtering and object binding. https://plnkr.co/edit/tRG1ZT0oa3LKkWk3q69O?p=preview

Regards,
Ianko
Progress Telerik
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
0
Dennis
Top achievements
Rank 1
answered on 27 Mar 2018, 09:57 AM

I see one difference between your implementation and mine. You use odata, I use a custom transport.

In your implementation the multiselect control will make an odata call to fetch ALL objects from the server (this is visible through the network tab of the developer tools in Chrome). Because of this call, the control will have object data for the primitive values specified through :value="modelValue". So if you specify the component [3] (through the computed modelValue), the component can look in this list of all objects to find that it needs to be rendered using { "ProductName": "Aniseed Syrup", "ProductID": 3 }.

In my case the list consist of >10.000 records, fetching the entire list is not an option. How can the control then display the tags without having the complete object data of the selected records?

Binding to objects would make this initial fetch all call unnecessary as the datasource data is not needed for rendering the tags using :data-text-field="'ProductName'" and :data-value-field="'ProductID'". Also, further filtering of the datasource for selecting an additional item won't make the previous tag unavailable because it dropped out of the datasource due to server filtering.

This is why I think having the option for binding to objects is important.

0
Ianko
Telerik team
answered on 27 Mar 2018, 11:11 AM
Hello Dennis,

You are correct about this behavior, but object binding in the Vue components will not resolve the case. Generally, this is how the Kendo MultiSelect widget works and you can observe the same behavior even by using the Kendo MultiSelect widget on its own. You can check out this demo: https://dojo.telerik.com/uMAciMoV

Generally, all dropdowns work that way. When selecting a value, that value must be part of the data bound (initially). What server filtering offers is the autocompletion functionality and that is all. This is why, initially, all the data should be bound and later the MultiSelect to filter it based on the text input. There is no possible way to select an item that does not exist in the data that is bound. 

What you need for your case is the virtualization that the dropdown widgets offer: https://www.telerik.com/kendo-vue-ui/components/dropdowns/multiselect/virtualization/. You can find more details about this feature here: https://docs.telerik.com/kendo-ui/controls/editors/combobox/virtualization

Regards,
Ianko
Progress Telerik
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
0
leri
Top achievements
Rank 1
answered on 28 Oct 2019, 11:57 AM
You're binding the SpaceOfWork to the new widget, but how that widget knows your Model ? I mean, just using data-bind doens't binds the model to the widget, it can't figure that by itself.
0
leri
Top achievements
Rank 1
answered on 28 Oct 2019, 11:59 AM
get an information about How can you bind a kendo multiselect to a list of objects facetime for pc download app
Asked by
Dennis
Top achievements
Rank 1
Answers by
Veselin Tsvetanov
Telerik team
Dennis
Top achievements
Rank 1
n/a
Top achievements
Rank 1
Ianko
Telerik team
Robert
Top achievements
Rank 1
leri
Top achievements
Rank 1
Share this question
or