Passing Date to WCF REST Service via Kendo UI (Javascript/Jquery) - javascript

The idea
is i have calendar control from where i can select different dates. Based upon the dates selected i make a ajax call to WCF service (GetDealData()) to fetch some sets of data.
Could you anyone please see whats wrong here? For two days i am going a bit crazy trying to figure out why does my GetRemoteData() method passes the same date (which is 25-10-2012) everytime i execute the OnDateChange Method even if i select different dates on my calendar control. Is it something to do with json data not being assigned properly?
$('#calendarContainer').kendoCalendar({
format: "dd/MM/yyyy",
culture: "en-GB",
change: onDateChange
});
function onDateChange() {
var date = kendo.toString(this.value(), 'dd/MM/yyyy');
var bob = GetRemoteData(date);
$("#grid").data("kendoGrid").dataSource.data(bob);
$("#grid").data("kendoGrid").dataSource.read();
}
function GetRemoteData(date) {
var chosenDate;
if (typeof date=="undefined")
{
alert("it is null " + date);
chosenDate = "25-10-2012";
}
else {
alert("it is not null " + date);
chosenDate = date;
}
source = new kendo.data.DataSource({
// autoSync:true,
transport: {
read: {
type: "GET",
url: "http://localhost:35798/RestServiceImpl.svc/GetDealData",
dataType: "jsonp",
contentType: "application/json; charset=utf-8",
cache: false,
data: {
startDate:chosenDate
}
}
},
schema: {
model: {
fields: {
DealNumber: { type: "string" },
DealIssuer: { type: "string" },
Ticker: { type: "string" },
DealType: { type: "string" },
DealValue: { type: "number" },
DealStatus: { type: "string" },
DealPricingCompletionDate: { type: "date" }
}
}
},
pageSize: 16
});
return source;
}
WCF Methods
[OperationContract]
[WebInvoke(Method = "GET", ResponseFormat = WebMessageFormat.Json,
BodyStyle = WebMessageBodyStyle.WrappedRequest,
UriTemplate = "GetDealData?startDate={startDate}")]
List<DealData> GetDealData(string startDate);
public List<DealData> GetDealData(string startDate)
{
CultureInfo culture = new CultureInfo("en-GB");
List<DealData> model = Service.GetDealData(Convert.ToDateTime(startDate,culture));
return model;
}

From your code, it seems that this issue does not related to wcf - its just a JavaScript issue.
It seems, that your date is always undefined.
I'd try to find out what is the value of this.value(), and after this - kendo.toString(this.value(), 'dd/MM/yyyy') value.
For me its sound like some format issue may be.
You can use browser's console to debug JavaScript

Related

How to get part of JSON for KendoDataSource

I need to fill a KendoListView from a external server and I need to use just part of the response I am reading for a Java Servlet
var srcListView = new kendo.data.DataSource({
transport: {
read: {
dataType: "json",
url: "MainServlet",
data:{event:"Test"},
},
},
});
And the response is:
{
"status": "ok",
"response": {
"trucks": [
"A6U-905",
"AHF-888",
"AHP-779",
"buzz"
]
}
}
I need just the trucks array for kendoListView, I am using Kendo-ui, How I can do this?
As an alternative to what #DontVoteMeDown said about using schema.parse you can use a simpler solution for cases like this where you don't need to process the result but just return what is in an element. This solution is define schema.data as the name of the field containing the data. In your example:
new kendo.data.DataSource({
transport: {
read: {
dataType: "json",
url: "MainServlet",
data:{event:"Test"},
}
},
schema: {
data: "response.trucks"
}
});
I recommend using schema.parse when you need to do some transformation on the data received and schema.data when is simply returning some sub-element of the received JSON.
Use dataSource.schema.parse to filter the data to be used in the widget:
new kendo.data.DataSource({
transport: {
read: {
dataType: "json",
url: "MainServlet",
data:{event:"Test"},
}
},
schema: {
parse: function(data) {
return (data && data.trucks ? data.trucks : []);
}
}
});

Properly Initialize Client Side Model

