Customer Information Screen Using C1 Blazor Input Controls
Blazor is a framework that enables developers to create Single Page Web applications with C# and HTML. Blazor has two types of projects - Blazor Server App and Blazor Web Assembly. Blazor applications can interop with JavaScript, which can be triggered with the .NET Code.
ComponentOne started development for Blazor platform after Microsoft announced the Blazor preview. The Blazor Edition includes FlexGrid, FlexChart, FlexPie, ListView, TreeMap, Calendar, ComboBox, AutoComplete, NumericBox, TimeEditor, DatePicker and DateTimePicker controls. More controls will be added based on user feedback.
In this blog, we are going to create a Customer Information screen using the GcDemo DataServices' Northwind Database and Blazor Input Controls for a Store, which retrieves the Customer information for Orders. We will also apply Filtering based on OrderID, Date Range using Blazor Input controls.
To create the above screen, we will use the following C1 Blazor Input Controls:
- C1AutoComplete
- C1NumericBox
- C1TextBox
- C1DateTimeEditor
- C1ListView
The C1AutoComplete will be used to display Customer List, and C1NumericBox will be used to get the number of records. The Order information will be displayed using C1ListView. C1TextBox and C1DateTimeEditor will be used to filter items.
Download C1 Blazor Controls | Blazor Demo
Let's create the above screen with the following steps:
Install NuGet Packages:
To use the C1Blazor controls, we need to install the following C1 Blazor controls from the NuGet in the Blazor project.
Reference Required Script and Style Files:
After installing the NuGet packages, we’re required to add the script and styles files for C1 Controls so that they might render correctly and work fine.
For this, we need to add the following scripts in the wwwroot\index.html file:
<!-- **** C1 Styles files **** -->
<link rel="stylesheet" href="/_content/C1.Blazor.Core/styles.css" />
<link rel="stylesheet" href="/_content/C1.Blazor.Input/styles.css" />
<link rel="stylesheet" href="/_content/C1.Blazor.Calendar/styles.css" />
<link rel="stylesheet" href="/_content/C1.Blazor.DateTimeEditors/styles.css" />
<!-- **** C1 Scripts files **** -->
<script src="/_content/C1.Blazor.Core/scripts.js"></script>
<script src="/_content/C1.Blazor.Input/scripts.js"></script>
<script src="/_content/C1.Blazor.Calendar/scripts.js"></script>
Adding Controls in the Code:
After installing the NuGet packages and adding the scripts & styles file, we may add the required controls in the Blazor page.
For this, we need to import the required namespace in the page as follows:
@using C1.Blazor.Input
@using C1.Blazor.ListView
@using C1.Blazor.DateTimeEditors
@using CustomerInformation.Models
@using Newtonsoft.Json
The above screen can be split into three parts:
- Order Search
- Filter Order
- Display Orders
Order Search:
For searching Order from the DataBase, we required the CustomerId which can be retrieved from the API and will be displayed using the AutoComplete.
Here is the code to fetch the Customers from the API:
@code{
string _baseUrl = "https://gc-demo-dataservice.azurewebsites.net/northwind/api/v1/Customers";
...
List<Customer> Customers = new List<Customer>();
...
protected override async Task OnInitializedAsync()
{
this.Customers = await GetCustomersAsync();
}
public async Task<List<Customer>> GetCustomersAsync()
{
HttpClient http = new HttpClient();
var data = await http.GetStringAsync($"{_baseUrl}");
return JsonConvert.DeserializeObject<List<Customer>>(data);
}
...
}
Once the Customers data is fetched, the data can be displayed in the C1AutoComplete using the following code:
@if (Customers.Count > 0)
{
<div class="form-group">
<label>Customer:</label>
<C1AutoComplete @ref="Customer" ItemsSource="Customers" T="Customer" DisplayMemberPath=" CustomerId" Class="form-control" Style="@("width:69%;")" ShowButton="false" @bind-SelectedIndex="CustomerIndex"
></C1AutoComplete>
</div>
}
@code{
...
C1AutoComplete<Customer> Customer;
...
}
When the Customer is selected, we may fetch the records from the API using the following code snippet:
@code{
...
public async Task<List<Order>> GetCustomersOrderAsync()
{
HttpClient http = new HttpClient();
var data = await http.GetStringAsync($"{_baseUrl}/{Customer.SelectedItem.CustomerId}/Orders"); return JsonConvert.DeserializeObject<List<Order>>(data);
}
...
}
Once the Orders are fetched, we may fetch the number of records using the C1NumericBoxes using the following code:
@if (Customers.Count > 0)
{
<div class="col-sm-12" style="padding-top: 15px;">
<h3>Customer Information Screen</h3>
<div style="padding-top: 15px;width:100%;">
<span class="head-text">Find Customer's Orders: </span>
<div class="form-inline">
<div class="form-group">
<label>Customer:</label><C1AutoComplete @ref="Customer" ItemsSource="Customers" T=" Customer" DisplayMemberPath="CustomerId" Class="form-control" Style="@("width:69%;")" ShowButton="false" @bind- SelectedIndex="CustomerIndex"></C1AutoComplete> </div>
<div class="form-group">
<label>Record Count:</label><C1NumericBox @bind-Value="RecordCount" Class="form- control" Style="@("width:69%;height:38px;border-radius:4px;")"></C1NumericBox>
</div>
<div style="width:28%;padding-left:5px;">
<button class="btn btn-primary" @onclick="GetOrders">Search</button>
</div>
</div>
</div>
</div>
}
@code{
int CustomerIndex = 0; int PageFrom = 0;
int RecordCount = 5; C1AutoComplete<Customer> Customer;
List<Customer> Customers = new List<Customer>(); List<Order> Orders = new List<Order>();
...
public async Task GetOrders()
{
var _orders = await GetCustomersOrderAsync();
Orders = _orders.Skip(this.PageFrom).Take(this.RecordCount).ToList<Order>();
}
...
}
Filter Orders:
Once the records are fetched, we can apply filtering. Here, we would use the C1TextBox to filter the records according to OrderID with the Contains operator. Also, the DateTimeEditor would be used to filter the records between a range of dates using the following code snippet:
@if (Orders.Count > 0)
{
<span class="head-text">Filter Orders:</span>
<div class="form-inline">
<div class="form-group">
<label>Order From: </label>
<C1DateTimePicker @ref="fromDateCtrl" Placeholder="From... " Class="form-control datepicker" @bind-Value="FromDate" MinDate="new DateTime(1997,1,1)" MaxDate="new DateTime(2000,12,31)" Style="@ ("width:69%;")"></C1DateTimePicker>
</div>
<div class="form-group">
<label style="justify-content:flex-end!important;">To:</label>
<C1DateTimePicker @ref="toDateCtrl" Placeholder="To... " Class="form-control datepicker" @bind-Value="ToDate" MinDate="new DateTime(1997,1,1)" MaxDate="new DateTime(2000,12,31)" Style="@ ("width:69%;")"></C1DateTimePicker>
</div>
<div style="width:28%;padding-left:5px;">
<button class="btn btn-primary" style="width:76.7px;" @onclick="FilterItems">Filter</button>
</div>
<div class="form-group">
<label>OrderID:</label>
<C1TextBox @ref="orderID" Placeholder="OrderID..." Class="form-control" Style="@("width:
69%;")"></C1TextBox>
</div>
</div> ...
}
@code{
...
public void FilterItems()
{
var _orders = Orders.Where(x => { return x.OrderID.ToString().Contains(orderID.Text) && x.OrderDate > FromDate && x.OrderDate<ToDate; }).ToList();
Orders = _orders;
}
...
}
Display Orders:
The Orders will be displayed using the C1ListView. After displaying the selected Orders, we would show the details of selected records with the help of the SelectionChanged event.
@if (Orders.Count > 0)
{
...
<div class="row" style="padding-top:15px;">
<div class="col-sm-5">
<span class="head-text">Customer Orders:</span>
<C1ListView @ref="ListOrder" ItemsSource="Orders" T="Order" DisplayMemberPath="
OrderID" Style="@("max-height:50vh;border-radius:5px;border:1px solid #ced4da;")" SelectionMode=" ListViewSelectionMode.Single" SelectionChanged="GetOrder">
<ItemTemplate>
<span>@context.CustomerId - @context.OrderID</span>
</ItemTemplate>
</C1ListView>
</div>
<div class="col-sm-7"> @if (Order != null)
{
<div class="col-sm-12">
<span class="head-text">Selected Order:</span>
<div style="width:100%;border: 1px solid #ced4da;background-color: rgba (224,224,224,0.2);padding:6px;border-radius:5px;" >
<table width="100%">
<tr class="row"><td class="col-sm-6">Order ID </td><td class="col-
sm-6"> @Order.OrderID</td></tr>
sm-6"> @Order.CustomerId</td></tr>
<tr class="row"><td class="col-sm-6">Customer ID</td><td class="col-
<tr class="row"><td class="col-sm-6">Order Date</td><td class="col-
sm-6"> @Order.OrderDate.ToShortDateString()</td></tr>
<tr class="row"><td class="col-sm-6">Shipped Date</td><td class=" col-sm-6"> @Order.ShippedDate.ToShortDateString()</td></tr>
<tr class="row"><td class="col-sm-6">Freight</td><td class="col-sm-
6"> @Order.Freight</td></tr>
}
</div>
</div>
}
</table>
</div>
</div>
@code{
C1ListView<Order> ListOrder;
...
public void GetOrder()
{
if (ListOrder != null)
{
Order = Orders[ListOrder.Selection.Row];
}
}
}
Now, we are ready to execute the sample.