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.WebApi() .Controller("SchedulerSignalR") .Key("AppointmentId") .DeleteAction(true) .UpdateAction(true) .InsertAction(true) .Key("AppointmentId") ) .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="~/Scripts/signalr/jquery.signalR-2.2.2.js"></script> <script src="~/signalr/hubs"></script> <script> $(function () { var store1 = $("#scheduler1").dxScheduler("getDataSource").store(); var store2 = $("#scheduler2").dxScheduler("getDataSource").store(); var hub = $.connection.schedulerSignalRHub; hub.client.update = function (key, data) { store1.push([{ type: "update", key: key, data: data }]); store2.push([{ type: "update", key: key, data: data }]); }; hub.client.insert = function (data) { store1.push([{ type: "insert", data: data }]); store2.push([{ type: "insert", data: data }]); }; hub.client.remove = function (key) { store1.push([{ type: "remove", key: key }]); store2.push([{ type: "remove", key: key }]); }; $.connection.hub.start({ waitForPageLoad: false }); }); </script>
using DevExtreme.MVC.Demos.Models.SampleData; using DevExtreme.MVC.Demos.ViewModels; using System; using System.Collections.Generic; using System.Linq; using System.Web.Mvc; namespace DevExtreme.MVC.Demos.Controllers { public class SchedulerController : Controller { public ActionResult SignalRService() { return View(); } } }
using DevExtreme.AspNet.Data; using DevExtreme.AspNet.Mvc; using DevExtreme.MVC.Demos.Hubs; using DevExtreme.MVC.Demos.Models; using Microsoft.AspNet.SignalR; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Net.Http; using System.Net.Http.Formatting; using System.Web; using System.Web.Http; namespace DevExtreme.MVC.Demos.Controllers.ApiControllers { public class SchedulerSignalRController : ApiController { InMemoryAppointmentsDataContext _data = new InMemoryAppointmentsDataContext(); IHubContext hubContext; public SchedulerSignalRController() { hubContext = GlobalHost.ConnectionManager.GetHubContext<SchedulerSignalRHub>(); } [HttpGet] public HttpResponseMessage Get(DataSourceLoadOptions loadOptions) { return Request.CreateResponse(DataSourceLoader.Load(_data.Appointments, loadOptions)); } [HttpPost] public HttpResponseMessage Post(FormDataCollection form) { var values = form.Get("values"); var newAppointment = new Appointment(); JsonConvert.PopulateObject(values, newAppointment); Validate(newAppointment); if(!ModelState.IsValid) return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState.GetFullErrorMessage()); _data.Appointments.Add(newAppointment); _data.SaveChanges(); var groupName = GetGroupName(); if(groupName != null) { hubContext.Clients.Group(GetGroupName()).insert(newAppointment); } return Request.CreateResponse(HttpStatusCode.Created); } [HttpPut] public HttpResponseMessage Put(FormDataCollection form) { var key = Convert.ToInt32(form.Get("key")); var values = form.Get("values"); var appointment = _data.Appointments.First(a => a.AppointmentId == key); JsonConvert.PopulateObject(values, appointment); Validate(appointment); if(!ModelState.IsValid) return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState.GetFullErrorMessage()); _data.SaveChanges(); var groupName = GetGroupName(); if(groupName != null) { hubContext.Clients.Group(GetGroupName()).update(key, appointment); } return Request.CreateResponse(HttpStatusCode.OK); } [HttpDelete] public void Delete(FormDataCollection form) { var key = Convert.ToInt32(form.Get("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()).remove(key); } } string GetGroupName() { var cookie = Request.Headers.GetCookies(SchedulerSignalRHub.GroupIdKey).FirstOrDefault(); if(cookie != null) { return cookie[SchedulerSignalRHub.GroupIdKey].Value; } return null; } } }
using System; using System.Collections.Generic; using System.Linq; namespace DevExtreme.MVC.Demos.Models { public class Appointment { public int AppointmentId { get; set; } public string Text { get; set; } public DateTime StartDate { get; set; } public DateTime EndDate { get; set; } public bool AllDay { get; set; } public string RecurrenceRule { get; set; } } }
using System; using System.Collections.Generic; using System.Linq; namespace DevExtreme.MVC.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.Threading.Tasks; using System.Web; using Microsoft.AspNet.SignalR; namespace DevExtreme.MVC.Demos.Hubs { public class SchedulerSignalRHub : Hub { public static string GroupIdKey = "dx-SchedulerSignalRHub-groupId"; private static readonly Random random = new Random(); public override Task OnConnected() { Cookie cookie; this.Context.RequestCookies.TryGetValue(GroupIdKey, out cookie); string groupId; if(cookie != null) { groupId = cookie.Value; } else { groupId = random.Next(0, int.MaxValue).ToString(); var newCookie = new HttpCookie(GroupIdKey, groupId); Context.Request.GetHttpContext().Response.Cookies.Add(newCookie); } Groups.Add(Context.ConnectionId, groupId); return base.OnConnected(); } } }
.schedulers { display: flex; } .column-1 { padding-right: 5px; } .column-2 { padding-left: 5px; } .dx-scheduler-small .dx-scheduler-view-switcher.dx-tabs { display: table; }