How to properly bind kendo multiselect with knockout using ajax - ajax

I've been working on this for days and finally have a partially working solution, but it doesnt feel quite right. In fact, i'm not sure any of this is right.
My problem is three fold:
generating the filter value in the read function doesnt seem right. I feel like i should be able to bind the multiselects text value or something and use that in the function,
the filter stops processing if i keep typing characters beyond the minLength setting. If i type "cha" the ds fetches "Charles" and "Chad". But if i continue typing and enter "chad", the filter still shows "Charles".
names already selected in the "value" property continue to display in subsequent searches. So if i select "Charles", then i select "Tim", then i type "cha", "Charles" will show up on the list again. But because he's already selected he should not appear on the list.
I'm using the kendo-knockout js, here's what i have so far:
<select data-bind="kendoMultiSelect: { dataSource: ds, autoBind: false, change:'filterTypeOnChanged', search: relatesSearch, minLength: 3, filter:'contains', value: selectedPersons, dataTextField:'PersonName'}"></select>
And here's the datasource (ds) that i'm binding to. (it's in typescript, so hopefully that wont hang anybody up).
ds = new kendo.data.DataSource({
serverFiltering: true
, type: 'json'
, transport: {
read: (options) => {
var srch: string;
debugger;
if (options.data[0] != undefined)
srch = options.data[0].value;
else
srch = options.data.filter.filters[0].value;
jQuery.ajax({
url: "/Person/GetPersons",
cache: false,
dataType: "json",
async: true,
data: JSON.stringify({ textToBeSearched: srch }),
type: "POST",
contentType: 'application/json, charset=utf-8',
processData: false,
success: result => {
options.success(result.data);
},
error: function (e) {
debugger;
console.log(e);
}
});
}
}
});

Related

Populating a kendo multiselect with ajax data

I am using a kendo multiselect widget for users to select different values pulled from the database via an ajax call. The ajax call takes one parameter, searchValue, which will narrow down the returned data. Here is my controller:
[HttpPost]
public JsonResult ProfitabilitySearch(string searchValue)
{
return Json(InventoryDataAccess.ProfitabilitySearch(searchValue));
}
1) How do you get the value from the text box to use as your searchValue? I commented the area in question below.
Here is my dataSource:
var searchDataSource = new kendo.data.DataSource({
transport: {
read: function () {
$.ajax({
type: 'POST',
url: Firm.ProfitabilitySearchURL,
contentType: 'application/json; charset=utf-8',
dataType: 'json',
//'SuperClient' is test data to see if it works, but what do i
//need to make searchValue = what I type?
data: JSON.stringify({ searchValue: 'SuperClient'}),
success: function (data) {
return data.RESULT;
}
});
}
},
group: { field: 'category' },
serverFiltering: true
});
And here is where I create the multiselect widget:
var TKSearch = $("#TKSearch").kendoMultiSelect({
dataSource: searchDataSource,
autoBind: false,
minLength: 3,
placeholder: 'Search Timekeepers...',
dataTextField: 'label',
dataTextValue: 'value',
delay: 200
}).data("kendoMultiSelect");
I'm not sure if this will help, but here is the structure of the json that is returned from the ajax call:
{"label":"SUNFLOWER REALTY CORP. (023932)","value":"023932","category":"RC"}
Solving the first question above may answer my second question so I will wait to ask that until after.
You can use functions for the request parameters.
var searchDataSource = new kendo.data.DataSource({
transport: {
read: function (options) {
$.ajax({
type: 'POST',
url: Firm.ProfitabilitySearchURL,
contentType: 'application/json; charset=utf-8',
data: {
searchValue: function () {
// better: use a model property instead of this
return $("#TKSearch").data('kendoMaskedTextBox').value();
}
},
success: function (data) {
options.success(data.RESULT);
}
});
}
},
group: { field: 'category' },
serverFiltering: true
});
Notes
This really should be a GET request. Use POST for requests that actually change data on the server and GET for requests that merely retrieve data from the server.
You do not have to JSON.stringify() yourself. jQuery does that transparently.
Specifying dataType is completely superfluous, jQuery will figure this out from the response headers.
Reading the input value via jQuery is not clean. Use the data-bound model property instead.
The callback invocation (options.success())
This sample lacks HTTP error handling, you must add that.

