Elements Wave lBlue Hero

Telerik UI for Blazor

Develop Blazor applications in half the time with a high-performing Grid and
90+ truly native, easy-to-customize UI components to cover any requirement.

NEW

*Includes access to online technical training to speed-up your onboarding.

trust-radius-badge

Telerik Earns Multiple TrustRadius Best of Development 2021 awards

Telerik has won Best Feature Set and Best Customer Support.

trust-radius-badge

Telerik UI Earns TrustRadius' 2021 Top Rated Award

Progress Telerik UI has earned TrustRadius’ Top Rated Award for Software Components and .NET Development.

ninja-peeking
@using System.ComponentModel.DataAnnotations
@using Telerik.DataSource
 
<TelerikGrid Data=@GridData
             Height="450px"
             Width="100%"
             EditMode="@GridEditMode.Inline"
             Pageable="true"
             PageSize="10"
             Resizable="true"
             Reorderable="true"
             FilterMode="@GridFilterMode.FilterMenu"
             SelectionMode="@GridSelectionMode.Multiple"
             Groupable="true"
             Sortable="true"
             SortMode="@SortMode.Multiple"
             OnCreate="@CreateHandler"
             OnDelete="@DeleteHandler"
             OnUpdate="@UpdateHandler"
             OnStateInit="@((GridStateEventArgs<ProductO> args) => OnStateInit(args))">
    <GridToolBar>
        <GridCommandButton Command="Add" Icon="add">Add Product</GridCommandButton>
        <GridCommandButton Command="ExcelExport" Icon="file-excel">Export to Excel</GridCommandButton>
    </GridToolBar>
    <GridExport>
        <GridExcelExport FileName="telerik-grid-export" AllPages="true" />
    </GridExport>
    <GridColumns>
        <GridCheckboxColumn Width="80px" CheckBoxOnlySelection="true" SelectAllMode="@GridSelectAllMode.All"></GridCheckboxColumn>
        <GridColumn Field=@nameof(ProductO.ProductName) Width="220px" Title="Product Name" />
        <GridColumn Field=@nameof(ProductO.Cost) Title="Price" Width="100px" DisplayFormat="{0:C2}" TextAlign="@ColumnTextAlign.Right" />
        <GridColumn Field=@nameof(ProductO.Available) Title="In Stock" Width="100px" TextAlign="@ColumnTextAlign.Center">
            <Template>
                @{
                    bool isInStock = (context as ProductO).Available;

                    if (isInStock)
                    {
                        <span class="k-badge k-badge-md k-badge-solid k-badge-success k-badge-rounded">Available</span>
                    }
                    else
                    {
                        <span class="k-badge k-badge-md k-badge-solid k-badge-error k-badge-rounded">Not Available</span>
                    }
                }
            </Template>
        </GridColumn>
        <GridColumn Field=@nameof(ProductO.CategoryName) Title="Category" Width="150px" FilterMenuType="@FilterMenuType.CheckBoxList"></GridColumn>
        <GridCommandColumn Width="110px" Locked="true" Resizable="false">
            <GridCommandButton Command="Edit" Icon="edit">Edit</GridCommandButton>
            <GridCommandButton Command="Delete" Icon="delete">Delete</GridCommandButton>
            <GridCommandButton Command="Save" Icon="save" ShowInEdit="true">Save</GridCommandButton>
            <GridCommandButton Command="Cancel" Icon="cancel" ShowInEdit="true">Cancel</GridCommandButton>
        </GridCommandColumn>
    </GridColumns>
</TelerikGrid>

