Fermer

mars 22, 2023

Comment afficher et créer un horaire dans l’interface utilisateur Telerik pour Blazor

Comment afficher et créer un horaire dans l’interface utilisateur Telerik pour Blazor


Lors de la création d’une vue de calendrier ou de planificateur pour votre application, il y a beaucoup de nuances impliquées. L’interface utilisateur Telerik pour Blazor Scheduler vise à gérer toutes ces complexités pour vous.

Si vous avez déjà essayé de créer une vue de calendrier ou de planificateur pour votre application, vous savez qu’il y a beaucoup de nuances impliquées, surtout si vous souhaitez activer des fonctionnalités « avancées » comme le glisser-déposer, le glisser pour redimensionner et plusieurs vues (jour , semaine mois).

Le Planificateur Blazor du progrès Interface utilisateur Telerik pour Blazor vise à gérer toutes ces complexités pour vous : lancez une nouvelle instance, lancez-lui des événements et vous devriez être prêt à partir.

Alors comment ça tient dans la pratique ? Découvrons-le.

Vous allez avoir besoin de certains événements

Nous avons d’abord besoin de quelques données pour notre ordonnanceur.

Nous commencerons par quelques événements simples codés en dur pour lancer le processus, puis nous passerons aux événements « réels » lorsque nous saurons que le calendrier fonctionne.

Créons un service pour renvoyer ces événements codés en dur :

CalendarService.cs

public class CalendarService
{
    private readonly List<CalendarEntry> _entries = new List<CalendarEntry>
    {
        new CalendarEntry
        {
            Title = "A Holiday",
            Start = new DateTime(2023,2,13),
            End = new DateTime(2023,2,13),
            IsAllDay = true
        }
    };

    public IEnumerable<CalendarEntry> List()
    {
        return _entries.ToList();
    }
}

Voici notre CalendarEntry classe:

public class CalendarEntry
{
    public Guid Id { get; }
    public string Title { get; set; }
    public string Description { get; set; }
    public DateTime Start { get; set; }
    public DateTime End { get; set; }
    public bool IsAllDay { get; set; }

    public CalendarEntry()
    {
        Id = Guid.NewGuid();
    }
}

Les noms de champs ici sont ceux par défaut que Telerik Planificateur va chercher. Si nous nous en tenons à ces noms, nous n’avons pas besoin d’effectuer de mappage supplémentaire pour que le planificateur interagisse avec et affiche nos événements (vacances dans ce cas).

Nous devrons nous assurer que cela est enregistré en tant que service pour notre application Blazor :

Programme.cs

...
    
builder.Services.AddSingleton<CalendarService>();

...

Ceci est une application Blazor Server; en l’enregistrant en tant que Singleton, nous pouvons nous assurer d’obtenir des données utiles avec lesquelles interagir et qui ne seront pas effacées à chaque fois que nous actualiserons le site. Dans une application de production, nous pointerions probablement cela vers une base de données plutôt que d’utiliser des données codées en dur comme celle-ci.

Maintenant, nous pouvons aller de l’avant et essayer d’afficher ces entrées de calendrier en utilisant TelerikScheduler:

Calendrier.razor

@page "/Calendar"
@inject CalendarService CalendarService

<TelerikScheduler Data="entries" @bind-Date="@StartDate" Height="600px">
    <SchedulerViews>
        <SchedulerWeekView StartTime="@DayStart" />
    </SchedulerViews>
</TelerikScheduler>
@code {
    
    public DateTime StartDate { get; set; } = DateTime.Now;
    public DateTime DayStart { get; set; } = new DateTime(2023, 2, 1, 8, 0, 0);

    private IEnumerable<CalendarEntry> entries;

    protected override async Task OnInitializedAsync()
    {
        entries = CalendarService.List();
    }
    
    ...
}

Nous avons créé un planificateur avec une seule « vue » (SchedulerWeekView). Les vues offrent différentes façons de représenter vos données de calendrier, par jour, semaine, mois, etc.

Nous avons également établi un StartDate (le calendrier affichera les événements à et autour de cette date lors du premier chargement du calendrier).

Enfin, nous avons spécifié un StartTime pour le SchedulerWeekView. Bien que ce soit un DateTimenous ne nous intéressons qu’à la partie temporelle de DateTime qui est utilisé pour contrôler la première heure affichée dans la vue.

