Your search did not match any results.
Scheduler

SignalR Service

This demo shows how two users can edit data in the Scheduler simultaneously. A SignalR service is used to broadcast push notifications.

Each Scheduler has an individual store to emulate the situation when Schedulers are being edited on two different clients. Changes made in one Scheduler are repeated in the other and persist until the browser session has expired.

<div class="schedulers"> @for(int i = 1; i <= 2; i++) { <div class="column-@i"> @(Html.DevExtreme().Scheduler() .ID(string.Format("{0}{1}", "scheduler", i)) .DataSource(d => d.Mvc() .Controller("SchedulerSignalR") .Key("AppointmentId") .LoadAction("Get") .UpdateAction("Put") .InsertAction("Post") .DeleteAction("Delete") ) .Views(new SchedulerViewType[] { SchedulerViewType.Day, SchedulerViewType.WorkWeek }) .CurrentView(SchedulerViewType.Day) .CurrentDate(new DateTime(2017, 5, 23)) .StartDayHour(9) .EndDayHour(19) .Height(600) .TextExpr("Text") .StartDateExpr("StartDate") .EndDateExpr("EndDate") .AllDayExpr("AllDay") ) </div> } </div> <script src="~/signalr/signalr-client.js"></script> <script> var connection = new signalR.HubConnectionBuilder() .withUrl("@Url.Content("~/schedulerSignalRHub")") .configureLogging(signalR.LogLevel.Information) .build(); $(function () { var store1 = $("#scheduler1").dxScheduler("getDataSource").store(); var store2 = $("#scheduler2").dxScheduler("getDataSource").store(); connection.start() .then(function () { connection.on("update", function (key, data) { store1.push([{ type: "update", key: key, data: data }]); store2.push([{ type: "update", key: key, data: data }]); }); connection.on("insert", function (data) { store1.push([{ type: "insert", data: data }]); store2.push([{ type: "insert", data: data }]); }); connection.on("remove", function (key) { store1.push([{ type: "remove", key: key }]); store2.push([{ type: "remove", key: key }]); }); }); }); </script>
using DevExtreme.NETCore.Demos.Models.SampleData; using DevExtreme.NETCore.Demos.ViewModels; using Microsoft.AspNetCore.Mvc; using System; using System.Collections.Generic; using System.Linq; namespace DevExtreme.NETCore.Demos.Controllers { public class SchedulerController : Controller { public ActionResult SignalRService() { return View(); } } }
using System; using System.Linq; using DevExtreme.AspNet.Data; using DevExtreme.AspNet.Mvc; using DevExtreme.NETCore.Demos.Hubs; using DevExtreme.NETCore.Demos.Models; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.SignalR; using Microsoft.Extensions.Caching.Memory; using Newtonsoft.Json; namespace DevExtreme.NETCore.Demos.Controllers.ApiControllers { [Route("api/[controller]")] public class SchedulerSignalRController : Controller { InMemoryAppointmentsDataContext _data; private static readonly Random random = new Random(); private IHubContext<SchedulerSignalRHub> hubContext; public SchedulerSignalRController(IHttpContextAccessor httpContextAccessor, IMemoryCache memoryCache, IHubContext<SchedulerSignalRHub> hubcontext) { _data = new InMemoryAppointmentsDataContext(httpContextAccessor, memoryCache); hubContext = hubcontext; } [HttpGet] public object Get(DataSourceLoadOptions loadOptions) { return DataSourceLoader.Load(_data.Appointments, loadOptions); } [HttpPost] public IActionResult Post(string values) { var newAppointment = new Appointment(); JsonConvert.PopulateObject(values, newAppointment); if(!TryValidateModel(newAppointment)) return BadRequest(ModelState.GetFullErrorMessage()); _data.Appointments.Add(newAppointment); _data.SaveChanges(); var groupName = GetGroupName(); if(groupName != null) { hubContext.Clients.Group(GetGroupName()).SendAsync("insert", newAppointment); } return Ok(); } [HttpPut] public IActionResult Put(int key, string values) { var appointment = _data.Appointments.First(a => a.AppointmentId == key); JsonConvert.PopulateObject(values, appointment); if(!TryValidateModel(appointment)) return BadRequest(ModelState.GetFullErrorMessage()); _data.SaveChanges(); var groupName = GetGroupName(); if(groupName != null) { hubContext.Clients.Group(GetGroupName()).SendAsync("update", key, appointment); } return Ok(); } [HttpDelete] public void Delete(int key) { var appointment = _data.Appointments.First(a => a.AppointmentId == key); _data.Appointments.Remove(appointment); _data.SaveChanges(); var groupName = GetGroupName(); if(groupName != null) { hubContext.Clients.Group(GetGroupName()).SendAsync("remove", key); } } string GetGroupName() { string cookie; HttpContext.Request.Cookies.TryGetValue(SchedulerSignalRHub.GroupIdKey, out cookie); return cookie; } } }
using System; using System.Collections.Generic; using System.Linq; using Newtonsoft.Json; namespace DevExtreme.NETCore.Demos.Models { public class Appointment { [JsonProperty(PropertyName = "AppointmentId")] public int AppointmentId { get; set; } [JsonProperty(PropertyName = "Text")] public string Text { get; set; } [JsonProperty(PropertyName = "StartDate")] public DateTime StartDate { get; set; } [JsonProperty(PropertyName = "EndDate")] public DateTime EndDate { get; set; } [JsonProperty(PropertyName = "AllDay")] public bool AllDay { get; set; } [JsonProperty(PropertyName = "RecurrenceRule")] public string RecurrenceRule { get; set; } } }
using System; using System.Collections.Generic; using System.Linq; namespace DevExtreme.NETCore.Demos.Models.SampleData { public partial class SampleData { public static List<Appointment> Appointments { get { return new List<Appointment> { new Appointment { AppointmentId = 1, Text = "Website Re-Design Plan", StartDate = new DateTime(2017, 5, 22, 9, 30, 0), EndDate = new DateTime(2017, 5, 22, 11, 30, 0) }, new Appointment { AppointmentId = 2, Text = "Book Flights to San Fran for Sales Trip", StartDate = new DateTime(2017, 5, 22, 12, 0, 0), EndDate = new DateTime(2017, 5, 22, 13, 0, 0), AllDay = true }, new Appointment { AppointmentId = 3, Text = "Install New Router in Dev Room", StartDate = new DateTime(2017, 5, 22, 14, 30, 0), EndDate = new DateTime(2017, 5, 22, 15, 30, 0) }, new Appointment { AppointmentId = 4, Text = "Approve Personal Computer Upgrade Plan", StartDate = new DateTime(2017, 5, 23, 10, 0, 0), EndDate = new DateTime(2017, 5, 23, 11, 0, 0) }, new Appointment { AppointmentId = 5, Text = "Final Budget Review", StartDate = new DateTime(2017, 5, 23, 12, 0, 0), EndDate = new DateTime(2017, 5, 23, 13, 35, 0) }, new Appointment { AppointmentId = 6, Text = "New Brochures", StartDate = new DateTime(2017, 5, 23, 14, 30, 0), EndDate = new DateTime(2017, 5, 23, 15, 45, 0) }, new Appointment { AppointmentId = 7, Text = "Install New Database", StartDate = new DateTime(2017, 5, 24, 9, 45, 0), EndDate = new DateTime(2017, 5, 24, 11, 15, 0) }, new Appointment { AppointmentId = 8, Text = "Approve New Online Marketing Strategy", StartDate = new DateTime(2017, 5, 24, 12, 0, 0), EndDate = new DateTime(2017, 5, 24, 14, 0, 0) }, new Appointment { AppointmentId = 9, Text = "Upgrade Personal Computers", StartDate = new DateTime(2017, 5, 24, 15, 15, 0), EndDate = new DateTime(2017, 5, 24, 16, 30, 0) }, new Appointment { AppointmentId = 10, Text = "Customer Workshop", StartDate = new DateTime(2017, 5, 25, 11, 0, 0), EndDate = new DateTime(2017, 5, 25, 12, 0, 0), AllDay = true }, new Appointment { AppointmentId = 11, Text = "Prepare 2015 Marketing Plan", StartDate = new DateTime(2017, 5, 25, 11, 0, 0), EndDate = new DateTime(2017, 5, 25, 13, 30, 0) }, new Appointment { AppointmentId = 12, Text = "Brochure Design Review", StartDate = new DateTime(2017, 5, 25, 14, 0, 0), EndDate = new DateTime(2017, 5, 25, 15, 30, 0) }, new Appointment { AppointmentId = 13, Text = "Create Icons for Website", StartDate = new DateTime(2017, 5, 26, 10, 0, 0), EndDate = new DateTime(2017, 5, 26, 11, 30, 0) }, new Appointment { AppointmentId = 14, Text = "Upgrade Server Hardware", StartDate = new DateTime(2017, 5, 26, 14, 30, 0), EndDate = new DateTime(2017, 5, 26, 16, 0, 0) }, new Appointment { AppointmentId = 15, Text = "Submit New Website Design", StartDate = new DateTime(2017, 5, 26, 16, 30, 0), EndDate = new DateTime(2017, 5, 26, 18, 0, 0) }, new Appointment { AppointmentId = 16, Text = "Launch New Website", StartDate = new DateTime(2017, 5, 26, 12, 20, 0), EndDate = new DateTime(2017, 5, 26, 14, 0, 0) } }; } } } }
using System; using System.Net; using System.Threading.Tasks; using Microsoft.AspNetCore.SignalR; namespace DevExtreme.NETCore.Demos.Hubs { public class SchedulerSignalRHub : Hub { public static string GroupIdKey = "dx-SchedulerSignalRHub-groupId"; private static readonly Random random = new Random(); public override Task OnConnectedAsync() { string cookie; Context.GetHttpContext().Request.Cookies.TryGetValue(GroupIdKey, out cookie); string groupId; if(cookie != null) { groupId = cookie; } else { groupId = random.Next(0, int.MaxValue).ToString(); Context.GetHttpContext().Response.Cookies.Append(GroupIdKey, groupId); } Groups.AddToGroupAsync(Context.ConnectionId, groupId); return base.OnConnectedAsync(); } } }
.schedulers { display: flex; } .column-1 { padding-right: 5px; } .column-2 { padding-left: 5px; } .dx-scheduler-small .dx-scheduler-view-switcher.dx-tabs { display: table; }