@code {
    public List<ProductO> GridData { get; set; }
    public List<ProductO> SourceData { get; set; }
    public List<ProductO> Categories { get; set; }
    int lastId = 0;

    protected override Task OnInitializedAsync()
    {
        InitSourceData();

        LoadData();

        return base.OnInitializedAsync();
    }

    private void CreateHandler(GridCommandEventArgs args)
    {
        CreateItem((ProductO)args.Item);

        LoadData();
    }


    private void CreateItem(ProductO item)
    {
        ProductO product = item;

        product.ProductId = ++lastId;
        SourceData.Insert(0, product);
    }

    private void DeleteHandler(GridCommandEventArgs args)
    {
        DeleteItem((ProductO)args.Item);
        
        LoadData();
    }

    private void DeleteItem(ProductO item)
    {
        SourceData.Remove(item);
    }

    private void UpdateHandler(GridCommandEventArgs args)
    {
        UpdateItem((ProductO)args.Item);

        LoadData();
    }

    private void UpdateItem(ProductO item)
    {
        var existing = SourceData.FirstOrDefault(p => p.ProductId == item.ProductId);

        if (existing != null)
        {
            existing.ProductName = item.ProductName;
            existing.Cost = item.Cost;
            existing.CategoryName = item.CategoryName;
            existing.Quantity = item.Quantity;
            existing.Available = item.Available;
        }
    }

    private void OnStateInit(GridStateEventArgs<ProductO> args)
    {
        args.GridState.GroupDescriptors = new List<GroupDescriptor>()
        {
            new GroupDescriptor()
            {
                Member = nameof(ProductO.CategoryName)
            }
        };
    }

    public class ProductO
    {
        public int ProductId { get; set; }
        public string ProductName { get; set; }
        public int CategoryId { get; set; }
        public CategoryName CategoryName { get; set; }

        public decimal Cost { get; set; }
        public string Quantity { get; set; }
        public bool Available { get; set; }

        public ProductO()
        {
            Available = true;
        }
    }

    public enum CategoryName
    {
        Beverages,
        Condiments,
        Confections,
        [Display(Name = "Dairy Products")]
        DairyProducts,
        [Display(Name = "Grains/Cereals")]
        Grains,
        [Display(Name = "Meat/Poultry")]
        Meat,
        Seafood
    }

    public void LoadData()
    {
        GridData = new List<ProductO>(SourceData);
    }

    public void InitSourceData()
    {       
        List<ProductO> data = new List<ProductO>();
        
        data.Add(new ProductO() { ProductId = 1, ProductName = "Chai", CategoryId = 1, CategoryName = CategoryName.Beverages, Cost = 18m, Quantity = "10 boxes x 20 bags" });
        data.Add(new ProductO() { ProductId = 2, ProductName = "Chang", CategoryId = 1, CategoryName = CategoryName.Beverages, Cost = 19m, Quantity = "24 - 12 oz bottles", Available = false });
        data.Add(new ProductO() { ProductId = 3, ProductName = "Guaraná Fantástica", CategoryId = 1, CategoryName = CategoryName.Beverages, Cost = 4.5m, Quantity = "12 - 355 ml cans" });
        data.Add(new ProductO() { ProductId = 4, ProductName = "Sasquatch Ale", CategoryId = 1, CategoryName = CategoryName.Beverages, Cost = 14m, Quantity = "24 - 12 oz bottles" });
        data.Add(new ProductO() { ProductId = 5, ProductName = "Steeleye Stout", CategoryId = 1, CategoryName = CategoryName.Beverages, Cost = 18.99m, Quantity = "24 - 12 oz bottles", Available = false });
        data.Add(new ProductO() { ProductId = 6, ProductName = "Côte de Blaye", CategoryId = 1, CategoryName = CategoryName.Beverages, Cost = 263.5m, Quantity = "12 - 75 cl bottles" });
        data.Add(new ProductO() { ProductId = 7, ProductName = "Chartreuse verte", CategoryId = 1, CategoryName = CategoryName.Beverages, Cost = 18m, Quantity = "750 cc per bottle" });
        data.Add(new ProductO() { ProductId = 8, ProductName = "Ipoh Coffee", CategoryId = 1, CategoryName = CategoryName.Beverages, Cost = 46m, Quantity = "16 - 500 g tins" });
                
        data.Add(new ProductO() { ProductId = 9, ProductName = "Aniseed Syrup", CategoryId = 2, CategoryName = CategoryName.Condiments, Cost = 10m, Quantity = "12 - 550 ml bottles" });
        data.Add(new ProductO() { ProductId = 10, ProductName = "Chef Anton's Cajun Seasoning", CategoryId = 2, CategoryName = CategoryName.Condiments, Cost = 22.80m, Quantity = "48 - 6 oz jars", Available = false });
        data.Add(new ProductO() { ProductId = 11, ProductName = "Chef Anton's Gumbo Mix", CategoryId = 2, CategoryName = CategoryName.Condiments, Cost = 21.35m, Quantity = "36 boxes" });
        data.Add(new ProductO() { ProductId = 12, ProductName = "Grandma's Boysenberry Spread", CategoryId = 2, CategoryName = CategoryName.Condiments, Cost = 25m, Quantity = "12 - 8 oz jars" });
        data.Add(new ProductO() { ProductId = 13, ProductName = "Northwoods Cranberry Sauce", CategoryId = 2, CategoryName = CategoryName.Condiments, Cost = 40m, Quantity = "12 - 12 oz jars" });
        data.Add(new ProductO() { ProductId = 14, ProductName = "Genen Shouyu", CategoryId = 2, CategoryName = CategoryName.Condiments, Cost = 15.50m, Quantity = "24 - 250 ml bottles" });
        data.Add(new ProductO() { ProductId = 15, ProductName = "Gula Malacca", CategoryId = 2, CategoryName = CategoryName.Condiments, Cost = 19.45m, Quantity = "20 - 2 kg bags", Available = false });
        data.Add(new ProductO() { ProductId = 16, ProductName = "Vegie-spread", CategoryId = 2, CategoryName = CategoryName.Condiments, Cost = 43.90m, Quantity = "15 - 625 g jars" });

        
        data.Add(new ProductO() { ProductId = 17, ProductName = "Pavlova", CategoryId = 3, CategoryName = CategoryName.Confections, Cost = 17.45m, Quantity = "100 - 250 g bags", Available = false });
        data.Add(new ProductO() { ProductId = 18, ProductName = "Teatime Chocolate Biscuits", CategoryId = 3, CategoryName = CategoryName.Confections, Cost = 9.20m, Quantity = "20 - 450 g glasses" });
        data.Add(new ProductO() { ProductId = 19, ProductName = "Sir Rodney's Marmalade", CategoryId = 3, CategoryName = CategoryName.Confections, Cost = 81.00m, Quantity = "24 pkgs. x 4 pieces" });
        data.Add(new ProductO() { ProductId = 20, ProductName = "Sir Rodney's Scones", CategoryId = 3, CategoryName = CategoryName.Confections, Cost = 10.00m, Quantity = "30 gift boxes", Available = false });
        data.Add(new ProductO() { ProductId = 21, ProductName = "NuNuCa Nuß-Nougat-Creme", CategoryId = 3, CategoryName = CategoryName.Confections, Cost = 14.00m, Quantity = "10 boxes x 12 pieces" });
        data.Add(new ProductO() { ProductId = 22, ProductName = "Gumbär Gummibärchen", CategoryId = 3, CategoryName = CategoryName.Confections, Cost = 31.23m, Quantity = "32 - 500 g boxes" });
        data.Add(new ProductO() { ProductId = 23, ProductName = "Schoggi Schokolade", CategoryId = 3, CategoryName = CategoryName.Confections, Cost = 43.9m, Quantity = "100 - 100 g pieces" });
        data.Add(new ProductO() { ProductId = 24, ProductName = "Zaanse koeken", CategoryId = 3, CategoryName = CategoryName.Confections, Cost = 9.5m, Quantity = "10 - 4 oz boxes", Available = false });

        
        data.Add(new ProductO() { ProductId = 25, ProductName = "Queso Cabrales", CategoryId = 4, CategoryName = CategoryName.DairyProducts, Cost = 21m, Quantity = "1 kg pkg" });
        data.Add(new ProductO() { ProductId = 26, ProductName = "Mascarpone Fabioli", CategoryId = 4, CategoryName = CategoryName.DairyProducts, Cost = 32m, Quantity = "24 - 200 g pkgs", Available = false });
        data.Add(new ProductO() { ProductId = 27, ProductName = "Geitost", CategoryId = 4, CategoryName = CategoryName.DairyProducts, Cost = 2.5m, Quantity = "500 g" });
        data.Add(new ProductO() { ProductId = 28, ProductName = "Raclette Courdavault", CategoryId = 4, CategoryName = CategoryName.DairyProducts, Cost = 55m, Quantity = "5 kg pkg" });
        data.Add(new ProductO() { ProductId = 29, ProductName = "Camembert Pierrot", CategoryId = 4, CategoryName = CategoryName.DairyProducts, Cost = 34m, Quantity = "15 - 300 g rounds", Available = false });
        data.Add(new ProductO() { ProductId = 30, ProductName = "Gudbrandsdalsost", CategoryId = 4, CategoryName = CategoryName.DairyProducts, Cost = 36m, Quantity = "10 kg pkg" });
        data.Add(new ProductO() { ProductId = 31, ProductName = "Flotemysost", CategoryId = 4, CategoryName = CategoryName.DairyProducts, Cost = 21.5m, Quantity = "10 - 500 g pkgs" });
        data.Add(new ProductO() { ProductId = 32, ProductName = "Mozzarella di Giovanni", CategoryId = 4, CategoryName = CategoryName.DairyProducts, Cost = 34.8m, Quantity = "24 - 200 g pkgs" });
        
        data.Add(new ProductO() { ProductId = 33, ProductName = "Gustaf's Knäckebröd", CategoryId = 5, CategoryName = CategoryName.Grains, Cost = 21m, Quantity = "24 - 500 g pkgs" });
        data.Add(new ProductO() { ProductId = 34, ProductName = "Tunnbröd", CategoryId = 5, CategoryName = CategoryName.Grains, Cost = 9m, Quantity = "12 - 250 g pkgs", Available = false });
        data.Add(new ProductO() { ProductId = 35, ProductName = "Singaporean Hokkien Fried Mee", CategoryId = 5, CategoryName = CategoryName.Grains, Cost = 14m, Quantity = "32 - 1 kg pkgs" });
        data.Add(new ProductO() { ProductId = 36, ProductName = "Filo Mix", CategoryId = 5, CategoryName = CategoryName.Grains, Cost = 7m, Quantity = "16 - 2 kg boxes" });
        data.Add(new ProductO() { ProductId = 37, ProductName = "Gnocchi di nonna Alice", CategoryId = 5, CategoryName = CategoryName.Grains, Cost = 38m, Quantity = "24 - 250 g pkgs" });
        data.Add(new ProductO() { ProductId = 38, ProductName = "Ravioli Angelo", CategoryId = 5, CategoryName = CategoryName.Grains, Cost = 19.5m, Quantity = "24 - 250 g pkgs" });
        data.Add(new ProductO() { ProductId = 39, ProductName = "Wimmers gute Semmelknödel", CategoryId = 5, CategoryName = CategoryName.Grains, Cost = 33.25m, Quantity = "20 bags x 4 pieces" });

        
        data.Add(new ProductO() { ProductId = 40, ProductName = "Mishi Kobe Niku", CategoryId = 6, CategoryName = CategoryName.Meat, Cost = 97m, Quantity = "24 boxes x 2 pies" });
        data.Add(new ProductO() { ProductId = 41, ProductName = "Alice Mutton", CategoryId = 6, CategoryName = CategoryName.Meat, Cost = 39m, Quantity = "16 pies" });
        data.Add(new ProductO() { ProductId = 42, ProductName = "Thüringer Rostbratwurst", CategoryId = 6, CategoryName = CategoryName.Meat, Cost = 123.99m, Quantity = "48 pieces" });
        data.Add(new ProductO() { ProductId = 43, ProductName = "Perth Pasties", CategoryId = 6, CategoryName = CategoryName.Meat, Cost = 32.8m, Quantity = "50 bags x 30 sausgs", Available = false });
        data.Add(new ProductO() { ProductId = 44, ProductName = "Tourtière", CategoryId = 6, CategoryName = CategoryName.Meat, Cost = 7.45m, Quantity = "20 - 1 kg tins" });
        data.Add(new ProductO() { ProductId = 45, ProductName = "Pâté chinois", CategoryId = 6, CategoryName = CategoryName.Meat, Cost = 24.00m, Quantity = "18 - 500 g pkgs" });
        data.Add(new ProductO() { ProductId = 46, ProductName = "Uncle Bob's Organic Dried Pears", CategoryId = 6, CategoryName = CategoryName.Meat, Cost = 30m, Quantity = "12 - 1 lb pkgs" });
        data.Add(new ProductO() { ProductId = 47, ProductName = "Tofu", CategoryId = 6, CategoryName = CategoryName.Meat, Cost = 23.25m, Quantity = "40 - 100 g pkgs", Available = false });
        
        data.Add(new ProductO() { ProductId = 48, ProductName = "Ikura", CategoryId = 7, CategoryName = CategoryName.Seafood, Cost = 31m, Quantity = "12 - 200 ml jars" });
        data.Add(new ProductO() { ProductId = 49, ProductName = "Konbu", CategoryId = 7, CategoryName = CategoryName.Seafood, Cost = 6m, Quantity = "2 kg box" });
        data.Add(new ProductO() { ProductId = 50, ProductName = "Carnarvon Tigers", CategoryId = 7, CategoryName = CategoryName.Seafood, Cost = 62.5m, Quantity = "16 kg pkg", Available = false });
        data.Add(new ProductO() { ProductId = 51, ProductName = "Nord-Ost Matjeshering", CategoryId = 7, CategoryName = CategoryName.Seafood, Cost = 25.89m, Quantity = "10 - 200 g glasses", Available = false });
        data.Add(new ProductO() { ProductId = 52, ProductName = "Inlagd Sill", CategoryId = 7, CategoryName = CategoryName.Seafood, Cost = 19m, Quantity = "24 - 250 g jars" });
        data.Add(new ProductO() { ProductId = 53, ProductName = "Gravad lax", CategoryId = 7, CategoryName = CategoryName.Seafood, Cost = 97m, Quantity = "12 - 500 g pkgs" });
        data.Add(new ProductO() { ProductId = 54, ProductName = "Jack's New England Clam Chowder", CategoryId = 7, CategoryName = CategoryName.Seafood, Cost = 9.65m, Quantity = "12 - 12 oz cans" });
        data.Add(new ProductO() { ProductId = 55, ProductName = "Spegesild", CategoryId = 7, CategoryName = CategoryName.Seafood, Cost = 26m, Quantity = "4 - 450 g glasses" });

        SourceData = data;
    }
}
<div style="width:40%; display: inline-block;">
    <TelerikChart>
        <ChartTitle Text="Gross domestic product growth /GDP annual %/"></ChartTitle>
        <ChartLegend Visible="false"></ChartLegend>

        <ChartSeriesItems>
            <ChartSeries Type="@ChartSeriesType.Column" Data="@Data" Field="@nameof(ModelData.Series1)" Name="Canada"></ChartSeries>
            <ChartSeries Type="@ChartSeriesType.Column" Data="@Data" Field="@nameof(ModelData.Series2)" Name="USA"></ChartSeries>
            <ChartSeries Type="@ChartSeriesType.Column" Data="@Data" Field="@nameof(ModelData.Series3)" Name="Bulgaria"></ChartSeries>
            <ChartSeries Type="@ChartSeriesType.Line" Data="@Data" Field="@nameof(ModelData.Series4)" Name="Average Trend"></ChartSeries>
        </ChartSeriesItems>

        <ChartCategoryAxes>
            <ChartCategoryAxis Categories="@Categories">
                <ChartCategoryAxisLabels>
                    <ChartCategoryAxisLabelsRotation Angle="45" Align="@ChartAxisLabelsRotationAlignment.Center" />
                </ChartCategoryAxisLabels>
            </ChartCategoryAxis>
        </ChartCategoryAxes>

        <ChartValueAxes>
            <ChartValueAxis>
                <ChartValueAxisTitle Text="Growth, %"></ChartValueAxisTitle>
                <ChartValueAxisLabels Format="{0:N0}%"></ChartValueAxisLabels>
            </ChartValueAxis>
        </ChartValueAxes>

        <ChartTooltip Visible="true" Shared="true"></ChartTooltip>
    </TelerikChart>