Avec cela, nous avons un calendrier entièrement fonctionnel.

Affichage du calendrier montrant une seule semaine, commençant le lundi 30 janvier et se terminant le dimanche 5 février.  Il y a un marqueur bleu le mercredi qui montre un événement d'une journée entière avec le titre

Et si nous voulons ajouter des événements ?

Jusqu’ici tout va bien, mais que se passe-t-il si nous voulons laisser l’utilisateur ajouter ses propres entrées au calendrier ?

Nous devons d’abord activer la création d’événements, puis fournir une méthode qui contiendra la logique à exécuter lorsqu’un élément est ajouté.

<TelerikScheduler ... AllowCreate="true" OnCreate="OnItemCreated">
	...
</TelerikScheduler>

La méthode prend un argument de type SchedulerCreateEventArgs.

@code {
    
    ...
        
    private async Task OnItemCreated(SchedulerCreateEventArgs args)
    {
        var item = args.Item as CalendarEntry;
        CalendarService.Add(item);
        entries = CalendarService.List(); 
    } 
    
}

L’entrant SchedulerCreateEventArgs comprend un Item propriété que nous pouvons convertir en notre type de modèle spécifique (CalendarEntry).

Nous pouvons transmettre cet article à notre CalendarService (afin qu’il puisse s’occuper de l’ajouter à la liste des entrées), et récupère les entrées (pour voir le nouvel élément dans la liste).

Voici ça Add méthode dans CalendarService.

CalendarService.cs

namespace DemoServer.Services;

public class CalendarService
{
    ...

    public void Add(CalendarEntry item)
    {
        _entries.Add(item);
    }
}

Avec ces modifications, nous pouvons double-cliquer sur le calendrier et un formulaire pratique pour ajouter un nouvel événement s’affichera :

Un formulaire avec plusieurs champs pour ajouter une nouvelle entrée à un calendrier, y compris Titre, DateHeure de début et DateHeure de fin, ainsi que des options pour marquer l'événement comme étant Toute la journée et répéter l'entrée

Autoriser les utilisateurs à modifier des événements existants

Nous pouvons également permettre aux utilisateurs de modifier les événementsavec le AllowUpdate et OnUpdate paramètres:

<TelerikScheduler ... AllowUpdate="true" OnUpdate="OnItemEdited">
   ...
</TelerikScheduler>

Nous avons activé la mise à jour des éléments avec AllowUpdate et lorsque l’utilisateur modifie un élément, notre OnItemUpdated méthode sera invoquée.

private async Task OnItemUpdated(SchedulerUpdateEventArgs args)
{
    var item = args.Item as CalendarEntry;
    CalendarService.Edit(item);
    entries = CalendarService.List();   
}

Ici, encore une fois, nous lançons l’élément entrant sur args.Item à notre CalendarEntry taper.

On laisse ensuite CalendarService gérer la mise à jour proprement dite, avant d’actualiser les données pour refléter nos modifications.

CalendarService.cs

namespace DemoServer.Services;

public class CalendarService
{

	...

    public void Edit(CalendarEntry item)
    {
        var existingEntry = _entries.FirstOrDefault(x => x.Id == item.Id);
        _entries.Remove(existingEntry);
        _entries.Add(item);
    }
}

(Dans une application de production, nous modifierions probablement l’entrée existante, mais il est plus facile pour notre démo de supprimer l’ancienne entrée et de la remplacer par une nouvelle entrée pour l’élément modifié).

Avec cela, si un utilisateur double-clique sur une entrée existante, il verra l’interface utilisateur d’édition intégrée.

Juste avant de passer à la suppression d’éléments, un peu de duplication s’est glissée ici, avec plusieurs appels identiques pour actualiser les données du calendrier. Déplaçons ce code dans une méthode distincte qui peut être appelée à partir de plusieurs endroits.

