Backend API
@model DevExtreme.MVC.Demos.ViewModels.DynamicAppointmentsViewModel @(Html.DevExtreme().Scheduler() .ID("scheduler") .DataSource(Model.Appointments) .Views(new[] { SchedulerViewType.Week, SchedulerViewType.TimelineWeek }) .CurrentView(SchedulerViewType.Week) .CurrentDate(new JS("new Date()")) .ShowCurrentTimeIndicator(true) .ShadeUntilCurrentTime(true) .ShowAllDayPanel(false) .Editing(false) .Resources(res => { res.Add() .FieldExpr("MovieId") .ValueExpr("Id") .DataSource(Model.Resources); }) .Height(600) .StartDateExpr("StartDate") .EndDateExpr("EndDate") .RecurrenceRuleExpr("RecurrenceRule") .OnContentReady("onContentReady") .OnAppointmentClick("onAppointmentClick") .OnAppointmentDblClick("onAppointmentClick") .AppointmentTemplate(@<text> <% var movie = getMovieById(appointmentData.MovieId); %> <div class="movie"> <img src="<%- movie.Image %>" alt="" /> <div class="movie-text"><%- movie.Text %></div> </div> </text>) ) <div class="options"> <div class="column"> <div class="option"> <div class="label">Current time indicator</div> <div class="value"> @(Html.DevExtreme().Switch() .ID("show-indicator") .Value(true) .OnValueChanged("onCurrentTimeIndicatorChanged") ) </div> </div> <div class="option"> <div class="label">Shading until current time</div> <div class="value"> @(Html.DevExtreme().Switch() .ID("allow-shading") .Value(true) .OnValueChanged("onShadingChanged") ) </div> </div> </div> <div class="column"> <div class="option"> <div class="label">Update position in</div> <div class="value"> @(Html.DevExtreme().NumberBox() .ID("update-interval") .Min(1) .Max(1200) .Value(10) .Step(10) .ShowSpinButtons(true) .Width("100px") .Format("#0 s") .InputAttr("aria-label", "Position") .OnValueChanged("onUpdateIntervalChanged") ) </div> </div> </div> </div> <script> let moviesData = @Html.Raw(System.Text.Json.JsonSerializer.Serialize(Model.Resources)); function onContentReady(e) { e.component.scrollTo(new Date()); } function onAppointmentClick(e) { e.cancel = true; } function getSchedulerInstance() { return $("#scheduler").dxScheduler("instance"); } function getMovieById(id) { return DevExpress.data.query(moviesData) .filter("Id", id) .toArray()[0] } function onCurrentTimeIndicatorChanged(e) { getSchedulerInstance().option("showCurrentTimeIndicator", e.value); } function onShadingChanged(e) { getSchedulerInstance().option("shadeUntilCurrentTime", e.value); } function onUpdateIntervalChanged(e) { getSchedulerInstance().option("indicatorUpdateInterval", e.value * 1000); } </script>
using DevExtreme.MVC.Demos.Models.SampleData; using DevExtreme.MVC.Demos.ViewModels; using System.Web.Mvc; namespace DevExtreme.MVC.Demos.Controllers { public class SchedulerController : Controller { public ActionResult CurrentTimeIndicator() { return View(new DynamicAppointmentsViewModel { Appointments = SampleData.DynamicAppointments, Resources = SampleData.DynamicAppointmentsResources }); } } }
using System; using System.Collections.Generic; using System.Linq; namespace DevExtreme.MVC.Demos.Models { public class DynamicAppointment { public int MovieId { get; set; } public DateTime StartDate { get; set; } public DateTime EndDate { get; set; } public string RecurrenceRule { get; set; } } }
using System; using System.Collections.Generic; namespace DevExtreme.MVC.Demos.Models.SampleData { public partial class SampleData { public static IEnumerable<DynamicAppointment> DynamicAppointments { get { var today = DateTime.Today; var testDate = today.AddDays(3 - (int)today.DayOfWeek); return new[] { new DynamicAppointment { MovieId = 1, StartDate = testDate.AddHours(-113.5), EndDate = testDate.AddHours(-111.5), RecurrenceRule = "FREQ=HOURLY;INTERVAL=15;COUNT=15" }, new DynamicAppointment { MovieId = 2, StartDate = testDate.AddHours(-110.5), EndDate = testDate.AddHours(-108.5), RecurrenceRule = "FREQ=HOURLY;INTERVAL=15;COUNT=15" }, new DynamicAppointment { MovieId = 3, StartDate = testDate.AddHours(-106.5), EndDate = testDate.AddHours(-104.5), RecurrenceRule = "FREQ=HOURLY;INTERVAL=15;COUNT=15" }, new DynamicAppointment { MovieId = 4, StartDate = testDate.AddHours(-104), EndDate = testDate.AddHours(-102), RecurrenceRule = "FREQ=HOURLY;INTERVAL=15;COUNT=15" }, new DynamicAppointment { MovieId = 5, StartDate = testDate.AddHours(-101), EndDate = testDate.AddHours(-99), RecurrenceRule = "FREQ=HOURLY;INTERVAL=15;COUNT=15" } }; } } } }
using System; using System.Collections.Generic; using System.Linq; namespace DevExtreme.MVC.Demos.Models { public class DynamicAppointmentsResource { public int Id { get; set; } public string Text { get; set; } public string Image { get; set; } } }
using System; using System.Collections.Generic; namespace DevExtreme.MVC.Demos.Models.SampleData { public partial class SampleData { public static readonly IEnumerable<DynamicAppointmentsResource> DynamicAppointmentsResources = new[] { new DynamicAppointmentsResource { Id = 1, Text = "His Girl Friday", Image = "../../Content/Images/movies/HisGirlFriday.jpg" }, new DynamicAppointmentsResource { Id = 2, Text = "Royal Wedding", Image = "../../Content/Images/movies/RoyalWedding.jpg" }, new DynamicAppointmentsResource { Id = 3, Text = "A Star Is Born", Image = "../../Content/Images/movies/AStartIsBorn.jpg" }, new DynamicAppointmentsResource { Id = 4, Text = "The Screaming Skull", Image = "../../Content/Images/movies/ScreamingSkull.jpg" }, new DynamicAppointmentsResource { Id = 5, Text = "It's a Wonderful Life", Image = "../../Content/Images/movies/ItsAWonderfulLife.jpg" } }; } }
.dx-scheduler-appointment { color: #000000; font-weight: 500; background-color: #e4e4e4; } .dx-scheduler-appointment-recurrence .dx-scheduler-appointment-content { padding: 5px 0px 5px 7px; } .options { background-color: rgba(191, 191, 191, 0.15); margin-top: 20px; display: flex; align-items: flex-start; } .column { width: 40%; display: inline-block; margin: 15px 3%; text-align: left; vertical-align: top; } .option { padding: 5px 0; display:flex; align-items: center; } .label, .value { display: inline-block; vertical-align: middle; } .label { width: 180px; } .value { width: 30%; } .movie img { height: 70px; } .movie-text { font-size: 90%; white-space: normal; } #allow-shading, #show-indicator { height: 36px; }