</div>

<div style="width:50%; display: inline-block; margin-left:10px;">
  <TelerikChart>
    <ChartTitle Text="What is you favourite sport?"></ChartTitle>
    <ChartLegend Visible="true" Position="ChartLegendPosition.Top"></ChartLegend>

    <ChartSeriesItems>
        <ChartSeries Type="@ChartSeriesType.Donut" Data="@DataForDonut"
                     Field="@nameof(DonutData.Value)" CategoryField="@nameof(DonutData.Category)">
            <ChartSeriesTooltip Visible="true">
                <Template>
                    @((context.DataItem as DonutData).Category) - @((context.DataItem as DonutData).Value)%
                </Template>
            </ChartSeriesTooltip>
            <ChartSeriesLabels Position="@ChartSeriesLabelsPosition.OutsideEnd"
                               Visible="true"
                               Background="transparent"
                               Format="{0}%">
            </ChartSeriesLabels>
        </ChartSeries>
    </ChartSeriesItems>
  </TelerikChart>
</div>

@code {
    public class DonutData
    {
        public string Category { get; set; }
        public Int32 Value { get; set; }
    }

    public List<DonutData> DataForDonut = new List<DonutData>()
    {
        new DonutData()
        {
            Category = "Football",
            Value = 35
        },
        new DonutData()
        {
            Category = "Basketball",
            Value = 25
        },
        new DonutData()
        {
            Category = "Volleyball",
            Value = 20
        },
        new DonutData()
        {
            Category = "Rugby",
            Value = 10
        },
        new DonutData()
        {
            Category = "Tennis",
            Value = 10
        },

    };

    public class ModelData
    {
        public double Series1 { get; set; }
        public double Series2 { get; set; }
        public double Series3 { get; set; }
        public double Series4 { get; set; }
    }

    public string[] Categories = new string[] { "2002", "2003", "2004", "2005", "2006", "2007", "2008", "2009", "2010", "2011" };


    public List<ModelData> Data = new List<ModelData>()
    {
        new ModelData()
        {
            Series1 = 3.907,
            Series2 = 4.743,
            Series3 = 0.01,
            Series4 = 1.988
        },
        new ModelData()
        {
            Series1 = 7.943,
            Series2 = 7.295,
            Series3 = 0.375,
            Series4 = 2.733
        },
        new ModelData()
        {
            Series1 = 7.848,
            Series2 = 7.175,
            Series3 = 1.161,
            Series4 = 3.994
        },
        new ModelData()
        {
            Series1 = 9.284,
            Series2 = 6.376,
            Series3 = 0.684,
            Series4 = 3.464
        },
        new ModelData()
        {
            Series1 = 9.263,
            Series2 = 8.153,
            Series3 = 3.7,
            Series4 = 4.001
        },
        new ModelData()
        {
            Series1 = 9.801,
            Series2 = 8.535,
            Series3 = 3.269,
            Series4 = 3.939
        },
        new ModelData()
        {
            Series1 = 3.89,
            Series2 = 5.247,
            Series3 = 1.083,
            Series4 = 1.333
        },
        new ModelData()
        {
            Series1 = 8.238,
            Series2 = 7.832,
            Series3 = 5.127,
            Series4 = 2.245
        },
        new ModelData()
        {
            Series1 = 9.552,
            Series2 = 4.3,
            Series3 = 3.69,
            Series4 = 4.339
        },
        new ModelData()
        {
            Series1 = 6.855,
            Series2 = 4.3,
            Series3 = 2.995,
            Series4 = 2.727
        }
    };

  }