My issue is very simple. I am using ASP Web API, Entity Framework, Angular, and Kendo UI. I have 2 classes, FREQUENCY and FREQ_TYPE_. Class FREQUENCY has a navigation property to class FREQ_TYPE. I have a kendo ui grid that loads 10 class FREQUENCY models. Each class FREQUENCY model has it's FREQ_TYPE data loaded properly. My problem is that when I create a new row in my kendo ui grid and try to save the row to the server, I get an error saying the navigation property FREQ_TYPE needs to be initialized. This is expected of course since kendo doesn't know how to auto=initialize my nav properties.
What is the best practice for giving my angular JS client the knowledge it needs to create a new class FREQ_TYPE so I can properly initialize class FREQUENCY and save it to the server? My models only exist as code-first entity models, so I can't just create a new model in my client side JS as it doesn't know about these models. Is there some framework that can generate local model classes from an EF database? Or do I just have to manually set all the json fields for my class FREQ_TYPE navigation property? Or is there an easier way for me to use Web API so that I can make a request to "figure out" what the model info is and create a client side JS model without needing to have a "local model"?
Here is the client side grid and datasource:
$(document).ready(function () {
var crudServiceBaseUrl = "http://localhost:29858/";
var NIICDDS = new kendo.data.DataSource({
transport: {
read: {
url: crudServiceBaseUrl + "api/NIICDFreq",
dataType: "json"
},
update: {
url: function (data) {
console.log("DATA TEST");
console.log(data);
return crudServiceBaseUrl + "api/NIICDFreq/";
},
// url: crudServiceBaseUrl + "api/VHFMasterLists",
dataType: "json",
data: function (data) {
console.log("returning data in update TEST");
console.log(data.models[0]);
return data.models[0];
},
type: "PUT",
contentType: "application/json; charset=utf-8",
},
destroy: {
url: crudServiceBaseUrl + "api/NIICDFreq",
dataType: "json"
},
create: {
url: crudServiceBaseUrl + "api/NIICDFreq",
dataType: "json",
type: "POST",
contentType: "application/json; charset=utf-8"
},
parameterMap: function (model, operation) {
if (operation !== "read" && model) {
return kendo.stringify(model);
} else {
return kendo.stringify(model) ;
}
}
},
batch: true,
pageSize: 20,
schema: {
data: function (data) { //specify the array that contains the data
console.log("DATA RETURN TEST");
console.log(data);
return data || [];
},
model: {
id: "Id",
fields: {
Id: { editable: false,
nullable: false,
type: "number"
},
Frequency: { type: "string" }
}
}
}
});
$("#NIICDFreqGrid").kendoGrid({
dataSource: NIICDDS,
columns: [
{ field: "Id", title: "Freq ID", format: "{0:c}", width: "120px" },
{ field: "Frequency", title: "Frequency Test", format: "{0:c}", width: "120px" },
{ command: ["edit", "destroy"], title: " ", width: "250px" }
],
toolbar: ["create"],
editable: "inline"
});
});
And here is the web api controller:
[ResponseType(typeof(FREQUENCY))]
public IHttpActionResult PostFREQUENCY(FREQUENCY testfreq)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
db.FREQUENCIES.Add(testfreq);
try
{
db.SaveChanges();
}
catch (DbUpdateException)
{
if (FREQUENCYExists(testfreq.Id))
{
return Conflict();
}
else
{
throw;
}
}
return CreatedAtRoute("DefaultApi", new { id = testfreq.Id }, testfreq);
}
The error is the last line:
iisexpress.exe Information: 0 : Request, Method=POST, Url=http://localhost:29858/api/NIICDFreq, Message='http://localhost:29858/api/NIICDFreq'
iisexpress.exe Information: 0 : Message='NIICDFreq', Operation=DefaultHttpControllerSelector.SelectController
iisexpress.exe Information: 0 : Message='CFETSWebAPI.Controllers.Frequency.NIICDFreqController', Operation=DefaultHttpControllerActivator.Create
iisexpress.exe Information: 0 : Message='CFETSWebAPI.Controllers.Frequency.NIICDFreqController', Operation=HttpControllerDescriptor.CreateController
iisexpress.exe Information: 0 : Message='Selected action 'PostFREQUENCY(FREQUENCY testfreq)'', Operation=ApiControllerActionSelector.SelectAction
iisexpress.exe Information: 0 : Message='Value read='DomainModelModule.FREQUENCY'', Operation=JsonMediaTypeFormatter.ReadFromStreamAsync
iisexpress.exe Information: 0 : Message='Parameter 'testfreq' bound to the value 'DomainModelModule.FREQUENCY'', Operation=FormatterParameterBinding.ExecuteBindingAsync
iisexpress.exe Information: 0 : Message='Model state is invalid.
testfreq.FREQ_POOL: The FREQ_POOL field is required.,testfreq.FREQ_TYPE: The FREQ_TYPE field is required.', Operation=HttpActionBinding.ExecuteBindingAsync
And of course testfreq has all null values.
Thank you for your help.
Since you shared no code, I can only make an assumption. However, I think you're confused with the error message. Neither Kendo or Angular are responsible. They do not "initialize" classes. You said yourself, the data is there on the client.
From what it sounds like to me, the data arrives at your controller action, and the compiler does not know how to initialize your class. Make sure your Class B has a constructor defined in your server-side code. Even an empty constructor will suffice, unless the members of the class need explicit initialization themselves.
public class B {
// constructor
public B() {
// initialize class members
}
}

