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
Related
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.
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() }
}
}
}
})
});
I am trying to get a grid filled with the json response I would receive when making a httpwebrequest call to a url endpoint which requires authentication. The data will be in json form:
{
"data": [
{
"value": "(\"Samsung Health\")",
"tag": "ME"
},
{
"value": "(\"Samsung Galaxy Tab\")",
"tag": "HIM"
},
{
"value": "(\"Amazon fire\")",
"tag": "ME"
}
]
}
I am not sure how to even start and whether to use Ext.Ajax.Request or some type of call from code behind. I am using vb.net in code behind. Any suggestions appreciated. Sample code for ajax call;
function getMembers() {
var parameters = {
node: dynamicNodeId
}
Ext.Ajax.Request({
url: 'https://data.json',
method: 'GET',
jsonData: Ext.encode(parameters),
success: function (response, opts) {
alert('I WORKED!');
//decode json string
var responseData = Ext.decode(response.responseText);
//Load store from here
memberStore.loadData(responseData);
},
failure: function (response, opts) {
alert('I DID NOT WORK!');
}
});
}
The grid formation:
var grid = Ext.create('Ext.grid.Panel', {
store: store,
stateful: true,
stateId: 'stateGrid',
columns: [
{
text: 'Query',
flex: 1,
sortable: false,
dataIndex: 'query'
},
{
text: 'Last Updated',
width: 85,
sortable: true,
renderer: Ext.util.Format.dateRenderer('m/d/Y'),
dataIndex: 'lastChange'
},
Here query would be the value from the json response and lastChange the current datetime. I tried the proxy request call and realized that since I am calling an endpoint on a different domain I needed to use jsonp.
var myStore = Ext.create('Ext.data.Store', {
model: 'User',
proxy: {
type: 'jsonp',
extraParams: {
login: 'username',
password: 'password'
},
url: 'https://api.data/rules.json',
reader: {
type: 'json',
root: 'rules'
},
callbackParam: 'callback'
},
autoLoad: true
});
I might have to just figure out some other way to do by making sure all the data I needed is called to a database by some other function.
The best approach for your situation would be to create store that is configured with a remote proxy. See the example at the top of this documentation page: http://docs.sencha.com/extjs/4.2.2/#!/api/Ext.data.Store
The remote proxy will take care of the AJAX request to retrieve the data, and the store will automatically manage casting the data results to Ext.data.Model instances. Once the store is loaded with data, the grid to which the store is bound will also automatically handle rendering the data that has been populated into the store.
I've setup a basic Kendo Grid and I'm using the DataSourceResult class from the PHP Wrapper library on the sever side.
I've come across a strange issue... if I create a new record and then edit it (without refreshing the page), the create operation is called again, rather than the update operation.
If the page is refreshed after adding the new record, the update operation is called correctly after making changes to the record.
I can confirm that the DataSourceResult class is returning the correct data after the create operation, including the id of the new record.
Any ideas why this is happening (and how to stop it)?
Thanks
Update: Here's the datasource code. The query string in the url is just to easily distinguish the requests in Chrome's console. The additional data passed with each request is used by ajax.php to distinguish the different actions requested.
data = new kendo.data.DataSource({
transport: {
create: {
url: '/ajax.php?r=gridCreate',
dataType: 'json',
type: 'post',
data: { request: 'grid', type: 'create' }
},
read: {
url: '/ajax.php?request=gridRead',
dataType: 'json',
type: 'post',
data: { request: 'grid', type: 'read' }
},
update: {
url: '/ajax.php?r=gridUpdate',
dataType: 'json',
type: 'post',
data: { request: 'grid', type: 'update' }
},
destroy: {
url: '/ajax.php?r=gridDestroy',
dataType: 'json',
type: 'post',
data: { request: 'grid', type: 'destroy' }
},
parameterMap: function(data, operation) {
if (operation != "read"){
data.expires = moment(data.expires).format('YYYY-MM-DD HH:mm');
}
return data;
}
},
schema: {
data: 'data',
total: 'total',
model: {
id: 'id',
fields: {
id: { editable: false, nullable: true },
code: { type: 'string' },
expires: { type: 'date' },
enabled: { type: 'boolean', defaultValue: true }
}
}
},
pageSize: 30,
serverPaging: true,
serverSorting: true,
serverFiltering: true
});
Best solution
Set to update, create or delete different Call Action
From Telerik Support :
I already replied to your question in the support thread that you
submitted on the same subject. For convenience I will paste my reply
on the forum as well.
This problem occurs because your model does not have an ID. The model
ID is essential for editing functionality and should not be ommited -
each dataSource records should have unique ID, records with empty ID
field are considered as new and are submitted through the "create"
transport.
schema: {
model: {
//id? model must have an unique ID field
fields: {
FirstName: { editable: false},
DOB: { type: "date"},
Created: {type: "date" },
Updated: {type: "date" },
}
} },
For more information on the subject, please check the following
resources:
http://docs.kendoui.com/api/framework/model#methods-Model.define
http://www.kendoui.com/forums/ui/grid/request-for-support-on-editable-grid.aspx#228oGIheFkGD4v0SkV8Fzw
MasterLink
I hope this information will help
I have also the same problem & I have tried this & it will work.
.Events(events => events.RequestEnd("onRequestEnd"))
And in this function use belowe:
function onRequestEnd(e) {
var tmp = e.type;
if (tmp == "create") {
//RequestEnd event handler code
alert("Created succesully");
var dataSource = this;
dataSource.read();
}
else if (tmp == "update") {
alert("Updated succesully");
}
}
Try to Use this code in onRequestEnd event of grid
var dataSource = this;
dataSource.read();
Hope that it will help you.
Pass the auto-incremented id of the table when you call the get_data() method to display data into kendo grid, so that when you click on the delete button then Deledata() will call definitely.
Another variation, in my case, I had specified a defaultValue on my key field:
schema: $.extend(true, {}, kendo.data.transports["aspnetmvc-ajax"], {
data: "Data",
total: "Total",
errors: "Errors",
model: kendo.data.Model.define({
id: "AchScheduleID",
fields: {
AchScheduleID: { type: "number", editable: true, defaultValue: 2 },
LineOfBusinessID: { type: "number", editable: true },
Not sure what I was thinking but it caused the same symptom.
Since I've tryed to write on kendoui forum but the answer I've got was "buy a license" for report a bug, I'm asking if someone has faced the same problem using kendoGrid 2013.1.319. Since I'm using it in a "sundays test application" there's no hurry at all!
My original message was on kendo forum was:
Hi there,
I've been updated kendo grid with the latest version and all of a sudden my application is facing problems on data operations. The problem seems to be located client side, because I'm correctly receiving requests for GET, PUT, POST and DELETE verbs but the grid does not update its status.
I'm using ASP.NET MVC 4 OData implementation through an API service.
For example: if I delete 2 rows and press save, the DELETE calls are made, the client grid hides the rows but if I press save again, the delete is called on and on.
The same problem is on update / create, the cell remains with the red corner and, after saving, again the data are still submitted as it was the first time.
I've noticed that when I receiving the callback on dataSource:
requestEnd: function (e) {
if (e.type === "update" || e.type === "create") {
// Refresh data after changes
this.read();
}
}
e.type is always undefined when inserting or updating records.
This is my dataSource configuration:
dataSource: {
type: 'odata', // <-- Include OData style params on query string
transport: {
read: {
url: $("#contactsGrid").attr("data-api-crud"),
dataType: "json", // <-- The default is "jsonp".
type: "GET"
},
update: {
url: $("#contactsGrid").attr("data-api-crud"),
dataType: "json", // <-- The default is "jsonp".
type: "POST"
},
create: {
url: $("#contactsGrid").attr("data-api-crud"),
dataType: "json", // <-- The default is "jsonp".
type: "PUT"
},
destroy: {
url: function (data) {
return $("#contactsGrid").attr("data-api-crud") + "/" + data.Id;
},
dataType: "json", // <-- The default is "jsonp".
type: "DELETE"
},
parameterMap: kendo.data.transports.odata.parameterMap
},
schema: {
// The array of repeating data elements (items)
data: "Results",
// The total count of records in the whole dataset. used for paging.
total: "Count",
model: {
id: "Id",
fields: {
Dealer: { type: "string", editable: true },
Address: { type: "string", editable: true }
}
}
},
pageSize: 50,
serverPaging: true,
serverFiltering: true,
serverSorting: true,
requestEnd: function (e) {
if (e.type === "update" || e.type === "create") {
// Refresh data after changes
this.read();
}
}
}
the Kendo UI team have just published a blogpost how to use the library with JayData to simplify the configuration of datasources. Hopefully it will help you.