@page "/scheduler"

<TelerikScheduler @bind-Date="@StartDate"
                  @bind-View="@CurrView"
                  Data="@Appointments"
                  OnUpdate="@UpdateAppointment"
                  OnDelete="@DeleteAppointment"
                  OnCreate="@AddAppointment"
                  AllowUpdate="true"
                  AllowCreate="true"
                  AllowDelete="true"
                  Height="500px"
                  Width="100%"
                  IdField="@(nameof(Appointment.Id))"
                  RecurrenceRuleField="@(nameof(Appointment.RecurrenceRule))"
                  RecurrenceExceptionsField="@(nameof(Appointment.RecurrenceExceptions))"
                  RecurrenceIdField="@(nameof(Appointment.RecurrenceId))">
    <SchedulerViews>
        <SchedulerDayView StartTime="@DayStart" />
        <SchedulerWeekView StartTime="@DayStart" />
        <SchedulerMultiDayView StartTime="@DayStart" />
    </SchedulerViews>
</TelerikScheduler>

@code {
    List<Appointment> Appointments = new List<Appointment>();
    public DateTime StartDate { get; set; }
    public SchedulerView CurrView { get; set; } = SchedulerView.Week;

    public DateTime DayStart { get; set; } = new DateTime(2000, 1, 1, 8, 0, 0);

    protected override Task OnInitializedAsync()
    {
        StartDate = GetStart();

        Appointments = GetAppointments();

        return base.OnInitializedAsync();
    }

    private List<Appointment> GetAppointments()
    {
        List<Appointment> data = new List<Appointment>();
        DateTime baselineTime = GetStart();

        data.Add(new Appointment
        {
            Title = "Vet visit",
            Description = "The cat needs vaccinations and her teeth checked.",
            Start = baselineTime.AddHours(2),
            End = baselineTime.AddHours(2).AddMinutes(30)
        });

        data.Add(new Appointment
        {
            Title = "Trip to Hawaii",
            Description = "An unforgettable holiday!",
            IsAllDay = true,
            Start = baselineTime.AddDays(-10),
            End = baselineTime.AddDays(-2)
        });

        data.Add(new Appointment
        {
            Title = "Jane's birthday party",
            Description = "Make sure to get her fresh flowers in addition to the gift.",
            Start = baselineTime.AddDays(5).AddHours(10),
            End = baselineTime.AddDays(5).AddHours(18),
        });

        data.Add(new Appointment
        {
            Title = "One-on-one with the manager",
            Start = baselineTime.AddDays(2).AddHours(3).AddMinutes(30),
            End = baselineTime.AddDays(2).AddHours(3).AddMinutes(45),
        });

        data.Add(new Appointment
        {
            Title = "Brunch with HR",
            Description = "Performance evaluation of the new recruit.",
            Start = baselineTime.AddDays(3).AddHours(3),
            End = baselineTime.AddDays(3).AddHours(3).AddMinutes(45)
        });

        data.Add(new Appointment
        {
            Title = "Interview with new recruit",
            Description = "See if John will be a suitable match for our team.",
            Start = baselineTime.AddDays(3).AddHours(1).AddMinutes(30),
            End = baselineTime.AddDays(3).AddHours(2).AddMinutes(30)
        });

        data.Add(new Appointment
        {
            Title = "Conference",
            Description = "The big important work conference. Don't forget to practice your presentation.",
            Start = baselineTime.AddDays(6),
            End = baselineTime.AddDays(11),
            IsAllDay = true
        });

        data.Add(new Appointment
        {
            Title = "New Project Kickoff",
            Description = "Everyone assemble! We will also have clients on the call from a later time zone.",
            Start = baselineTime.AddDays(3).AddHours(8).AddMinutes(30),
            End = baselineTime.AddDays(3).AddHours(11).AddMinutes(30)
        });

        data.Add(new Appointment
        {
            Title = "Get photos",
            Description = "Get the printed photos from last week's holiday. It's on the way from the vet to work.",
            Start = baselineTime.AddHours(2).AddMinutes(15),
            End = baselineTime.AddHours(2).AddMinutes(30)
        });


        return data;
    }

    public DateTime GetStart()
    {
        DateTime now = DateTime.Now;
        int diff = (7 + (now.DayOfWeek - DayOfWeek.Monday)) % 7;
        DateTime lastMonday = now.AddDays(-1 * diff);
        //return 8 AM on today's date for better visualization of the demos
        return new DateTime(lastMonday.Year, lastMonday.Month, lastMonday.Day, 8, 0, 0);
    }

    void UpdateAppointment(SchedulerUpdateEventArgs args)
    {
        Appointment item = (Appointment)args.Item;
        var matchingItem = Appointments.FirstOrDefault(a => a.Id == item.Id);
        if (matchingItem != null)
        {
            matchingItem.Title = item.Title;
            matchingItem.Description = item.Description;
            matchingItem.Start = item.Start;
            matchingItem.End = item.End;
            matchingItem.IsAllDay = item.IsAllDay;
        }
    }

    void AddAppointment(SchedulerCreateEventArgs args)
    {
        Appointment item = args.Item as Appointment;
        Appointments.Add(item);
    }

    void DeleteAppointment(SchedulerDeleteEventArgs args)
    {
        Appointment item = (Appointment)args.Item;
        Appointments.Remove(item);
    }

    public class Appointment
    {
        public Guid Id { get; set; }
        public DateTime Start { get; set; }
        public DateTime End { get; set; }
        public string Title { get; set; }
        public bool IsAllDay { get; set; }
        public string Description { get; set; }
        public string RecurrenceRule { get; set; }
        public List<DateTime> RecurrenceExceptions { get; set; }
        public Guid? RecurrenceId { get; set; }

        public Appointment()
        {
            Id = Guid.NewGuid();
        }
    }
}
<div class="calendar-wrap">
    <div>
        <div class="header">
        <h3>Switch View</h3>
        </div>
        <TelerikRadioGroup Data="@CalendarViews"
                        @bind-Value="@CalendarViewValue"
                        Layout="@RadioGroupLayout.Vertical"></TelerikRadioGroup>
    </div>
    <TelerikCalendar SelectionMode="@CalendarSelectionMode.Multiple"
                     @bind-Date="@startDate"
                     @bind-View="@CalendarViewValue"
                     Views="2">
    </TelerikCalendar>