kendo ui combo box not sending requests

I'm trying to get a Kendo UI combo box to load data from the server as I type. #Client is an Input box. I need the id of the item in the textbox saved, which is why I am using a combo box instead of autocomplete. When I type into the combo box it always sends the string that is 1 keypress behind the data in the input box. I assume this happens because the "shadowed" Kendo UI input box doesn't update the original input box until after the call to the server is already made.
Also, If I don't use the parameterMap code, nothing that is typed in the input box is sent to the server. And, I would expect that the filter condition would be sent too. I have looked at the examples on Telriks site and they show to use the filters from the request parameters to see the data, but when I use fiddler or any other tracing tool, I can see that nothing is sent in the request that has anything to do with the data from the Kendo UI server call. This should be a relativity easy thing to do, but I'm stumped.
EDIT: I changed it to a kendoAutoComplete and everything works as I would expect an AutoComplete to work. It shouldn't be any different than the ComboBox for implementation other than the return for the dataValueField.
$("#Client").kendoComboBox({
dataTextField: "label",
displayValueField: "id",
suggest: true,
autoBind: false,
minLength: 1,
highlightFirst: true,
filter: "contains",
dataSource: new kendo.data.DataSource({
serverFiltering: true,
transport: {
read: { url: "/search/client", dataType: "json", type: "POST" },
parameterMap: function (data) {
return { search: $("#Client").val() }
}
}
})
});
$("#Client").kendoComboBox({
dataTextField: "label",
displayValueField: "id",
suggest: true,
autoBind: false,
minLength: 1,
highlightFirst: true,
filter: "contains",
dataSource: new kendo.data.DataSource({
serverFiltering: true,
transport: {
read: {
url: "/search/client",
dataType: "json",
type: "GET",
data: function () {
return { search: $("#Client").val() }
}
}
}
})
});

SharePoint 2013 and Kendo Grid cross domain call issues

I am having a small issue that I just can't seem to figure out. I am trying to make a simple SharePoint 2013 demo app that gets a few fields from a list on the parent site and binds to a kendo grid.
Due to the new nature of SP2013, app's get created in their own local site which makes these calls cross domain. When I make the call, no data is pulled back. When I compare a working call vs the call being made by the app, I can see that a cookie is not present in the call that is failing (which is why no data is being pulled back). If anyone could offer any hints or suggestions on things to try, I would appreciate it.
The List I am trying to call is called KendoGridList and I am trying to pull back the first and last name and bind to the grid. Below is my code:
EDIT: After looking into the code a little deeper, it looks like a cookie is not getting passed in the call to the service. If I take the cookie from a normal rest call to the service which works and add it to the composer in fiddler the call goes through and returns data.
$(document).ready(function () {
$("#grid").empty();
var siteUrl = "site url placed here";
var url = siteUrl + "/_vti_bin/Listdata.svc/KendoGridList/?$select=FirstName,LastName";
grid = $("#grid").kendoGrid({
dataSource: {
type: "odata",
transport: {
read: {
url: url,
dataType: "json",
beforeSend: function (xhr) {
xhr.setRequestHeader("Accept", "application/json;odata=verbose");
}
}
},
schema: {
type: "json",
model: {
fields: {
FirstName: "FirstName",
LastName: "LastName"
}
}
},
pageSize: 10,
serverPaging: true,
serverFiltering: true,
serverSorting: true,
change: function (e) { // data load completed for grid
},
},
filterable: false,
sortable: true,
pageable: true,
scrollable: false,
//groupable: true,
columns: [{
field: "FirstName",
title: "First Name",
width: 50
}, {
field: "LastName",
title: "Last Name",
width: 50
}
]
});
});
I've also tried using:
read: {
url: url,
type: "GET",
dataType: "json",
contentType: "application/json;odata=verbose",
headers: {
"accept": "application/json;odata=verbose"
}
},
If you are using a provider-hosted app you should try using the SP cross-domain library. I think your best bet is to retrieve the data using the library and then bind the resulting info to the grid.
http://blogs.msdn.com/b/officeapps/archive/2012/11/29/solving-cross-domain-problems-in-apps-for-sharepoint.aspx