@code {
    
    public DateTime StartDate { get; set; } = DateTime.Now;
    public DateTime DayStart { get; set; } = new DateTime(2023, 2, 1, 8, 0, 0);
    
    private IEnumerable<CalendarEntry> entries;
    
    protected override async Task OnInitializedAsync()
    {
        await LoadData();
    }    
    
    private async Task LoadData()
    {
        entries = CalendarService.List(); 
    }
    
    private async Task OnItemCreated(SchedulerCreateEventArgs args)
    {
        var item = args.Item as CalendarEntry;
        CalendarService.Add(item);
        await LoadData();   
    }

    private async Task OnItemEdited(SchedulerUpdateEventArgs args)
    {
        var item = args.Item as CalendarEntry;
        CalendarService.Edit(item);
        await LoadData();   
    }
    
}

Maintenant, nous avons un seul LoadData méthode que nous pouvons appeler chaque fois que nous voulons (re)récupérer nos données de calendrier.

Glisser-déposer, redimensionner pour reprogrammer

Si vous avez déjà essayé d’implémenter la fonctionnalité « glisser-déposer », vous savez que ce n’est pas toujours simple. Heureusement, dans ce cas, Telerik UI pour Blazor Scheduler s’en charge pour nous.

Lorsque l’édition est activée, nous pouvons faire glisser une entrée existante vers un nouveau créneau horaire (le même jour ou un jour différent) et l’événement sera automatiquement mis à jour.

Il est également possible de modifier une entrée en cliquant sur l’un de ses bords et en étendant (ou en réduisant) la quantité d’espace qu’elle occupe (modifiant ainsi l’heure de début et/ou de fin de l’entrée).

Activer la suppression d’événements

Comme vous vous en doutez, vous pouvez également activer la suppression des entrées :

<TelerikScheduler ... AllowDelete="true" OnDelete="Callback">
@code {
    
    ...
        
    private async Task OnDelete(SchedulerDeleteEventArgs args)
    {
        var item = args.Item as CalendarEntry;
        CalendarService.Delete(item);
        await LoadData();
    }
    
}

À présent, cela semble assez familier. Nous transtypons l’élément entrant en une instance de CalendarEntrypuis transmettez-le à CalendarService qui effectue la suppression proprement dite :

CalendarService.cs

...

public void Delete(CalendarEntry item)
{
    var existingEntry = _entries.FirstOrDefault(x => x.Id == item.Id);
    _entries.Remove(existingEntry);
}

Scénario avancé—Événements en lecture seule

Enfin, regardons un scénario un peu plus avancé.

Supposons que nous voulions extraire une liste de jours fériés et les afficher dans le calendrier, mais, surtout, ces entrées doivent être « en lecture seule » (non modifiables par l’utilisateur).

Bien qu’il n’y ait pas de concept intégré d’événements en lecture seule pour le composant Scheduler, il existe un moyen pratique d’implémenter cette fonctionnalité avec un minimum de code.

Tout d’abord, ajoutons quelques jours fériés à notre calendrier. Pour cela, nous utiliserons l’API Public Holidays très pratique de Nager.Date.

Créons un nouveau service pour récupérer les jours fériés et les renvoyer en tant qu’entrées pour notre calendrier :

using DemoServer.Services;

namespace CalendarDemo.Services;

public class PublicHolidayService
{
    private readonly HttpClient _httpClient;

    public PublicHolidayService(HttpClient httpClient)
    {
        _httpClient = httpClient;
    }

    public async Task<IEnumerable<CalendarEntry>> ListForYear(int year)
    {
        var holidays = await _httpClient.GetFromJsonAsync<NagerHoliday[]>($"https://date.nager.at/api/v3/publicholidays/{year}/GB");
        return holidays.Select(x=>new CalendarEntry
        {
            Title = $"{x.Name} ({x.CountryCode})",
            IsAllDay = true,
            Start = x.Date,
            End = x.Date,
            Description = x.LocalName
        });
    }

    public class NagerHoliday
    {
        public DateTime Date { get; set; }
        public string LocalName { get; set; }
        public string Name { get; set; }
        public string CountryCode { get; set; }
    }
}

Cela fait une récupération HTTP vers l’API Nager pour récupérer les jours fériés pour le donné yearpuis les convertit en instances de notre CalendarEntry classe.

Avec ceci enregistré en tant que service dans Program.cs…

Programme.cs

...

builder.Services.AddScoped<PublicHolidayService>();

...

Nous pouvons continuer et l’utiliser dans notre composant :

@page "/Calendar"
@inject CalendarService CalendarService
@inject PublicHolidayService PublicHolidayService

...