</div>

@code {
    private DateTime startDate = DateTime.Now;

    public CalendarView CalendarViewValue { get; set; } = CalendarView.Month;    
    public List<CalendarViewModel> CalendarViews { get; set; } = new List<CalendarViewModel>()
    {
        new CalendarViewModel() { Text = "Month View", Value = CalendarView.Month },
        new CalendarViewModel() { Text = "Year View", Value = CalendarView.Year },
        new CalendarViewModel() { Text = "Decade View", Value = CalendarView.Decade },
        new CalendarViewModel() { Text = "Century View", Value = CalendarView.Century }
    };

    public class CalendarViewModel
    {
        public string Text { get; set; }
        public CalendarView Value { get; set; }

        public CalendarViewModel()
        {
        }
    }
}

<style>
    .calendar-wrap {
        display: flex;
        align-items: center;
        justify-content: center;
        gap: 30px;
        width: 100%;
    }
    .header {
      color: #454545;
    }
        .header h3 {
            font-weight: 700;
            font-size: 18px;
        }
</style>
@using System.ComponentModel.DataAnnotations

<div class="dropdownlist-form">

  <TelerikForm Model="@ValidationModel" OnValidSubmit="@HandleValidSubmit" Class="margin-top">
    <FormValidation>
    <DataAnnotationsValidator />
    <TelerikValidationSummary />
    </FormValidation>
    <FormItems>
        <FormItem>
            <Template>
              <div class="header">
              <h3>Product Details</h3>
              </div>
            </Template>
        </FormItem>
    <FormItem Field="CategoryId">
      <Template>
                <label for="category" class="k-label k-form-label">Category*:</label>
                        
        <TelerikDropDownList Id="category"
                   Data="@CategoryData"
                   @bind-Value="@ValidationModel.CategoryId"
                   OnChange="@OnCategoryChange"
                   PopupHeight=""
                   DefaultText="Select Category" ValueField="CategoryId" TextField="CategoryName">
        </TelerikDropDownList>

                <TelerikValidationMessage For="@(() => ValidationModel.CategoryId)"></TelerikValidationMessage>
            </Template>
    </FormItem>
    <FormItem>
      <Template>
                <label for="product" class="k-label k-form-label">Product*:</label>
                        
        <TelerikDropDownList Id="product"
                   Data="@ProductData"
                   Enabled="@ProductEnabled"
                   @bind-Value=@ValidationModel.ProductId
                   PopupHeight="170px"
                   DefaultText="Select Product"
                   ValueField="ProductId"
                   TextField="ProductName">
        </TelerikDropDownList>

                <TelerikValidationMessage For="@(() => ValidationModel.ProductId)"></TelerikValidationMessage>
            </Template>
    </FormItem>
    </FormItems>
  </TelerikForm>
  

  @if (SuccessMessage != string.Empty)
  {
    <div class="k-notification k-notification-success margin-top">
    @SuccessMessage
    </div>
  }
