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.

Datagrid

Try ComponentOne Studio

Download the latest version of ComponentOne Studio Enterprise

Download Now!

Creating a FlexGrid

  1. To create an editing form for the FlexGrid, first, we will need to create FlexGrid and bind it to a data source. This link will provide a quick start on how to create a Blazor project and how to a FlexGrid. We will use the Customer class as a model for FlexGrid:
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.

  1. Now, we will bind the data to the FlexGrid. We will add the columns manually and will also add an action column:
<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>&nbsp;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.

  1. Now, we will initialize the grid with data. For this article, we have used random data:
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.

Creating an Editing Form using C1Window

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.

  1. Add a C1Window control and its reference:
<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.

  1. Add the C1 Input controls inside the PopupContent component:
<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.

  1. Add the bound variables and a data source of the C1AutoComplete:
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.

Implementing Editing and Saving Actions

  1. Implementing the EditItem method. This method will be called on the action button click. We can pass the current row's data time to this method. Then it will initialize all the bound variables and open the C1Window control:
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.

  1. Add a method to close the popup with or without saving the updates. This method will take a boolean parameter which will indicate whether to save the updated data. This method will update the values of each of the property of the EditingItem:
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;
}

Build and Run the Application

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

Try ComponentOne Studio

Download the latest version of ComponentOne Studio Enterprise

Download Now!