Maintenant, nous pouvons modifier LoadData pour combiner les entrées des deux services (notre original CalendarService et le nouveau PublicHolidayService:

@code {
    ...
        
    private async Task LoadData()
    {
        var calendarEntries = CalendarService.List();
        var holidays = await PublicHolidayService.ListForYear(2023);
        entries = calendarEntries.Concat(holidays);
    }
}

Cela récupère les entrées de notre service d’origine ainsi que les jours fériés de notre nouveau service de jours fériés, puis utilise le pratique Concat méthode pour combiner les deux listes ensemble.

Affichage du calendrier montrant une seule semaine, commençant le lundi 27 novembre et se terminant le dimanche 3 décembre.  Il y a un marqueur bleu le jeudi qui montre un événement d'une journée entière avec le titre 'Saint Andrew's Day (GB)

Nous allons maintenant voir les jours fériés dans notre calendrier, mais qu’en est-il de cette obligation de rendre les jours fériés en lecture seule ? Pour le moment, ils peuvent être modifiés comme n’importe quelle autre entrée.

Mettons à jour notre classe de modèle pour le calendrier (CalendarEntry) avoir un ReadOnly propriété:

public class CalendarEntry
{    
    ... other properties
        
    public bool ReadOnly { get; set; }

}

Avec cela, nous pouvons mettre à jour PublicHolidayService mettre en place ReadOnly pour true pour toutes ses entrées :

PublicHolidayService.cs

    public async Task<IEnumerable<CalendarEntry>> ListForYear(int year)
    {
        var holidays = await _httpClient.GetFromJsonAsync<NagerHoliday[]>($"https://date.nager.at/api/v3/publicholidays/{year}/GB");
        return holidays.Select(x=>new CalendarEntry
        {
            Title = $"{x.Name} ({x.CountryCode})",
            IsAllDay = true,
            Start = x.Date,
            End = x.Date,
            Description = x.LocalName,
            ReadOnly = true
        });
    }

Notre travail final est de faire TelerikScheduler réagir à cela ReadOnly indicateur et empêche l’utilisateur de modifier des éléments s’il est défini sur true.

TelerikScheduler a une pratique OnEdit méthode qui est appelée juste avant l’affichage de l’interface utilisateur d’édition (lorsque l’utilisateur tente de modifier un élément).

C’est l’endroit idéal pour annuler la modification si l’événement est marqué en lecture seule.

<TelerikScheduler ... OnEdit="OnEdit">
	...
</TelerikScheduler>
@code {
    
    ...
    
    private void OnEdit(SchedulerEditEventArgs args)
    {
        if (((CalendarEntry)args.Item).ReadOnly)
        {
            args.IsCancelled = true;
        }
    }
    
}

En réglant IsCancelled à vrai, nous signalons à Scheduler qu’il devrait abandonner la modification dans ce cas. Si un utilisateur tente de modifier (ou de supprimer) l’un de nos jours fériés, la modification sera annulée, l’interface utilisateur de modification ne s’affichera pas et l’utilisateur pourra poursuivre son activité.

En résumé

Telerik Scheduler est un moyen puissant, rapide et facile d’afficher les données de calendrier/horaire dans votre application Blazor.

Ici, nous avons vu comment lier le planificateur à une liste d’événements, puis permettre aux utilisateurs d’ajouter rapidement de nouveaux éléments, de modifier et de supprimer des éléments existants.

De plus, avec un peu d’aide du OnEdit rappel, nous pouvons aborder des scénarios avancés comme l’annulation de l’édition pour les éléments « en lecture seule ».

Essayez l’interface utilisateur Telerik pour Blazor Scheduler aujourd’hui

Vous voulez commencer à profiter de Telerik Scheduler ou de l’un des plus de 100 autres composants prêts à l’emploi, comme la grille ou les graphiques ? Démarrez un essai gratuit dès aujourd’hui et découvrez par vous-même que la création d’applications interactives riches pour la moitié du temps n’est qu’à un clic.

Essayez l’interface utilisateur Telerik pour Blazor

N’hésitez pas à partager votre expérience et vos idées dans la section des commentaires ci-dessous ou en visitant le Interface utilisateur Telerik pour le portail de commentaires Blazor https://feedback.telerik.com/blazor. Votre contribution fait la différence.




Source link