</div>

@code  {
  string[] categoriesList = { "Beverages", "Condiments", "Dairy Products", "Meat/Poultry" };

  string SuccessMessage = string.Empty;
  
  public IEnumerable<Product> ProductSourceData { get; set; }
  public IEnumerable<Product> ProductData { get; set; }
  public IEnumerable<Category> CategoryData { get; set; }
  
  DropDownValidationModel ValidationModel { get; set; } = new DropDownValidationModel();

  public bool ProductEnabled => ValidationModel.CategoryId != null;

  protected override void OnInitialized()
  {
    ProductSourceData = GetProducts();

    List<Category> categories = new List<Category>();

    for (int i = 0; i < 4; i++)
    {
      categories.Add(new Category()
      {
        CategoryId = i + 1,
        CategoryName = categoriesList[i]
      });
    }

    CategoryData = categories;

    base.OnInitialized();
  }

  void OnCategoryChange(object value)
  {   
    ValidationModel.ProductId = default;

    if (value != null)
    {
      ProductData = ProductSourceData.Where(p => p.CategoryId == ValidationModel.CategoryId).ToList();
    }
  }

  async Task HandleValidSubmit()
  {
    SuccessMessage = "Form Submitted Successfully!";

    await Task.Delay(2000);

    SuccessMessage = string.Empty;
  }

  List<Product> GetProducts()
  { 
        List<Product> data = new List<Product>();
    
    data.Add(new Product() { ProductId = 1, ProductName = "Chai", CategoryId = 1 });
    data.Add(new Product() { ProductId = 2, ProductName = "Chang", CategoryId = 1 });
    data.Add(new Product() { ProductId = 3, ProductName = "Guaraná Fantástica" });
    data.Add(new Product() { ProductId = 4, ProductName = "Sasquatch Ale" });
    data.Add(new Product() { ProductId = 5, ProductName = "Steeleye Stout"});
    data.Add(new Product() { ProductId = 6, ProductName = "Côte de Blaye"});
    data.Add(new Product() { ProductId = 7, ProductName = "Chartreuse verte"});
    data.Add(new Product() { ProductId = 8, ProductName = "Ipoh Coffee"});
        
    data.Add(new Product() { ProductId = 9, ProductName = "Aniseed Syrup", CategoryId = 2});
    data.Add(new Product() { ProductId = 10, ProductName = "Chef Anton's Cajun Seasoning", CategoryId = 2 });
    data.Add(new Product() { ProductId = 11, ProductName = "Chef Anton's Gumbo Mix", CategoryId = 2 });
    data.Add(new Product() { ProductId = 12, ProductName = "Grandma's Boysenberry Spread", CategoryId = 2 });
    data.Add(new Product() { ProductId = 13, ProductName = "Northwoods Cranberry Sauce", CategoryId = 2 });
    data.Add(new Product() { ProductId = 14, ProductName = "Genen Shouyu", CategoryId = 2 });
    data.Add(new Product() { ProductId = 15, ProductName = "Gula Malacca", CategoryId = 2 });
    data.Add(new Product() { ProductId = 16, ProductName = "Vegie-spread", CategoryId = 2 });

    data.Add(new Product() { ProductId = 25, ProductName = "Queso Cabrales", CategoryId = 3 });
    data.Add(new Product() { ProductId = 26, ProductName = "Mascarpone Fabioli", CategoryId = 3 });
    data.Add(new Product() { ProductId = 27, ProductName = "Geitost", CategoryId = 3 });
    data.Add(new Product() { ProductId = 28, ProductName = "Raclette Courdavault", CategoryId = 3 });
    data.Add(new Product() { ProductId = 29, ProductName = "Camembert Pierrot", CategoryId = 3 });
    data.Add(new Product() { ProductId = 30, ProductName = "Gudbrandsdalsost", CategoryId = 3 });
    data.Add(new Product() { ProductId = 31, ProductName = "Flotemysost", CategoryId = 3 });
    data.Add(new Product() { ProductId = 32, ProductName = "Mozzarella di Giovanni", CategoryId = 3 });
        
    data.Add(new Product() { ProductId = 40, ProductName = "Mishi Kobe Niku", CategoryId = 4 });
    data.Add(new Product() { ProductId = 41, ProductName = "Alice Mutton", CategoryId = 4 });
    data.Add(new Product() { ProductId = 42, ProductName = "Thüringer Rostbratwurst", CategoryId = 4 });
    data.Add(new Product() { ProductId = 43, ProductName = "Perth Pasties", CategoryId = 4 });
    data.Add(new Product() { ProductId = 44, ProductName = "Tourtière", CategoryId = 4 });
    data.Add(new Product() { ProductId = 45, ProductName = "Pâté chinois", CategoryId = 4});
    data.Add(new Product() { ProductId = 46, ProductName = "Uncle Bob's Organic Dried Pears", CategoryId = 4 });
    data.Add(new Product() { ProductId = 47, ProductName = "Tofu", CategoryId = 4 });

    return data;
  } 

  public class DropDownValidationModel
  {
    [Required(ErrorMessage = "Choose a category")]
    public int? CategoryId { get; set; }
    
    [Required(ErrorMessage = "Choose a product")]
    public int? ProductId { get; set; }
  }

  public class Product
  {
  public int? ProductId { get; set; }

  public string ProductName { get; set; }
  
  public int? CategoryId { get; set; }
  }

  public class Category
  {
  public int? CategoryId { get; set; }

  public string CategoryName { get; set; }
  }
}

