ComponentOne's FlexGrid provides an inline editing style just like excel. This makes it easier to edit the data displayed in the grid and other operations that can perform like validation. But, in some cases, normal editing is not possible, or it is difficult. For example, for touch devices or devices with small dimensions, directly editing the grid will cause inconvenience as the keyboard takes up almost half the screen. Also, users can mistakenly start editing the cells even if they only wish to scroll the grid.
For these scenarios, we can create an editing form for FlexGrid. The form will use the C1 input controls to provide a rich editing experience to the users and will be a lot easier to handle on touch and non-touch devices. We can create an action button for each row in the FlexGrid. Clicking on it will open the form by which the users can edit the data in the row using the input controls.
public class Customer
{
public string ID { get; set; }
public string Name { get; set; }
public string Country { get; set; }
public DateTime? LastOrderDate { get; set; }
public int TotalOrders { get; set; }
}
The various properties of this class can be edited by different controls.
<FlexGrid @ref="theGrid" SelectionMode="GridSelectionMode.Row" DefaultColumnWidth="GridLength.Star" HeadersVisibility="GridHeadersVisibility.All" ItemsSource="customers" IsReadOnly="true" AutoGenerateColumns="false">
<FlexGridColumns>
<GridColumn Binding="ID" />
<GridColumn Binding="Name" />
<GridColumn Binding="Country" />
<GridDateTimeColumn Binding="LastOrderDate" Format="MMM dd, yyyy" />
<GridNumericColumn Binding="TotalOrders" Format="n0" />
<GridColumn Header="Action" HorizontalAlignment="C1.Blazor.Core.C1HorizontalAlignment.Center">
<CellTemplate>
@{
var item = (Customer)context;
}
<button @onclick="@EditItem(item)" class="btn btn-primary"><span class="oi-pencil oi"></span> Edit</button>
</CellTemplate>
</GridColumn>
</FlexGridColumns>
</FlexGrid>
Notice how we have used the CellTemplate component to add custom HTML inside the cell of FlexGrid. The context variable contains the current item of the row being rendered. We will add the EditItem method later on.
private List<Customer> customers;
protected override void OnInitialized()
{
this.customers = SampleData.GetCustomers(10);
}
We have used the OnInitialized callback of Blazor to set the data source.
C1Window is a new control added to ComponentOne Blazor in this release. This can be used to display a modal on the webpage. This control will display the editing form in a modal popup. To add C1Window control you can follow this link.
<C1Window @ref="resultPopup" Style="@("width: 50%")" IsModeless="false">
<PopupHeader>
Edit Item
</PopupHeader>
<PopupContent>
<!-- C1 Input controls -->
</PopupContent>
</C1Window>
@code {
public C1Window resultPopup;
}
We can use the resultPopup variable to show/hide the popup.
<div class="form-group">
<label>Name:</label>
<C1TextBox @bind-Text="@nameCtl" Class="form-control" />
</div>
<div class="form-group">
<label>Country:</label>
<C1AutoComplete ItemsSource="@Countries" @bind-SelectedItem="@countryCtl" Class="form-control" />
</div>
<div class="form-group">
<label>Last Order Date:</label>
<C1DatePicker DropDownBehavior="DropDownBehavior.HeaderTap" DropDownStyle="@("left: 50%")" Style="@("width: 100%")" Format="MMM dd, yyyy" @bind-Value="@lastOrderCtl" />
</div>
<div class="form-group">
<label>Total Orders:</label>
<C1NumericBox Style="@("width: 100%")" @bind-Value="@ordersCtl" />
</div>
<button class="btn btn-primary" @onclick="ClosePopup(true)">Save</button>
<button class="btn btn-default" @onclick="ClosePopup(false)">Cancel</button>
We have added a C1TextBox for editing the name, C1AutoComplete to select the appropriate country, C1DatePicker to set the date of the last order, and C1NumericBox for entering the total orders taken.
private List<string> Countries;
private Customer EditingItem;
private int ordersCtl;
private DateTime? lastOrderCtl;
private string nameCtl;
private string countryCtl;
protected override void OnInitialized()
{
this.customers = SampleData.GetCustomers(10);
this.Countries = SampleData.Countries;
}
Each of the above variables are bound to each respective control. Whenever the value of the control will be changed, the variables will also be updated to the same value and vice-versa. We will also create an EditingItem variable to store the current item being edited.
private Action<MouseEventArgs> EditItem(Customer item)
{
Action<MouseEventArgs> listener = (e) =>
{
this.EditingItem = item;
this.ordersCtl = this.EditingItem.TotalOrders;
this.lastOrderCtl = this.EditingItem.LastOrderDate;
this.nameCtl = this.EditingItem.Name;
this.countryCtl = this.EditingItem.Country;
this.resultPopup.Open();
};
return listener;
}
This method returns an event listener for the onclick event of the action button.
private Action<MouseEventArgs> CommitItem(bool save)
{
Action<MouseEventArgs> listener = (e) =>
{
if (save)
{
this.EditingItem.TotalOrders = this.ordersCtl;
this.EditingItem.Name = this.nameCtl;
this.EditingItem.LastOrderDate = this.lastOrderCtl;
this.EditingItem.Country = this.countryCtl;
}
this.resultPopup.Close();
this.EditingItem = null;
};
return listener;
}
Press the F5 key to build and run the project. Once the webpage is displayed, you can use the Edit button on the action column.
You can download the sample from here.
Blazor Explorer Demo | Blazor Documentation