Kendo Grid CRUD: how make update

i have a kendo ui grid with asp web api as backend. When i call the create method in the kendo ui, it's called the following method in web api
public IHttpActionResult PostProduct(ProductDTO product)
{
...
...
return StatusCode(HttpStatusCode.NoContent);
}
Now if i try to edit the item in the Kendo Ui Grid is called again the create method instead of the update method.
If i reload the page (so is called the read method of kendo ui grid), the update method works.
What's the problem? I have the following schema:
schema: {
model: {
id: "Id",
fields: {
Id: { editable: false, type: "number" },
Name: { validation: { required: true } },
Description: { editable: true },
Price: { editable: true },
Active: { type: "boolean" },
}
}
}
I have the following transport (omitted some code)
$scope.tabellaProdotto = new kendo.data.DataSource({
transport: {
read: {
url: function () {
return "api/Prodotti/GetProdottoPerTipoProdotto/" + productTypeMainSelected;
},
dataType: "json"
},
create: {
url: "api/Prodotti/PostProdotto",
dataType: "json",
data: function (prodottoTmp) {
...
},
type: "POST"
},
update: {
url: function (prodotto) {
return "api/Prodotti/PutProdotto" + prodotto.Id
},
data: function (prodottoTmp) {
...
},
type: "PUT",
dataType: "json"
UPDATE: the problem seems be the return of the web api action method:
return CreatedAtRoute("DefaultApi", new { id = p.Id }, p);
Now works but the p object size dimension is very high: i must return the entire object?
This sounds like the Grid is not getting the Json back in the right format.
Be sure to use the KendoMVC DataSourceRequest Object to return data in the right format.
Here is an example:
public ActionResult Update([DataSourceRequest] DataSourceRequest request, MyViewModel data)
{
var result = UpdateBackend(data);
return Json(result.ToDataSourceResult(request), JsonRequestBehavior.AllowGet);
}

Kendo DataSource appends Schema Id on datasoure sync

Just want to know why push method of the javascript inserts "index"
var agendaBatch=[];
for(var i=0; i<agendas.length; i++) {
var agenda = {
MeetingId: meetingId,
Title: agendas[i].title,
Description: agendas[i].description,
Remarks: "",
};
agendaBatch.push(agenda);
}
console.log(kendo.stringify(agendaBatch));
dataSourceAgenda.add(agendaBatch);
dataSourceAgenda.sync();
output:
{"0":{"Title":"Agenda title","Description":"Agenda details","Remarks":""},
"1":{"Title":"Agenda title","Description":"Agenda details","Remarks":""}}
what I expect is this output to match my Web API parameter requirement
[{"Title":"Agenda title","Description":"Agenda details","Remarks":""},
{"Title":"Agenda title","Description":"Agenda details","Remarks":""}]
Any suggestions how can I do this?....
UPDATE: just found out a moment ago, I'm using kendo ui datasource, I fixed the problem when I removed the Id on the schema
var dataSourceAgenda = new kendo.data.DataSource({
transport: {
type: "odata",
create: {
type: "POST",
url: API_URL + "/agendas",
contentType: "application/json; charset=utf-8",
dataType: 'json'
},
parameterMap: function (options, operation) {
if (operation !== "read" && options) {
return kendo.stringify(options);
}
}
},
schema: {
model: {
id: "Id", //I get my desired output if this is removed
fields: {
MeetingId: { type: "number" },
Title: { type: "string" },
Description: { type: "string" },
Remarks: { type: "string" },
}
},
}
});
HOWEVER I need to the Id parameter in other functions, is there anyway I can do this without removing the Id in kendo datasource.
Changed the Question title!
According the documentation of Kendo UI DataSource (here), add method accepts an Object not an array of Object.
In addition, you use as id a field called Id that is not among the fields of your model.
Try doing the following:
var dataSourceAgenda = new kendo.data.DataSource({
transport: {
create : function (op) {
...
},
parameterMap: function (options, operation) {
if (operation !== "read" && options) {
return kendo.stringify(options.models);
}
}
},
batch : true,
schema : {
model: {
id : "Id", //I get my desired output if this is removed
fields: {
Id : { type: "number" },
MeetingId : { type: "number" },
Title : { type: "string" },
Description: { type: "string" },
Remarks : { type: "string" }
}
}
}
});
I.e.:
Set batch to true for being able to send multiple requests at a time when you invoke sync.
Define Id in the schema.model.fields definition.
Do the stringify of options.models.
As agendaBatch is obviously an array, I assume that kendo.stringify is not serializing it properly. You could go with JSON.stringify.
Note that this is not implemented by older browsers. If you need to support them, you could include the script by Douglas Crockford:
https://github.com/douglascrockford/JSON-js/blob/master/json2.js
EDIT
Now that you changed your question - I am not really familiar with kendo ui, so this really is just a wild guess in an attempt to help you with your updated problem.
It looks like you have access to the data in the beforeSend function. You could try to manipulate it for your needs, like this maybe:
beforeSend: function (xhr, s) {
var arrayData = [];
for (var id in s.data) {
arrayData.push(s.data[id]);
}
s.data = arrayData;
}

select day and special date load by ajax to set in gldatepicker

I am using gldatepicker.I want to load some settings from database by ajax for gldatepicker such as day of week,special date etc.Now i have following js code for this:
$(document).ready(function () {
loadAllSettings();
});
var loadAllSettings = function () {
startDate = '';
endDate = '';
selectDay = '';
offdays = '';
$.ajax({
url: "bs_client_function.php",
type: "post",
dataType: "json",
data: {
action: 'getDateRange'
},
success: function (html) {
// alert(html.start);
startDate = Date.parse(html.start);
endDate = Date.parse(html.end);
}
});
$.ajax({
url: "bs_client_function.php",
type: "post",
dataType: "json",
data: {
action: 'getOffdays'
},
success: function (html) {
i = 0;
offdays = '[';
while (i < html.length) {
offdays = offdays + {
date: new Date(html[i]),
repeatYear: false,
cssClass: 'noday'
};
i = i + 1;
}
offdays = offdays + ']';
}
});
$.ajax({
url: "bs_client_function.php",
type: "post",
data: {
action: 'getDays'
},
success: function (html) {
var data = $.parseJSON(html);
// alert("[" + data + "]");
selectDay = '[' + data + ']';
// alert(selectDay);
showCalender(startDate, endDate, selectDay, offdays);
}
});
alert(selectDay);
console.log('selectDay' + selectDay);
};
I have checked all data is correctlly formated as gldatepicker recommanded.In my show calender
function:
var showCalender = function (startDate, endDate, selectDay, offdays) {
var dd = $('#mydate').glDatePicker({
showAlways: true,
allowMonthSelect: true,
allowYearSelect: false,
prevArrow: '\u25c4',
nextArrow: '\u25ba',
cssName: 'darkneon',
selectableDOW: selectDay,
dowOffset: 0,
selectedDate: new Date(),
selectableDateRange: [{
from: new Date(startDate),
to: new Date(endDate)
}, ],
specialDates: offdays
});
};
Now only stardate and enddate rightly working.selectDay,offdays are not working. i print selectDay in the console i got this: [1,2,3] but it not woking.What i am missing or what should be right way to do it.
Thanks in advance...
The problem is how you are getting your data for fill the glDatePicker.
You have 3 ajax calls, these calls are by default asynchronous, you execute your showCalender function in the last success function, but you have no sureness that the preceding calls are completed.
You can make your ajax calls synchronous by setting the async parameter to false see the jQuery docs:
async (default: true) Type: Boolean By default, all requests are sent
asynchronously (i.e. this is set to true by default). If you need
synchronous requests, set this option to false. Cross-domain requests
and dataType: "jsonp" requests do not support synchronous operation.
Note that synchronous requests may temporarily lock the browser,
disabling any actions while the request is active. As of jQuery 1.8,
the use of async: false with jqXHR ($.Deferred) is deprecated; you
must use the success/error/complete callback options instead of the
corresponding methods of the jqXHR object such as jqXHR.done() or the
deprecated jqXHR.success().
or you can chain them in every success callbacks, but your code will be difficult to mantain or you can use this plugin to manager multiple ajax calls http://docs.jquery.com/AjaxQueue
It works well with local data, see: http://jsfiddle.net/IrvinDominin/V59E7/
Pay attention only at the object that specialDates option needs:
specialDates: [{
date: new Date(0, 8, 5),
data: {
message: 'Happy Birthday!'
},
repeatYear: true,
cssClass: 'special-bday'
}, {
date: new Date(2013, 0, 8),
data: {
message: 'Meeting every day 8 of the month'
},
repeatMonth: true
}]

Categories

Resources