<style>

  .dropdownlist-form {
  padding: 20px;
    width: 100%;
    display: flex;
    justify-content: center;
  }

  .header {
    color: #454545;
    font-weight: 700;
  }
        .header h3 {
            font-weight: 500;
            font-size: 18px;
        }

  .margin-top {
    margin-top: 8px;
  }
</style>

Blazor UI Components Key Features

Find truly native Blazor components for every use case

Cut development time and cost in half with the Telerik high-performing Grid and 90+ truly native, easy-to-customize UI components to cover any app scenario. New set of components is added every 6 weeks!

Save months of UI development time with the feature-rich Telerik Grid

100+ features provide flexible data visualization and manipulation, rich API, professional looks and a way to satisfy any design requirement.

“I'm excited to see partners like Telerik creating custom UI controls for Blazor. The Telerik UI controls make building beautiful web apps with lots of rich functionality sooooo easy!”

Daniel Roth

Program Manager, Microsoft

Build any type of app with just one set of UI controls

Easy to customize Telerik Blazor controls through multitude of methods, properties and events, as well as professionally styled built-in themes & the Telerik Sass Theme Builder enabling you to build your own.

Get support with 97% satisfaction rates

Outstanding support from the developers who build the product to help you work out all challenges promptly.

Get started fast with our interactive learning materials