kendo grid custom delete not persisting to datasource

I simply want to use my own workflow for deleting a record from my grid. Is this not the proper way to do it via Javascript? The function below removes the row but refreshing the page shows the row was not actually deleted from the datasource and I do not see any requests sent in the network tab of Chrome. I should add that I am able to obtain a reference to the grid and the dataItem perfectly.
function delete(e) {
var $tr = $(e.currentTarget).closest("tr"),
grid = this,
dataItem = grid.dataItem($tr),
id = $tr.attr(kendo.attr("uid")),
model = grid.dataSource.getByUid(id);
e.preventDefault();
grid.dataSource.remove(model);
grid.dataSource.sync();
}
Edit - Here is how my datasource is defined:
$scope.contacts = new kendo.data.DataSource({
transport: {
read: {
url: apiUrl,
dataType: "json",
type: "GET"
},
update: {
url: apiUrl,
dataType: "json",
type: "POST"
},
destroy: {
url: apiUrl,
type: "DELETE"
},
create: {
url: apiUrl,
dataType: "json",
type: "POST"
}
},
pageSize: 10
});
I found something and I dont know if it works in your side.
I needed to add this line in my kendo.datasource
schema: {
model:{id:"id"}
}
and trigger like this
data_source_inspection.remove(selected.data);
data_source_inspection.sync();
this works for me.

jqGrid populate select control on row edit

I want to add about 150 element from a xml file to a select control that is inside a jqGrid cell. I was thinking of doing this in two ways:
1.Using the editoptions value:
{ name: 'language', width: 100, sortable: false, editable: true, edittype: 'select', editoptions: { value: languageElem()} }
using data received from the method:
function languageElem() {
$.ajax({
type: 'POST',
contentType: "application/json; charset=utf-8",
url: 'jqService.asmx/GetLanguages',
data: {},
dataType: "json",
success: function (data) {
alert("success");
}
});}
But I'm having trouble forwarding the data from the ajax part.
2.Simply accessing the select control inside the jqGrid cell and manually adding the options whenever the edit button is pressed.
The problem over here is that I have no idea how to access the control itself.
The code I used over here is:
function startEdit() {
if (selRow > -1) {
$.ajax({
type: 'POST',
contentType: "application/json; charset=utf-8",
url: 'jqService.asmx/GetLanguages',
data: {},
dataType: "json",
success: function (data) {
var cell = jQuery("#MainContent_list").getCell(selRow, "language");
cell.options.length = 0;
for (var i=0;i<data.d.length;i++)
{
}
}
});
jQuery("#MainContent_list").jqGrid('restoreRow', selRow);
jQuery("#MainContent_list").jqGrid('editRow', selRow);
}
My questions are:
1.Related to the first idea, what should I do to fix the method so that the control will receive it's needed values?
2.Related to the second idea, how could I access the control inside the row?
Thanks, Catalin
Instead of value property (editoptions: { value: languageElem()}) you should use dataUrl and buildSelect (see the documentation). Because it's difficult to return from ASMX HTML fragment <select><option>...</option></select> you can provide the list serialized as JSON and convert the server response to HTML fragment using buildSelect. In the answer and in this one you will find additional information. If you would search for dataUrl and buildSelect you will find more information and code example which you could use.

Resources