CDA the Programmer
CDA the Programmer

Reputation: 107

Using ko.PureComputed List as DataSource for Kendo ComboBox

I'm attempting to get the list of selectedJobs below to be a dataSource for the kendoComboBox below. However, the values of the list aren't loading and I'm not getting an error and so I'm unsure of what's wrong. Is what I'm trying possible? Can I not use a ko.pureComputed() returned list as a dataSource? Also, the jobid isn't being recognized as a field for dataValueField even though the selectedJobs has this field. Thank you!

pageModel.newServiceModel.selectedJobs = ko.pureComputed(function () {
    return pageModel.newServiceModel.selectedAccount() ? pageModel.newServiceModel.selectedAccount().jobs : null;
});

var source = new kendo.data.DataSource(pageModel.newServiceModel.selectedJobs);

$("#newServiceJobs").kendoComboBox({
    placeholder: "Select One",
    filter: "contains",
    suggest: true,
    change: pageModel.newServiceModel.JobSelectionChange,
    dataSource: source,
    //dataValueField: jobid,
    dataTextField: name
});

Upvotes: 0

Views: 104

Answers (1)

RP Niemeyer
RP Niemeyer

Reputation: 114792

Here are a couple of ways to fix up your existing code:

  • To access a pureComputed, you need to call it as a function like: pageModel.newServiceModel.selectedJobs(). You can pass that directly in as the dataSource property.
  • The dataValueField and dataTextField options expect strings (like "jobid" and "name")
  • If you want the control to react to your selectedJobs computed changing, then you would need to subscribe to changes and update the control like:
pageModel.newServiceModel.selectedJobs.subscribe( function(newData) {
     $("#newServiceJobs").data( "kendoComboBox" ).dataSource.data( newData );
});

Here is a snippet that shows your scenario. Click the "Fill Selected Account" button to populate the selectedAccount observable.

const viewModel = {
	selectedAccount: ko.observable(),
  clearSelectedAccount() {
  	viewModel.selectedAccount( null );
  },
  fillSelectedAccount() {
      viewModel.selectedAccount({
      	jobs: [
        	{ jobid: "1", name: "one" },
        	{ jobid: "2", name: "two" }
      	]
    	});
  }
};

viewModel.selectedJobs = ko.pureComputed(function () {
    const account = viewModel.selectedAccount();
    return account ? account.jobs : [];
});

ko.applyBindings( viewModel );

$("#newServiceJobs").kendoComboBox({
    placeholder: "Select One",
    filter: "contains",
    suggest: true,
    change: null,
    dataSource: viewModel.selectedJobs(),
    dataValueField: "jobid",
    dataTextField: "name"
});

viewModel.selectedJobs.subscribe( newData => {
	$("#newServiceJobs").data( "kendoComboBox" ).dataSource.data( newData );
} );
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link href="https://kendo-labs.github.io/knockout-kendo/css/kendo.default.min.css" rel="stylesheet"/>
<link href="https://kendo-labs.github.io/knockout-kendo/css/kendo.common.min.css" rel="stylesheet"/>
<script src="https://kendo-labs.github.io/knockout-kendo/js/kendo.all.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>

<button data-bind="click: fillSelectedAccount">Fill Selected Account</button>
<button data-bind="click: clearSelectedAccount">Clear Selected Account</button>

<hr/>

<input id="newServiceJobs" />

Another option, if possible, is to look at knockout-kendo that will give you some basic bindings to Kendo UI from Knockout like: http://kendo-labs.github.io/knockout-kendo/web/ComboBox.html. The library handles keeping the control and view model in sync with each other and avoids you manually having to manage the kendo controls via jQuery.

Upvotes: 1

Related Questions