Get results within hours by experimenting with our extensive Blazor demos, docs & online technical training to help you get started in no time.

Explore our Native UI Blazor Components

flows_end_section
visual

Build, Run, Style and Share Your Snippets

ninja-v1-opt

Working with Designers? We Got You Covered!

It's easy to collaborate with your designers using Telerik UI for Blazor and the Telerik UI kits for Figma. The highly-customizable, identical components on both sides set you off to a running start to craft your own design system.

“For anyone reading this that is not a Progress Telerik customer yet, this (customer support) is why I have been since 2010. Great controls / components but even better service.”

Renier Pretorius

Owner, Consultlink

An artisan-crafted product out of the box for a developer with less time to do with the UI and other details. Just focus on your logic, the rest is handled very well.

Evlv Digital

Dev, Evlv Digital

“Telerik UI for Blazor is a great product. It saves time, high performance and Professional Look.”

Mahmoud Helmy

Senior Data Scientists, Kuwait University

“I've been testing Blazor components from a variety of providers and hands-down, the Telerik ones are the best - great UX, fast, easy to extend/implement.”

Chris Woodard

Technical Consultant, Avisra

“Very happy with the current control set, the progress to release new controls and the extending of current functionality. The controls are fast and easy to implement. Support is one of the best I've had to deal with. Friendly response and they always try to help you with examples, custom made for you examples and if what you want/need is not yet possible they try to find a workaround for you.”

Jurgen Mangé

, SGS Belgium NV

“I saw Telerik UI components in YouTube videos and then I loved it. It is going to be a blast using them!”

M Imamul Hassan Khan

Developer, Xenon Solutions Ltd.

“I'm excited to see partners like Telerik creating custom UI controls for Blazor. The Telerik UI controls make building beautiful web apps with lots of rich functionality sooooo easy!”

Daniel Roth

Program Manager, Microsoft

Latest News, Updates and Resources

Getting started
Support Resources
Community
Services

Upgrade to Telerik DevCraft Complete

Be Ready for Any Project & Technology

Save up to 50% in development time by getting 1,250+ .NET and JavaScript UI components for building web, desktop and mobile apps.

Get the Best Value for Money

Enjoy Telerik UI for Blazor along with embedded reporting and mocking tools while saving up to 90% from the upgrade price.

What's New with Telerik UI for Blazor

Telerik UI for Blazor Carousel

New Component: Carousel

Scroll through an image gallery or any other rich content with the Telerik UI for Blazor Carousel.

Telerik UI for Blazor Barcode Overview

New Component: Barcode

Generate Barcodes for various industry standards and customize their appearance with ease through a variety of exposed properties.

Telerik UI for Blazor Gantt Component

New Gantt Enhancements

The Telerik UI for Blazor Gantt component lets you plan project start and end dates, visualize task progress, dependencies and milestones and many more.

Industry-Leading Support

Expert and Timely Support

Get answers to your questions directly from the developers who build this UI suite, even during your trial period.

Contact support

Need Evaluation Help?

If you are not a developer or don't have time to evaluate our product, send us your project requirements. We will evaluate your required features and let you know how our products fit your needs.

Send us your project requirements
Background-NextSteps

Ready to Try it Out?

Download Free Trial