I have a scheduler and a dropdown in a diary app. The scheduler is configured as such:
$("#scheduler").kendoScheduler({
date : Date.now(),
workDayStart: new Date("2015/1/1 08:00 AM"),
workDayEnd: new Date("2015/1/1 8:00 PM"),
dateHeaderTemplate: kendo.template("<strong>#=kendo.toString(date, 'ddd dd/M')#</strong>"),
majorTimeHeaderTemplate: kendo.template("<strong>#=kendo.toString(date, 'HH')#</strong><sup>00</sup>"),
minorTimeHeaderTemplate: kendo.template("<strong>#=kendo.toString(date, 'HH')#</strong><sup>#=kendo.toString(date, 'mm')#</sup>"),
selectable: true,
messages: {
ariaSlotLabel: "Selected from {0:g} to {0:g}",
showWorkDay: "Show core work hours"
},
editable: {
window: {
title: "Work Request Details",
width: "800px"
},
template: $("#customEditorTemplate").html()
},
edit: function (e) {
//set the start end datetime
if (e.event.isNew && e.event.id == -1) {
var startDtp = e.container.find("[name=start][data-role=datetimepicker]");
var endDtp = e.container.find("[name=end][data-role=datetimepicker]");
var setStartDate = e.event.start;
var setEndDate = e.event.end;
setStartDate.setHours(8);
setEndDate.setHours(-6); // by default the end date is midnight on the following day of the selected cell so we subtract 6h to get 18:00 on the selected date.
$(startDtp).data("kendoDateTimePicker").value(setStartDate); //set start date to the selected cell start date and time 08:00
$(endDtp).data("kendoDateTimePicker").value(setEndDate); //set enddate to the selected cell end date and time 18:00
}
var recurrenceEditor = e.container.find("[data-role=recurrenceeditor]").data("kendoRecurrenceEditor");
//set start option value, used to define the week 'Repeat on' selected checkboxes
recurrenceEditor.setOptions({
start: new Date(e.event.start)
});
},
eventTemplate: $("#eventTemplate").html(),
height: 550,
messages: {
allDay: "Anytime"
},
views: [
{ type: "day", allDaySlot: true},
{ type: "week", eventHeight: 80 },
{ type: "timeline", eventHeight: 80 },
{ type: "timelineWeek", selected: true, majorTick: 1440, minorTickCount: 1, eventHeight: 80 },
{ type: "agenda" },
{ type: "month", eventHeight: 80 }
],
timezone: "Etc/UTC",
selectable: true,
dataSource: {
parameterMap: function parameterMap(data, type) {
console.log(type);
if (type === "read") {
//var reqFilter = wRequestFilter.value();
var reqFilter = 'ALL'
console.log(reqFilter);
if (reqFilter == "MY") {
data.filter = { logic: "and", filters: [{ field: "diary", operator: "eq", value: 'UIS' }, { field: "AssigneeID", operator: "eq", value: 1 }] };
} else if (reqFilter == "ALL") {
data.filter = { logic: "and", filters: [{ field: "diary", operator: "eq", value: 'UIS' }] };
} else {
data.filter = { logic: "and", filters: [{ field: "diary", operator: "eq", value: 'UIS' }, { field: "team", operator: "eq", value: reqFilter }] };
}
}
console.log(data);
return data;
},
type: "signalr",
push: function (e) {
generateNotification(e.type, e.items[0].WRequestID, e.items[0].diary, e.items[0].team);
},
transport: {
signalr: {
hub: sHub,
promise: sHubStart,
server: {
read: "read",
create: "create",
update: "update",
destroy: "destroy"
},
client: {
read: "read",
create: "create",
update: "update",
destroy: "destroy"
}
},
},
schema: {
model: {
id: "WRequestID",
fields: {
WRequestID: {
type: "number",
editable: false,
defaultValue: -1
},
start: {
from: "Start",
type: "date",
culture: "en-GB"
},
end : {
from: "End",
type: "date",
culture: "en-GB" },
diary: {
from: "Diary",
type: "string",
defaultValue: "#AppShort"
},
team: {
from: "Team",
type: "string",
validation: { required: true }
},
title: {
from: "Title",
type: "string",
validation: { required: true }
},
workManager: {
from: "WorkManagerID",
type: "number",
validation: { required: true }
},
assignee: {
from: "AssigneeID",
type: "number",
validation: { required: true }
},
changeRef: {
from: "ChangeRef",
type: "string",
validation: { required: true }
},
description: {
from: "Description",
type: "string",
validation: { required: true }
},
impactedServers: {
from: "ImpactedServers",
type: "string",
validation: { required: true }
},
impactedServices: {
from: "ImpactedServices",
type: "string",
validation: { required: true }
},
isBAU: {
from: "IsBAU",
type: "boolean",
defaultValue: false
},
projectRef: {
from: "ProjectRef",
type: "string",
validation: { required: true }
},
notes: {
from: "Notes",
type: "string"
},
isOOH: {
from: "IsOOH",
type: "boolean",
defaultValue: false
},
isAllDay: {
from: "IsAllDay",
type: "boolean",
defaultValue: false
},
recurrenceRule: {
from: "RecurrenceRule",
type: "string"
},
recurrenceId: {
from: "RecurrenceID",
type: "number"
},
recurrenceException: {
from: "RecurrenceException",
type: "string"
},
startTimezone: {
from: "StartTimezone",
type: "string"
},
endTimezone: {
from: "EndTimezone",
type: "string"
},
requestStatus: {
from: "RequestStatus",
type: "number",
defaultValue: 0
}
}
},
},
}
});
I am trying to use parameterMap to filter the data based on one or two bits of data.
If the dropdown value = ALL then the data is filtered by diary =
#AppShort where #AppShort is derived from the web.config settings
section.
If the dropdown value = MY then the data is further filtered to just
display the current uses events
If the dropdown value is anything else then that means a team name is
selected and so the data is filtered by diary and team.
My problem is that the data is not filtered at all and the parameterMap function is never triggered. Is this the best approach or is there another way of implementing filtering.
Any help appreciated.
UPDATE
As requested... this is my signalR hub code:
Public Class WRequestHub
Inherits Hub
Private requestService As SchedulerRequestService
Public Sub New()
requestService = New SchedulerRequestService()
End Sub
Public Function Read() As IEnumerable(Of WRequestViewModel)
Return requestService.GetAll()
End Function
Public Sub Update(request As WRequestViewModel)
requestService.Update(request)
Clients.Others.update(request)
End Sub
Public Sub Destroy(request As WRequestViewModel)
requestService.Delete(request)
Clients.Others.destroy(request)
End Sub
Public Function Create(request As WRequestViewModel) As WRequestViewModel
requestService.Insert(request)
Clients.Others.create(request)
Return request
End Function
Public Sub LockRecord(id As Integer)
Clients.Others.lockRecord(New With {
Key .id = id
})
End Sub
Public Sub UnlockRecord(id As Integer)
Clients.Others.unlockRecord(New With {
Key .id = id
})
End Sub
End Class
And this is my SchedulerRequestService class...
Public Class SchedulerRequestService
Public Overridable Function GetAll() As IQueryable(Of WRequestViewModel)
Using de As New SupportDiaryEntities
Dim rList As IQueryable(Of WRequestViewModel)
rList = (From r In de.tWorkRequests
Select New WRequestViewModel() With {
.WRequestID = r.WRequestID,
.Start = r.Start,
.[End] = r.[End],
.Title = r.Title,
.Diary = r.Diary,
.Team = r.Team,
.WorkManagerID = r.WorkManagerID,
.AssigneeID = r.AssigneeID,
.ChangeRef = r.ChangeRef,
.Description = r.Description,
.ImpactedServers = r.ImpactedServers,
.ImpactedServices = r.ImpactedServices,
.IsBAU = r.IsBAU,
.ProjectRef = r.ProjectRef,
.Notes = r.Notes,
.IsOOH = r.IsOOH,
.IsAllDay = r.IsAllDay,
.RecurrenceRule = r.RecurrenceRule,
.RecurrenceID = r.RecurrenceID,
.RecurrenceException = r.RecurrenceException,
.StartTimezone = r.StartTimezone,
.EndTimezone = r.EndTimezone,
.RequestStatus = r.RequestStatus
}).ToList.AsQueryable()
Return rList
End Using
End Function
'OTHER FUNCTIONS (Insert, Update, Delete) Removed for brevity.
End Class
UPDATE 2
With some help from Calinaadi and examples of filtering a SignalR datasource on a Kendo Grid I can see that I need to modify my read function to accept my filter(s). Unfortunately the examples used with the grid had .take, .skip, .sort, .filter and .aggregate as paramenters which I understand when you have a grid with paging and you want to take X records after skipping Y records.
This is a typical example from telerik demos...
public DataSourceResult Read(MyDataSourceRequest request)
{
return productService.Read().ToDataSourceResult(request.Take, request.Skip, request.Sort, request.Filter, request.Aggregates);
}
For a scheduler I would expect a read to fetch back all events with an end on or after the start of the current scheduler view and a start on or before the end of the current scheduler view. Probably sorted by start. Filtered by the field filters is necessary (these are the filters I've set). I can't see take, skip or aggregate have any concept in fetching event data.
My app function completely apart from the filtering. I have a VS solution I can share if necessary with database populated with dummy records.
Offering a bounty for any help.
You should change:
transport: {
signalr: {
hub: sHub,
promise: sHubStart,
ParameterMap: "parameterMap",
to:
transport: {
parameterMap: function parameterMap(data, type) {
alert(type);
},
signalr: {
After many searches and much reading. I now have a working system. The scheduler required the parameter serverFiltering: true also the Read, Create, Update and Destroy functions has to be redone to accept the filter that was posted. If anyone would like a copy of the code which is a tad too much to post here I can let you have it.
Related
I want to show day in shift for example 24 days hours can be divided into 3 shift 8 hours each or can 6 hours each.
Against that i wanted to add events in Kendo Scheduler. Each day must have shift as show in below image
in the image shift marked for each day and noted with different color.
Each shift can or can not have events.
I'm also expecting functionality where events can move across the shifts.
I believe you'll have to implement a custom view to accomplish this. Here is a Telerik page that demonstrates it, and if you click the "Open in Dojo" link in the upper right of the code example you can see it execute (and edit and try it yourself).
Code example for their custom 3-day view from link
<div id="scheduler"></div>
<script>
var CustomAgenda = kendo.ui.AgendaView.extend({
endDate: function() {
var date = kendo.ui.AgendaView.fn.endDate.call(this);
return kendo.date.addDays(date, 31);
}
});
var ThreeDayView = kendo.ui.MultiDayView.extend({
nextDate: function () {
return kendo.date.nextDay(this.startDate());
},
options: {
selectedDateFormat: "{0:D} - {1:D}"
},
name: "ThreeDayView",
calculateDateRange: function () {
// Create a range of dates that will be displayed within the view.
var start = this.options.date,
idx, length,
dates = [];
for (idx = 0, length = 3; idx < length; idx++) {
dates.push(start);
start = kendo.date.nextDay(start);
}
this._render(dates);
}
});
$(function() {
$("#scheduler").kendoScheduler({
date: new Date("2013/6/13"),
startTime: new Date("2013/6/13 07:00 AM"),
height: 600,
views: [
"day",
"week",
// "custom week",
{ type: "ThreeDayView", title: "Three day view", selected: true },
// "custom agenda",
{ type: "CustomAgenda", title: "Custom Agenda" }
],
timezone: "Etc/UTC",
dataSource: {
batch: true,
transport: {
read: {
url: "https://demos.telerik.com/kendo-ui/service/tasks",
dataType: "jsonp"
},
update: {
url: "https://demos.telerik.com/kendo-ui/service/tasks/update",
dataType: "jsonp"
},
create: {
url: "https://demos.telerik.com/kendo-ui/service/tasks/create",
dataType: "jsonp"
},
destroy: {
url: "https://demos.telerik.com/kendo-ui/service/tasks/destroy",
dataType: "jsonp"
},
parameterMap: function(options, operation) {
if (operation !== "read" && options.models) {
return {models: kendo.stringify(options.models)};
}
}
},
schema: {
model: {
id: "taskId",
fields: {
taskId: { from: "TaskID", type: "number" },
title: { from: "Title", defaultValue: "No title", validation: { required: true } },
start: { type: "date", from: "Start" },
end: { type: "date", from: "End" },
startTimezone: { from: "StartTimezone" },
endTimezone: { from: "EndTimezone" },
description: { from: "Description" },
recurrenceId: { from: "RecurrenceID" },
recurrenceRule: { from: "RecurrenceRule" },
recurrenceException: { from: "RecurrenceException" },
ownerId: { from: "OwnerID", defaultValue: 1 },
isAllDay: { type: "boolean", from: "IsAllDay" }
}
}
}
}
});
});
</script>
So, I'm trying to make a readyonly grid with kendo that shows data, but whatever I do, the data does not get shown.
The grid looks like this
And here's the code:
$("#Materials")
.kendoGrid({
dataSource: {
data: [],
schema: {
model: {
id: "ID",
fields: {
ID: { type: "number", editable: false },
Code: { type: "string", editable: false },
Name: { type: "string", editable: false },
ExtDeviceCode: { type: "string", editable: false , nullable: true },
BaseUomLOVString: { type: "string", editable: false }
}
}
},
pageSize: 20
},
filterable: {
extra: true
},
pageable: true,
columns: [
{ field: "Code", title:"Code"},
{ field: "Name", title: "Name"},
{ field: "ExtDeviceCode", title:"External device code"},
{ field: "BaseUomLOVString", title: "UnitsOfMeasure" }
],
editable: false
});
This makes an empty grid with no data, which I later on fill with an Ajax call. As you can see from above picture, the grid contains the data but does not display it. The data inside the dataSource looks like this. or as Json:
[{
"ID": 21150,
"Code": "3",
"ExtDeviceCode": null,
"Name": "Avio benzin",
"BaseUomLOVString": "Kilogram"
}, {
"ID": 21400,
"Code": "5003",
"ExtDeviceCode": null,
"Name": "Bencin 95",
"BaseUomLOVString": "Litre"
}]
EDIT 1: I'm filling the data with an Ajax call like this:
$.ajax({
url: '#SimpleUrlHelper.UrlObjectToRoot(Url)/FuelPointMaterialTankMask/LookupMaterials',
data: {
//Send list of IDs
'materialIDs': materialList
},
type: "POST",
success: function (response) {
var tmp = [];
if (typeof response !== "undefined" &&
response !== null) {
response.forEach(function(item) {
tmp.push(item);
});
}
grid = $("#Materials").data("kendoGrid");
originalMaterialDataSource = grid.dataSource;
originalMaterialDataSource.data(tmp);
originalMaterialDataSource._destroyed = [];
originalMaterialDataSource.pageSize(pageSize);
originalMaterialDataSource.page(1);
originalMaterialDataSource._total = tmp.length;
grid.pager.refresh();
}
});
You can set your data in your dataSource after your ajax call.
var dataArray = [{
"ID": 21150,
"Code": "3",
"ExtDeviceCode": null,
"Name": "Avio benzin",
"BaseUomLOVString": "Kilogram"
}, {
"ID": 21400,
"Code": "5003",
"ExtDeviceCode": null,
"Name": "Bencin 95",
"BaseUomLOVString": "Litre"
}];
Use .data() to set:
$("#Materials").data('kendoGrid').dataSource.data(dataArray );
Okay so after days of trying to figure out what was wrong I finally found the answer.
Somewhere along the lines I had:
var grids = $('.k-grid');
for (var i = 0; i < grids.length; i++) {
....
grid.dataSource.filter().filters[0] = {
logic: "or",
filters: filters
}
....
So basically I was putting filters on all grids without excluding this one, which was just a bug from my part.
I'm trying to show some events in a kendo scheduler but they do not show. What are the required fields that the datasourse needs? I have id, title, start and end which is what the documentation says.
here is my code:
dataSource: {
batch: true,
transport: {
read: {
url: "/schedule/appointments_read",
dataType: "jsonp"
},
parameterMap: function(options, operation)
{
if (operation !== "read" && options.models)
{
return { models: kendo.stringify(options.models) };
}
},
schema: {
model: {
id: "id",
fields: {
id: { from: "Id", type: "number" },
title: { from: "Title", },
start: { from: "Start", type: "date"},
end: { from: "End", type: "date"}
}
}
}
}
}
here is the json that I return:
{"Data":
[{"Id":1,"Title":"AAA","Start":"\/Date(1414767600000)\/","End":"\/Date(1414771200000)\/"},
{"Id":2,"Title":"BBB","Start":"\/Date(1414771200000)\/","End":"\/Date(1414774800000)\/"},
{"Id":3,"Title":"CCC","Start":"\/Date(1414774800000)\/","End":"\/Date(1414778400000)\/"},
{"Id":4,"Title":"DDD","Start":"\/Date(1414778400000)\/","End":"\/Date(1414782000000)\/"}],
"Total":4,"AggregateResults":null,"Errors":null}
those are four one hour long appointments at 8:00, 9:00, 10:00 and 11:00 on the current day.
what am I missing?
Required fields are listed in the SchedulerEvent API.
http://jsfiddle.net/bhoff/ZCyPx/50/
$("#grid").kendoGrid({
dataSource:{
data:entries,
schema:{
parse:function (response) {
$.each(response, function (idx, elem) {
if (elem.time && typeof elem.time === "string") {
elem.time = kendo.parseDate(elem.time, "HH:mm:ss");
}
if (elem.datetime && typeof elem.datetime === "string") {
elem.datetime = kendo.parseDate(elem.datetime, "HH:mm:ss");
}
});
return response;
}
}
},
columns:[
{ command: [ "edit" ] },
{ field:"type", title:"Cash Transation Type" },
{ field:"begintime", title:"Begin Time(CT)", format:"{0:hh:mm tt}", editor: timeEditor },
{ field:"endtime", title:"End Time(CT)", format:"{0:hh:mm tt}", editor: timeEditor },
],
editable:"inline",
navigatable:true
});
Based on my example how do I stop the user from editing my "Cash Transation Type" column?
Does it have something to do with this -> editable:"inline" ?
look here
you need to set in the datasource
<script>
var dataSource = new kendo.data.DataSource({
schema: {
model: {
id: "ProductID",
fields: {
ProductID: {
//this field will not be editable (default value is true)
editable: false,
// a defaultValue will not be assigned (default value is false)
nullable: true
},
ProductName: {
//set validation rules
validation: { required: true }
},
UnitPrice: {
//data type of the field {Number|String|Boolean|Date} default is String
type: "number",
// used when new model is created
defaultValue: 42,
validation: { required: true, min: 1 }
}
}
}
}
});
</script>
You would normally set this on your DataSource on the schema.model.fields.
var data = new kendo.data.DataSource({
schema: {
model: {
fields: {
type: { editable: "false" }
Add editable in the field you do not want to enable Edit,
columns:[
{ command: [ "edit" ] },
{ field:"type", title:"Cash Transation Type", editable: false },
{ field:"begintime", title:"Begin Time(CT)", format:"{0:hh:mm tt}", editor: timeEditor },
{ field:"endtime", title:"End Time(CT)", format:"{0:hh:mm tt}", editor: timeEditor },
],
editable:"inline",
navigatable:true
});
I'm using Durandal and Kendo UI. My current problem is the edit popup event on my grid. I cannot seem to set the selected value on my dropdown.
I can debug and inspect, and I indeed do see the correct value of e.model.InstrumentName nicely populated.
How can I set the value/text of those dropdowns in edit mode ?
Here's my grid init:
positGrid = $("#positGrid").kendoGrid({
dataSource: datasource,
columnMenu: false,
{
field: "portfolioName", title: "Portfolio Name",
editor: portfolioDropDownEditor, template: "#=portfolioName#"
},
{
field: "InstrumentName",
width: "220px",
editor: instrumentsDropDownEditor, template: "#=InstrumentName#",
},
edit: function (e) {
var instrDropDown = $('#InstrumentName').data("kendoDropDownList");
var portfDropDown = $('#portfolioName').data("kendoDropDownList");
instrDropDown.list.width(350); // let's widen the INSTRUMENT dropdown list
if (!e.model.isNew()) { // set to current valuet
//instrDropDown.text(e.model.InstrumentName); // not working...
instrDropDown.select(1);
//portfDropDown.text();
}
},
filterable: true,
sortable: true,
pageable: true,
editable: "popup",
});
Here's my Editor Template for the dropdown:
function instrumentsDropDownEditor(container, options) {
// INIT INSTRUMENT DROPDOWN !
var dropDown = $('<input id="InstrumentName" name="InstrumentName">');
dropDown.appendTo(container);
dropDown.kendoDropDownList({
dataTextField: "name",
dataValueField: "id",
dataSource: {
type: "json",
transport: {
read: "/api/breeze/GetInstruments"
},
},
pageSize: 6,
select: onSelect,
change: function () { },
optionLabel: "Choose an instrument"
}).appendTo(container);
}
thanks a lot
Bob
Your editor configuration is bit unlucky for grid, anyway i have updated my ans on provided code avoiding manual selections:
Assumptions: Instrument dropdown editor only (leaving other fields as strings), Dummy data for grid
<div id="positGrid"></div>
<script>
$(document).ready(function () {
$("#positGrid").kendoGrid({
dataSource: {
data: [
{ PositionId: 1, Portfolio: "Jane Doe", Instrument: { IID: 3, IName: "Auth2" }, NumOfContracts: 30, BuySell: "sfsf" },
{ PositionId: 2, Portfolio: "John Doe", Instrument: { IID: 2, IName: "Auth1" }, NumOfContracts: 33, BuySell: "sfsf" }
],
schema: {
model: {
id: "PositionId",
fields: {
"PositionId": { type: "number" },
Portfolio: { validation: { required: true } },
Instrument: { validation: { required: true } },
NumOfContracts: { type: "number", validation: { required: true, min: 1 } },
BuySell: { validation: { required: true } }
}
}
}
},
toolbar: [
{ name: "create", text: "Add Position" }
],
columns: [
{ field: "PositionId" },
{ field: "Portfolio" },
{ field: "Instrument", width: "220px",
editor: instrumentsDropDownEditor, template: "#=Instrument.IName#" },
{ field: "NumOfContracts" },
{ field: "BuySell" },
{ command: [ "edit", "destroy" ]
},
],
edit: function (e) {
var instrDropDown = $('#InstrumentName').data("kendoDropDownList");
instrDropDown.list.width(400); // let's widen the INSTRUMENT dropdown list
},
//sortable: true,
editable: "popup",
});
});
function instrumentsDropDownEditor(container, options) {
$('<input id="InstrumentName" required data-text-field="IName" data-value-field="IID" data-bind="value:' + options.field + '"/>')
.appendTo(container)
.kendoDropDownList({
dataSource: {
type: "json",
transport: {
read: "../Home/GetMl"
}
},
optionLabel:"Choose an instrument"
});
}
</script>
Action fetching json for dropddown in Home controller:
public JsonResult GetMl()
{
return Json(new[] { new { IName = "Auth", IID = 1 }, new { IName = "Auth1", IID = 2 }, new { IName = "Auth2", IID = 3 } },
JsonRequestBehavior.AllowGet);
}