mirror of
https://github.com/radzenhq/radzen-blazor.git
synced 2026-07-08 18:16:08 +00:00
Scheduler drag and drop with mobile support (#1395)
* Appointment drag and drop functionality for Scheduler component. * Added drag support for mobile devices. * Remove DragDropTouch.js. * Remove touch events. Set ondragstart as an attribute (required for mobile support). * Remove some views. --------- Co-authored-by: Atanas Korchev <akorchev@gmail.com>
This commit is contained in:
@@ -3,6 +3,7 @@ using Microsoft.AspNetCore.Components.Forms;
|
||||
using Microsoft.AspNetCore.Components.Web;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Radzen.Blazor;
|
||||
using Radzen.Blazor.Rendering;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
@@ -582,6 +583,22 @@ namespace Radzen
|
||||
public GoogleMapPosition Position { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Supplies information about a <see cref="DropableViewBase.AppointmentMove" /> event that is being raised.
|
||||
/// </summary>
|
||||
public class SchedulerAppointmentMoveEventArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the appointment data.
|
||||
/// </summary>
|
||||
public AppointmentData Appointment { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the time span.
|
||||
/// </summary>
|
||||
public TimeSpan TimeSpan { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Supplies information about a <see cref="RadzenMenu.Click" /> event that is being raised.
|
||||
/// </summary>
|
||||
|
||||
@@ -11,6 +11,11 @@ namespace Radzen.Blazor
|
||||
/// </summary>
|
||||
public interface IScheduler
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the appointment move event callback.
|
||||
/// </summary>
|
||||
/// <value>The appointment move event callback.</value>
|
||||
EventCallback<SchedulerAppointmentMoveEventArgs> AppointmentMove { get; set; }
|
||||
/// <summary>
|
||||
/// Gets the appointments in the specified range.
|
||||
/// </summary>
|
||||
@@ -97,15 +102,18 @@ namespace Radzen.Blazor
|
||||
/// </summary>
|
||||
/// <param name="reference"></param>
|
||||
/// <param name="data"></param>
|
||||
/// <returns></returns>
|
||||
Task MouseEnterAppointment(ElementReference reference, AppointmentData data);
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if the scheduler has a mouse enter appointment listener.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
bool HasMouseEnterAppointmentDelegate();
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if the scheduler has an AppointmentMove listener.
|
||||
/// </summary>
|
||||
bool HasAppointmentMoveDelegate();
|
||||
|
||||
/// <summary>
|
||||
/// Notifies the scheduler that the user has moved the mouse out of the specified appointment.
|
||||
/// </summary>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
|
||||
namespace Radzen.Blazor
|
||||
@@ -49,5 +50,11 @@ namespace Radzen.Blazor
|
||||
/// Gets the end date.
|
||||
/// </summary>
|
||||
DateTime EndDate { get; }
|
||||
/// <summary>
|
||||
/// Handles appointent move event.
|
||||
/// </summary>
|
||||
/// <param name="data"></param>
|
||||
/// <returns></returns>
|
||||
Task OnAppointmentMove(SchedulerAppointmentMoveEventArgs data);
|
||||
}
|
||||
}
|
||||
@@ -8,10 +8,11 @@
|
||||
{
|
||||
var appointments = Scheduler.GetAppointmentsInRange(StartDate, EndDate).ToList();
|
||||
|
||||
return
|
||||
return
|
||||
@<CascadingValue Value=@Scheduler>
|
||||
<DayView StartDate=@StartDate EndDate=@EndDate StartTime=@StartTime EndTime=@EndTime Appointments=@appointments
|
||||
TimeFormat=@TimeFormat MinutesPerSlot=@MinutesPerSlot />
|
||||
TimeFormat=@TimeFormat MinutesPerSlot=@MinutesPerSlot
|
||||
AppointmentMove=OnAppointmentMove />
|
||||
</CascadingValue>
|
||||
;
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
@inherits SchedulerViewBase
|
||||
|
||||
@code {
|
||||
@code {
|
||||
public override RenderFragment Render()
|
||||
{
|
||||
var appointments = Scheduler.GetAppointmentsInRange(StartDate, EndDate);
|
||||
@@ -21,7 +21,7 @@
|
||||
}
|
||||
|
||||
return @<CascadingValue Value=@Scheduler>
|
||||
<MonthView StartDate=@StartDate EndDate=@EndDate MaxAppointmentsInSlot=@maxAppointmentsInSlot MoreText=@MoreText Appointments=@appointments />
|
||||
<MonthView StartDate=@StartDate EndDate=@EndDate MaxAppointmentsInSlot=@maxAppointmentsInSlot MoreText=@MoreText Appointments=@appointments AppointmentMove=OnAppointmentMove />
|
||||
</CascadingValue>;
|
||||
}
|
||||
}
|
||||
@@ -235,6 +235,32 @@ namespace Radzen.Blazor
|
||||
[Parameter]
|
||||
public EventCallback<SchedulerLoadDataEventArgs> LoadData { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// A callback that will be invoked when an appointment is being dragged and then dropped on a different slot.
|
||||
/// Commonly used to change it to a different timeslot.
|
||||
/// </summary>
|
||||
/// <example>
|
||||
/// <code>
|
||||
/// <RadzenScheduler Data=@appointments AppointmentMove=@OnAppointmentMove>
|
||||
/// </RadzenScheduler>
|
||||
/// @code {
|
||||
/// async Task OnAppointmentMove(SchedulerAppointmentMoveEventArgs moved)
|
||||
/// {
|
||||
/// var draggedAppointment = appointments.SingleOrDefault(x => x == (Appointment)moved.Appointment.Data);
|
||||
/// if (draggedAppointment != null)
|
||||
/// {
|
||||
/// draggedAppointment.Start = draggedAppointment.Start + moved.TimeSpan;
|
||||
/// draggedAppointment.End = draggedAppointment.End + moved.TimeSpan;
|
||||
/// await scheduler.Reload();
|
||||
/// }
|
||||
/// }
|
||||
/// }
|
||||
/// </code>
|
||||
/// </example>
|
||||
/// <value></value>
|
||||
[Parameter]
|
||||
public EventCallback<SchedulerAppointmentMoveEventArgs> AppointmentMove { get; set; }
|
||||
|
||||
IList<ISchedulerView> Views { get; set; } = new List<ISchedulerView>();
|
||||
|
||||
/// <summary>
|
||||
@@ -610,5 +636,10 @@ namespace Radzen.Blazor
|
||||
{
|
||||
return AppointmentMouseEnter.HasDelegate;
|
||||
}
|
||||
|
||||
bool IScheduler.HasAppointmentMoveDelegate()
|
||||
{
|
||||
return AppointmentMove.HasDelegate;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
var appointments = Scheduler.GetAppointmentsInRange(StartDate, EndDate).ToList();
|
||||
|
||||
return @<CascadingValue Value=@Scheduler>
|
||||
<WeekView HeaderFormat=@HeaderFormat MinutesPerSlot=@MinutesPerSlot StartDate=@StartDate EndDate=@EndDate StartTime=@StartTime EndTime=@EndTime Appointments=@appointments TimeFormat="@TimeFormat" />
|
||||
<WeekView HeaderFormat=@HeaderFormat MinutesPerSlot=@MinutesPerSlot StartDate=@StartDate EndDate=@EndDate StartTime=@StartTime EndTime=@EndTime Appointments=@appointments TimeFormat="@TimeFormat" AppointmentMove=OnAppointmentMove />
|
||||
</CascadingValue>;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
@inherits SchedulerViewBase
|
||||
|
||||
@code {
|
||||
@code {
|
||||
public override RenderFragment Render()
|
||||
{
|
||||
var appointments = Scheduler.GetAppointmentsInRange(StartDate, EndDate);
|
||||
@@ -21,12 +21,13 @@
|
||||
}
|
||||
|
||||
return @<CascadingValue Value=@Scheduler>
|
||||
<YearPlannerView StartDate=@StartDate
|
||||
EndDate=@EndDate
|
||||
<YearPlannerView StartDate=@StartDate
|
||||
EndDate=@EndDate
|
||||
StartMonth=@StartMonth
|
||||
MaxAppointmentsInSlot=@maxAppointmentsInSlot
|
||||
MoreText=@MoreText
|
||||
Appointments=@appointments />
|
||||
MaxAppointmentsInSlot=@maxAppointmentsInSlot
|
||||
MoreText=@MoreText
|
||||
Appointments=@appointments
|
||||
AppointmentMove=OnAppointmentMove />
|
||||
</CascadingValue>;
|
||||
}
|
||||
}
|
||||
@@ -26,7 +26,8 @@
|
||||
StartMonth=@StartMonth
|
||||
MaxAppointmentsInSlot=@maxAppointmentsInSlot
|
||||
MoreText=@MoreText
|
||||
Appointments=@appointments />
|
||||
Appointments=@appointments
|
||||
AppointmentMove=OnAppointmentMove />
|
||||
</CascadingValue>;
|
||||
}
|
||||
}
|
||||
@@ -1,19 +1,23 @@
|
||||
@using Radzen.Blazor
|
||||
@using Radzen.Blazor.Rendering
|
||||
|
||||
<div @ref=@element class="@($"{"rz-event"} {CssClass}".Trim())" style=@Style @onclick=@OnClick @onmouseenter=@OnMouseEnter @onmouseleave=@OnMouseLeave>
|
||||
<div class="rz-event-content" title=@Title @attributes=@Attributes>
|
||||
@if (ShowAppointmentContent)
|
||||
{
|
||||
@Scheduler.RenderAppointment(Data)
|
||||
}
|
||||
<div @ref=@element class="@($"{"rz-event"} {CssClass}".Trim())" draggable=@DraggableAttribute style=@Style @onclick=@OnClick @onmouseenter=@OnMouseEnter @onmouseleave=@OnMouseLeave @ondrag=@OnDragStart ondragstart=@OnDragStartAttribute>
|
||||
<div class="rz-event-content" title=@Title @attributes=@Attributes>
|
||||
@if (ShowAppointmentContent)
|
||||
{
|
||||
@Scheduler.RenderAppointment(Data)
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@code {
|
||||
private ElementReference element;
|
||||
|
||||
private string Title => Scheduler.HasMouseEnterAppointmentDelegate() ? null : Data?.Text;
|
||||
|
||||
private string DraggableAttribute => Scheduler?.HasAppointmentMoveDelegate() == true ? "true" : null;
|
||||
|
||||
private string OnDragStartAttribute => Scheduler?.HasAppointmentMoveDelegate() == true ? "event.dataTransfer.setData('', event.target.id)" : null;
|
||||
|
||||
[Parameter]
|
||||
public string CssClass { get; set; }
|
||||
|
||||
@@ -32,6 +36,9 @@
|
||||
[Parameter]
|
||||
public EventCallback<AppointmentData> Click { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public EventCallback<AppointmentData> DragStart { get; set; }
|
||||
|
||||
IDictionary<string, object> Attributes { get; set; }
|
||||
|
||||
[Parameter]
|
||||
@@ -88,4 +95,9 @@
|
||||
{
|
||||
await Scheduler.MouseLeaveAppointment(element, Data);
|
||||
}
|
||||
|
||||
public async Task OnDragStart(DragEventArgs args)
|
||||
{
|
||||
await DragStart.InvokeAsync(Data);
|
||||
}
|
||||
}
|
||||
@@ -33,12 +33,14 @@
|
||||
@if (item.Start >= start && item.Start <= end)
|
||||
{
|
||||
<Appointment Data=@item Top=@top Left=@left Width=@width Height=@height Click=@OnAppointmentSelect
|
||||
CssClass="@(CurrentDate.Date == date.Date && object.Equals(Appointments.Where(i => i.Start.Date == CurrentDate.Date).OrderBy(i => i.Start).ThenByDescending(i => i.End).ElementAtOrDefault(CurrentAppointment),item) ? "rz-state-focused" : "")" />
|
||||
CssClass="@(CurrentDate.Date == date.Date && object.Equals(Appointments.Where(i => i.Start.Date == CurrentDate.Date).OrderBy(i => i.Start).ThenByDescending(i => i.End).ElementAtOrDefault(CurrentAppointment),item) ? "rz-state-focused" : "")"
|
||||
DragStart=@OnAppointmentDragStart />
|
||||
}
|
||||
else if (date == StartDate)
|
||||
{
|
||||
<Appointment Data=@item Top=@top Left=@left Width=@width Height=@height Click=@OnAppointmentSelect
|
||||
CssClass="@(CurrentDate == date && CurrentAppointment != - 1 && object.Equals(appointments.ElementAtOrDefault(CurrentAppointment),item) ? "rz-state-focused" : "")" />
|
||||
CssClass="@(CurrentDate == date && CurrentAppointment != - 1 && object.Equals(appointments.ElementAtOrDefault(CurrentAppointment),item) ? "rz-state-focused" : "")"
|
||||
DragStart=@OnAppointmentDragStart />
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -63,6 +65,9 @@
|
||||
[Parameter]
|
||||
public int MinutesPerSlot { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public EventCallback<AppointmentData> AppointmentDragStart { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public IList<AppointmentData> Appointments { get; set; }
|
||||
|
||||
@@ -136,4 +141,9 @@
|
||||
return groups;
|
||||
}
|
||||
|
||||
public async Task OnAppointmentDragStart(AppointmentData Data)
|
||||
{
|
||||
await AppointmentDragStart.InvokeAsync(Data);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
@using Radzen.Blazor
|
||||
@inherits DropableViewBase
|
||||
|
||||
<div class="rz-view rz-day-view">
|
||||
<div class="rz-view-header">
|
||||
@@ -11,11 +12,11 @@
|
||||
@onfocus=@(args => {if(CurrentDate == default(DateTime)) { CurrentDate = StartDate; }})>
|
||||
<Hours Start=@StartTime End=@EndTime TimeFormat=@TimeFormat MinutesPerSlot=@MinutesPerSlot />
|
||||
<div class="rz-slots">
|
||||
<DaySlotEvents MinutesPerSlot=@MinutesPerSlot StartDate=@StartDate EndDate=@EndDate Appointments=@Appointments CurrentDate="@CurrentDate" CurrentAppointment="@currentAppointment"/>
|
||||
<DaySlotEvents MinutesPerSlot=@MinutesPerSlot StartDate=@StartDate EndDate=@EndDate Appointments=@Appointments CurrentDate="@CurrentDate" CurrentAppointment="@currentAppointment" AppointmentDragStart=@OnAppointmentDragStart />
|
||||
@for (var date = StartDate; date < EndDate; date = date.AddMinutes(MinutesPerSlot))
|
||||
{
|
||||
var slotDate = date;
|
||||
<div @onclick=@(args => OnSlotClick(slotDate)) @attributes=@Attributes(date)></div>
|
||||
<div @onclick=@(args => OnSlotClick(slotDate)) @attributes=@Attributes(date) ondragover="event.preventDefault();" @ondrop=@(args => @OnDrop(slotDate))></div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
@@ -67,6 +68,7 @@
|
||||
{
|
||||
var attributes = Scheduler.GetSlotAttributes(date, date.AddMinutes(MinutesPerSlot));
|
||||
attributes["class"] = ClassList.Create("rz-slot").Add("rz-slot-minor", (date.Minute / MinutesPerSlot) % 2 == 1).Add(attributes).ToString();
|
||||
attributes["dropzone"] = "move";
|
||||
return attributes;
|
||||
}
|
||||
|
||||
@@ -119,4 +121,4 @@
|
||||
preventKeyPress = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
54
Radzen.Blazor/Rendering/DropableViewBase.cs
Normal file
54
Radzen.Blazor/Rendering/DropableViewBase.cs
Normal file
@@ -0,0 +1,54 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
|
||||
namespace Radzen.Blazor.Rendering
|
||||
{
|
||||
/// <summary>
|
||||
/// A base class for <see cref="MonthView" /> <see cref="DayView" /> <see cref="WeekView" /> <see cref="YearPlannerView" /> <see cref="YearTimelineView" /> views.
|
||||
/// </summary>
|
||||
public abstract class DropableViewBase : ComponentBase
|
||||
{
|
||||
private bool dragStarted = false;
|
||||
private AppointmentData draggedAppointment;
|
||||
/// <summary>
|
||||
/// Gets or sets the appointment move event callback.
|
||||
/// </summary>
|
||||
/// <value>The appointment move event callback.</value>
|
||||
[Parameter]
|
||||
public EventCallback<SchedulerAppointmentMoveEventArgs> AppointmentMove { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Handles on slot drop.
|
||||
/// </summary>
|
||||
/// <param name="slotDate"></param>
|
||||
/// <returns>Task</returns>
|
||||
public async Task OnDrop(DateTime slotDate)
|
||||
{
|
||||
if (draggedAppointment != null)
|
||||
{
|
||||
TimeSpan timespan = slotDate - draggedAppointment.Start;
|
||||
|
||||
await AppointmentMove.InvokeAsync(new SchedulerAppointmentMoveEventArgs { Appointment = draggedAppointment, TimeSpan = timespan });
|
||||
|
||||
draggedAppointment = null;
|
||||
}
|
||||
|
||||
dragStarted = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles Appointment drag started.
|
||||
/// </summary>
|
||||
/// <param name="data"></param>
|
||||
/// <returns></returns>
|
||||
public void OnAppointmentDragStart(AppointmentData data)
|
||||
{
|
||||
if (!dragStarted)
|
||||
{
|
||||
dragStarted = true;
|
||||
draggedAppointment = data;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,17 +2,19 @@
|
||||
@using Radzen.Blazor
|
||||
@using Radzen.Blazor.Rendering
|
||||
@inject DialogService DialogService
|
||||
@inherits DropableViewBase
|
||||
|
||||
<div class="rz-view rz-month-view">
|
||||
<div class="rz-view-header">
|
||||
@for(var date = StartDate; date <= StartDate.EndOfWeek(); date = date.AddDays(1))
|
||||
{
|
||||
<div class="rz-slot-header">
|
||||
@date.ToString("ddd", Scheduler.Culture)
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
@{
|
||||
|
||||
<div class="rz-view rz-month-view">
|
||||
<div class="rz-view-header">
|
||||
@for (var date = StartDate; date <= StartDate.EndOfWeek(); date = date.AddDays(1))
|
||||
{
|
||||
<div class="rz-slot-header">
|
||||
@date.ToString("ddd", Scheduler.Culture)
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
@{
|
||||
var days = 0;
|
||||
var points = new Dictionary<AppointmentData, double>();
|
||||
}
|
||||
@@ -49,7 +51,8 @@
|
||||
@if (item.Start >= start && item.Start <= end)
|
||||
{
|
||||
<Appointment Data=@item Top=@top Left=@left Width=@width Height=@height Click=@OnAppointmentClick
|
||||
CssClass="@(CurrentDate >= start && CurrentDate <= end && object.Equals(currentAppointments?.ElementAtOrDefault(currentAppointment),item) ? "rz-state-focused" : "")" />
|
||||
CssClass="@(CurrentDate >= start && CurrentDate <= end && object.Equals(currentAppointments?.ElementAtOrDefault(currentAppointment),item) ? "rz-state-focused" : "")"
|
||||
DragStart=@OnAppointmentDragStart />
|
||||
}
|
||||
else if (start == date)
|
||||
{
|
||||
@@ -58,7 +61,8 @@
|
||||
width = length * slotWidth;
|
||||
|
||||
<Appointment Data=@item Top=@top Left=@left Width=@width Height=@height Click=@OnAppointmentClick
|
||||
CssClass="@(CurrentDate == date && object.Equals(currentAppointments?.ElementAtOrDefault(currentAppointment),item) ? "rz-state-focused" : "")"/>
|
||||
CssClass="@(CurrentDate == date && object.Equals(currentAppointments?.ElementAtOrDefault(currentAppointment),item) ? "rz-state-focused" : "")"
|
||||
DragStart=@OnAppointmentDragStart />
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,7 +81,7 @@
|
||||
@for (var day = 0; day < 7; day ++)
|
||||
{
|
||||
var dayOfWeek = StartDate.AddDays(days++);
|
||||
<div @onclick="@(args => OnSlotClick(dayOfWeek))" @attributes=@Attributes(dayOfWeek)>
|
||||
<div @onclick="@(args => OnSlotClick(dayOfWeek))" @attributes=@Attributes(dayOfWeek) ondragover="event.preventDefault();" @ondrop=@(args => @OnDrop(dayOfWeek))>
|
||||
<div class="rz-slot-title @(dayOfWeek == CurrentDate ? " rz-state-focused" : "")">
|
||||
@dayOfWeek.Day
|
||||
</div>
|
||||
@@ -112,6 +116,7 @@
|
||||
{
|
||||
var attributes = Scheduler.GetSlotAttributes(start, start.AddDays(1));
|
||||
attributes["class"] = ClassList.Create("rz-slot").Add(attributes).ToString();
|
||||
attributes["dropzone"] = "move";
|
||||
return attributes;
|
||||
}
|
||||
|
||||
@@ -173,16 +178,16 @@
|
||||
|
||||
if (!preventDefault)
|
||||
{
|
||||
await DialogService.OpenAsync(date.ToShortDateString(), ds =>
|
||||
@<div class="rz-event-list">
|
||||
<CascadingValue Value=@Scheduler>
|
||||
@foreach(var item in appointments)
|
||||
{
|
||||
<Appointment Data=@item Click="OnListEventClick" />
|
||||
}
|
||||
</CascadingValue>
|
||||
</div>
|
||||
);
|
||||
await DialogService.OpenAsync(date.ToShortDateString(), ds =>
|
||||
@<div class="rz-event-list">
|
||||
<CascadingValue Value=@Scheduler>
|
||||
@foreach(var item in appointments)
|
||||
{
|
||||
<Appointment Data=@item Click="OnListEventClick" />
|
||||
}
|
||||
</CascadingValue>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
@using Radzen.Blazor
|
||||
@using Microsoft.JSInterop
|
||||
@inherits DropableViewBase
|
||||
@inject IJSRuntime JSRuntime
|
||||
|
||||
<div class="rz-view rz-week-view">
|
||||
@@ -20,12 +21,12 @@
|
||||
{
|
||||
var start = day.Add(StartTime);
|
||||
var end = day.Add(EndTime);
|
||||
<div class="rz-slots @(day == CurrentDate ? " rz-state-focused" : "")">
|
||||
<DaySlotEvents MinutesPerSlot=@MinutesPerSlot StartDate=@start EndDate=@end Appointments=@Appointments CurrentDate="@CurrentDate" CurrentAppointment="@currentAppointment"/>
|
||||
<div class="rz-slots @(day == CurrentDate ? " rz-state-focused" : "")">
|
||||
<DaySlotEvents MinutesPerSlot=@MinutesPerSlot StartDate=@start EndDate=@end Appointments=@Appointments CurrentDate="@CurrentDate" CurrentAppointment="@currentAppointment"AppointmentDragStart=@OnAppointmentDragStart/>
|
||||
@for (var date = start; date < end; date = date.AddMinutes(MinutesPerSlot))
|
||||
{
|
||||
var slotDate = date;
|
||||
<div @onclick=@(args => OnSlotClick(slotDate)) @attributes=@Attributes(date)></div>
|
||||
<div @onclick=@(args => OnSlotClick(slotDate)) @attributes=@Attributes(date) ondragover="event.preventDefault();" @ondrop=@(args => @OnDrop(slotDate))></div>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
@@ -81,6 +82,7 @@
|
||||
{
|
||||
var attributes = Scheduler.GetSlotAttributes(date, date.AddMinutes(MinutesPerSlot));
|
||||
attributes["class"] = ClassList.Create("rz-slot").Add("rz-slot-minor", (date.Minute / MinutesPerSlot) % 2 == 1).Add(attributes).ToString();
|
||||
attributes["dropzone"] = "move";
|
||||
return attributes;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
@using Radzen
|
||||
@using Radzen.Blazor
|
||||
@using Radzen.Blazor.Rendering
|
||||
@inherits DropableViewBase
|
||||
@inject DialogService DialogService
|
||||
|
||||
@{
|
||||
@@ -66,7 +67,7 @@
|
||||
|
||||
@if (item.Start >= realstart && item.Start <= end)
|
||||
{
|
||||
<Appointment Data=@item Top=@top Left=@left Width=@width Height=@height Click=@OnAppointmentClick ShowAppointmentContent=false />
|
||||
<Appointment Data=@item Top=@top Left=@left Width=@width Height=@height Click=@OnAppointmentClick ShowAppointmentContent=false DragStart=@OnAppointmentDragStart />
|
||||
}
|
||||
else if (realstart == start)
|
||||
{
|
||||
@@ -74,7 +75,7 @@
|
||||
length = Math.Max(1, Math.Min(daysinmonth, Math.Ceiling(item.End.Subtract(date).TotalDays - (startSlotIndex - 1))));
|
||||
width = length * slotWidth;
|
||||
|
||||
<Appointment Data=@item Top=@top Left=@left Width=@width Height=@height Click=@OnAppointmentClick ShowAppointmentContent=false />
|
||||
<Appointment Data=@item Top=@top Left=@left Width=@width Height=@height Click=@OnAppointmentClick ShowAppointmentContent=false DragStart=@OnAppointmentDragStart />
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,7 +110,7 @@
|
||||
|
||||
@if (slotInMonth)
|
||||
{
|
||||
<div @onclick="@(args => OnSlotClick(dayOfWeek))" @attributes=@Attributes(dayOfWeek, ($"rz-slot {dayType} {(CurrentDate.Date == dayOfWeek.Date ? "rz-state-focused" : "")}"), slotInMonth)>
|
||||
<div @onclick="@(args => OnSlotClick(dayOfWeek))" @attributes=@Attributes(dayOfWeek, ($"rz-slot {dayType} {(CurrentDate.Date == dayOfWeek.Date ? "rz-state-focused" : "")}"), slotInMonth) ondragover="event.preventDefault();" @ondrop=@(args => @OnDrop(dayOfWeek))>
|
||||
<div class="rz-slot-title">
|
||||
@dayOfWeek.Day
|
||||
</div>
|
||||
@@ -117,7 +118,7 @@
|
||||
}
|
||||
else
|
||||
{
|
||||
<div @attributes=@Attributes(dayOfWeek, ($"rz-slot {dayType}"), slotInMonth)>
|
||||
<div @attributes=@Attributes(dayOfWeek, ($"rz-slot {dayType}"), slotInMonth) ondragover="event.preventDefault();" @ondrop=@(args => @OnDrop(dayOfWeek))>
|
||||
<div class="rz-slot-title">
|
||||
</div>
|
||||
</div>
|
||||
@@ -162,6 +163,7 @@
|
||||
{
|
||||
var attributes = Scheduler.GetSlotAttributes(start, start.AddDays(1));
|
||||
attributes["class"] = ClassList.Create(className).Add(attributes).ToString();
|
||||
attributes["dropzone"] = "move";
|
||||
if (!slotInMonth)
|
||||
{
|
||||
attributes.Remove("style");
|
||||
@@ -264,7 +266,7 @@
|
||||
if(newDate < firstDate)
|
||||
{
|
||||
CurrentDate = firstDate;
|
||||
}
|
||||
}
|
||||
else if(newDate > lastDate)
|
||||
{
|
||||
CurrentDate = lastDate;
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
@using Radzen.Blazor.Rendering
|
||||
@using Microsoft.JSInterop
|
||||
@inject DialogService DialogService
|
||||
@inherits DropableViewBase
|
||||
@inject IJSRuntime JSRuntime
|
||||
@{
|
||||
var points = new Dictionary<AppointmentData, double>();
|
||||
@@ -67,7 +68,7 @@
|
||||
|
||||
@if (item.Start >= realstart && item.Start <= end)
|
||||
{
|
||||
<Appointment Data=@item Top=@top Left=@left Width=@width Height=@height Click=@OnAppointmentClick />
|
||||
<Appointment Data=@item Top=@top Left=@left Width=@width Height=@height Click=@OnAppointmentClick DragStart=@OnAppointmentDragStart />
|
||||
}
|
||||
else if (realstart == start)
|
||||
{
|
||||
@@ -75,7 +76,7 @@
|
||||
length = Math.Max(1, Math.Min(daysinmonth, Math.Ceiling(item.End.Subtract(date).TotalDays - (startSlotIndex - 1))));
|
||||
width = length * slotWidth;
|
||||
|
||||
<Appointment Data=@item Top=@top Left=@left Width=@width Height=@height Click=@OnAppointmentClick />
|
||||
<Appointment Data=@item Top=@top Left=@left Width=@width Height=@height Click=@OnAppointmentClick DragStart=@OnAppointmentDragStart />
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,7 +110,7 @@
|
||||
|
||||
@if (slotInMonth)
|
||||
{
|
||||
<div @onclick="@(args => OnSlotClick(dayOfWeek))" @attributes=@Attributes(dayOfWeek, ($"rz-slot {dayType} {(CurrentDate.Date == dayOfWeek.Date ? "rz-state-focused" : "")}"), slotInMonth)>
|
||||
<div @onclick="@(args => OnSlotClick(dayOfWeek))" @attributes=@Attributes(dayOfWeek, ($"rz-slot {dayType} {(CurrentDate.Date == dayOfWeek.Date ? "rz-state-focused" : "")}"), slotInMonth) ondragover="event.preventDefault();" @ondrop=@(args => @OnDrop(dayOfWeek))>
|
||||
<div class="rz-slot-title">
|
||||
@dayOfWeek.Day
|
||||
</div>
|
||||
@@ -117,7 +118,7 @@
|
||||
}
|
||||
else
|
||||
{
|
||||
<div @attributes=@Attributes(dayOfWeek, ($"rz-slot {dayType}"), slotInMonth)>
|
||||
<div @attributes=@Attributes(dayOfWeek, ($"rz-slot {dayType}"), slotInMonth) ondragover="event.preventDefault();" @ondrop=@(args => @OnDrop(dayOfWeek))>
|
||||
<div class="rz-slot-title">
|
||||
</div>
|
||||
</div>
|
||||
@@ -154,6 +155,7 @@
|
||||
{
|
||||
var attributes = Scheduler.GetSlotAttributes(start, start.AddDays(1));
|
||||
attributes["class"] = ClassList.Create(className).Add(attributes).ToString();
|
||||
attributes["dropzone"] = "move";
|
||||
if (!slotInMonth)
|
||||
{
|
||||
attributes.Remove("style");
|
||||
@@ -244,7 +246,7 @@
|
||||
{
|
||||
CurrentDate = StartDate.AddDays(1);
|
||||
}
|
||||
|
||||
|
||||
var key = args.Code != null ? args.Code : args.Key;
|
||||
|
||||
if (key == "ArrowLeft" || key == "ArrowRight")
|
||||
@@ -257,7 +259,7 @@
|
||||
if(newDate < firstDate)
|
||||
{
|
||||
CurrentDate = firstDate;
|
||||
}
|
||||
}
|
||||
else if(newDate > lastDate)
|
||||
{
|
||||
CurrentDate = lastDate;
|
||||
|
||||
@@ -34,6 +34,7 @@ namespace Radzen.Blazor
|
||||
[CascadingParameter]
|
||||
public IScheduler Scheduler { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Disposes this instance.
|
||||
/// </summary>
|
||||
@@ -88,5 +89,15 @@ namespace Radzen.Blazor
|
||||
/// </summary>
|
||||
/// <value>The end date.</value>
|
||||
public abstract DateTime EndDate { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Handles appointent move event.
|
||||
/// </summary>
|
||||
/// <param name="data"></param>
|
||||
/// <returns></returns>
|
||||
public async Task OnAppointmentMove(SchedulerAppointmentMoveEventArgs data)
|
||||
{
|
||||
await Scheduler.AppointmentMove.InvokeAsync(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,11 +2,11 @@
|
||||
|
||||
<RadzenScheduler @ref=@scheduler SlotRender=@OnSlotRender style="height: 768px;" TItem="Appointment" Data=@appointments StartProperty="Start" EndProperty="End"
|
||||
TextProperty="Text" SelectedIndex="2"
|
||||
SlotSelect=@OnSlotSelect AppointmentSelect=@OnAppointmentSelect AppointmentRender=@OnAppointmentRender>
|
||||
SlotSelect=@OnSlotSelect AppointmentSelect=@OnAppointmentSelect AppointmentRender=@OnAppointmentRender
|
||||
AppointmentMove=@OnAppointmentMove >
|
||||
<RadzenDayView />
|
||||
<RadzenWeekView />
|
||||
<RadzenMonthView />
|
||||
<RadzenYearView />
|
||||
</RadzenScheduler>
|
||||
|
||||
<EventConsole @ref=@console />
|
||||
@@ -93,4 +93,18 @@
|
||||
args.Attributes["style"] = "background: red";
|
||||
}
|
||||
}
|
||||
|
||||
async Task OnAppointmentMove(SchedulerAppointmentMoveEventArgs args)
|
||||
{
|
||||
var draggedAppointment = appointments.FirstOrDefault(x => x == args.Appointment.Data);
|
||||
|
||||
if (draggedAppointment != null)
|
||||
{
|
||||
draggedAppointment.Start = draggedAppointment.Start + args.TimeSpan;
|
||||
|
||||
draggedAppointment.End = draggedAppointment.End + args.TimeSpan;
|
||||
|
||||
await scheduler.Reload();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user