Please note that this control has been deprecated and replaced with the Grid component, and as such, we recommend migrating to that control. This will not be receiving any new features, bug fixes will be deprioritized. For help or questions on migrating your codebase to the Data Grid, please contact support.
Blazor Grid Editing
The Ignite UI for Blazor Data Table / Data Grid supports cell and row editing with batch updating. Note, this is currently limited to non-templated columns.
Blazor Grid Editing Example
EXAMPLE
MODULES
DATA
RAZOR
JS
CSS
using System;
using System.Net.Http;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Text;
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using IgniteUI.Blazor.Controls; // for registering Ignite UI modulesnamespaceInfragistics.Samples
{
publicclassProgram
{
publicstaticasync Task Main(string[] args)
{
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("app");
builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
// registering Ignite UI modules
builder.Services.AddIgniteUIBlazor(
typeof(IgbDataGridModule),
typeof(IgbGridColumnOptionsModule)
);
await builder.Build().RunAsync();
}
}
}cs
// NOTE this file contains multiple data sources:// Data Source #1
using System;
using System.Collections.Generic;
using System.Linq;
namespaceInfragistics.Samples
{
publicstaticclassDataGenerator
{
readonlystaticstring[] websites = { ".com", ".gov", ".edu", ".org" };
readonlystaticstring[] emails = { "gmail.com", "yahoo.com", "twitter.com" };
readonlystaticstring[] genders = { "male", "female" };
readonlystaticstring[] maleNames = { "Kyle", "Oscar", "Ralph", "Mike", "Bill", "Frank", "Howard", "Jack", "Larry", "Pete", "Steve", "Vince", "Mark", "Alex", "Max", "Brian", "Chris", "Andrew", "Martin", "Mike", "Steve", "Glenn", "Bruce" };
readonlystaticstring[] femaleNames = { "Gina", "Irene", "Katie", "Brenda", "Casey", "Fiona", "Holly", "Kate", "Liz", "Pamela", "Nelly", "Marisa", "Monica", "Anna", "Jessica", "Sofia", "Isabella", "Margo", "Jane", "Audrey", "Sally", "Melanie", "Greta", "Aurora", "Sally" };
readonlystaticstring[] lastNames = { "Adams", "Crowley", "Ellis", "Martinez", "Irvine", "Maxwell", "Clark", "Owens", "Rooney", "Lincoln", "Thomas", "Spacey", "MOrgan", "King", "Newton", "Fitzgerald", "Holmes", "Jefferson", "Landry", "Berry", "Perez", "Spencer", "Starr", "Carter", "Edwards", "Stark", "Johnson", "Fitz", "Chief", "Blanc", "Perry", "Stone", "Williams", "Lane", "Jobs", "Adams", "Power", "Tesla" };
readonlystaticstring[] countries = { "USA", "UK", "France", "Canada", "Poland" };
readonlystaticstring[] citiesUS = { "New York", "Los Angeles", "Miami", "San Francisco", "San Diego", "Las Vegas" };
readonlystaticstring[] citiesUK = { "London", "Liverpool", "Manchester" };
readonlystaticstring[] citiesFR = { "Paris", "Marseille", "Lyon" };
readonlystaticstring[] citiesCA = { "Toronto", "Vancouver", "Montreal" };
readonlystaticstring[] citiesPL = { "Krakow", "Warsaw", "Wroclaw", "Gdansk" };
readonlystaticstring[] citiesJP = { "Tokyo", "Osaka", "Kyoto", "Yokohama" };
readonlystaticstring[] citiesGR = { "Berlin", "Bonn", "Cologne", "Munich", "Hamburg" };
readonlystaticstring[] roadSuffixes = { "Road", "Street", "Way" };
readonlystaticstring[] roadNames = { "Main", "Garden", "Broad", "Oak", "Cedar", "Park", "Pine", "Elm", "Market", "Hill" };
publicstatic Random Rand = new Random();
publicstaticstringGetWebsite()
{
return GetItem(websites);
}
publicstaticstringGetEmail()
{
return GetItem(emails);
}
publicstaticdoubleGetNumber(double min, double max)
{
return Math.Round(min + (Rand.NextDouble() * (max - min)));
}
publicstaticintGetInteger(double min, double max)
{
return (int)GetNumber(min, max);
}
publicstaticstringGetPhone()
{
var phoneCode = GetNumber(100, 900);
var phoneNum1 = GetNumber(100, 900);
var phoneNum2 = GetNumber(1000, 9000);
var phone = phoneCode + "-" + phoneNum1 + "-" + phoneNum2;
return phone;
}
publicstaticstringGetGender()
{
return GetItem(genders);
}
publicstaticstringGetNameFirst(string gender)
{
if (gender == "male")
return GetItem(maleNames);
elsereturn GetItem(femaleNames);
}
publicstaticstringGetNameLast()
{
return GetItem(lastNames);
}
publicstaticstringGetItem(string[] array)
{
var index = (int)Math.Round(GetNumber(0, array.Length - 1));
return array[index];
}
publicstaticstringGetCountry()
{
return GetItem(countries);
}
publicstaticstringGetCity(string country)
{
if (country == "Canada")
{
return GetItem(citiesCA);
}
elseif (country == "France")
{
return GetItem(citiesFR);
}
elseif (country == "Poland")
{
return GetItem(citiesPL);
}
elseif (country == "USA")
{
return GetItem(citiesUS);
}
elseif (country == "Japan")
{
return GetItem(citiesJP);
}
elseif (country == "Germany")
{
return GetItem(citiesGR);
}
else
{ // if (country === "United Kingdom") {return GetItem(citiesUK);
}
}
publicstaticstringGetStreet()
{
var num = Math.Round(GetNumber(100, 300)).ToString();
var road = GetItem(roadNames);
var suffix = GetItem(roadSuffixes);
return num + " " + road + " " + suffix;
}
publicstatic DateTime GetBirthday()
{
var year = DateTime.Now.Year - GetInteger(30, 50);
var month = GetNumber(10, 12);
var day = GetNumber(20, 27);
returnnew DateTime(year, (int)month, (int)day);
}
publicstatic DateTime GetDate()
{
var year = DateTime.Now.Year;
var month = GetNumber(10, 12);
var day = GetNumber(20, 27);
returnnew DateTime(year, (int)month, (int)day);
}
publicstaticstringPad(int num, int size)
{
var s = num + "";
while (s.Length < size)
{
s = "0" + s;
}
return s;
}
publicstaticstringGetPhotoMale(int id)
{
return"https://static.infragistics.com/xplatform/images/people/GUY" + Pad(id, 2) + ".png";
}
publicstaticstringGetPhotoFemale(int id)
{
return"https://static.infragistics.com/xplatform/images/people/GIRL" + Pad(id, 2) + ".png";
}
privatestaticint maleCount = 0;
privatestaticint femaleCount = 0;
publicstaticstringGetPhoto(string gender)
{
if (gender == "male")
{
maleCount++;
if (maleCount > 24) maleCount = 1;
return GetPhotoMale(maleCount);
}
else
{
femaleCount++;
if (femaleCount > 24) femaleCount = 1;
return GetPhotoFemale(femaleCount);
}
}
publicstaticstringGetGenderPhoto(string gender)
{
return"https://static.infragistics.com/xplatform/images/genders/" + gender + ".png";
}
publicstaticstringGetCountryFlag(string country)
{
return"https://static.infragistics.com/xplatform/images/flags/" + country + ".png";
}
publicstaticstringGetIncomeRange(double salary)
{
if (salary < 50000)
{
return"Low";
}
elseif (salary < 100000)
{
return"Average";
}
else
{
return"High";
}
}
}
}
// Data Source #2
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
namespaceInfragistics.Samples
{
publicclassObsEmployeeInfo : INotifyPropertyChanged
{
publicstring ID { get; set; }
publicstring Address { get; set; }
publicdouble Age { get; set; }
publicstring Gender { get; set; }
publicstring FirstName { get; set; }
publicstring LastName { get; set; }
publicstring Name { get; set; }
publicstring Street { get; set; }
publicstring City { get; set; }
publicstring Email { get; set; }
publicstring Phone { get; set; }
publicstring Photo { get; set; }
publicdouble Salary { get; set; }
publicdouble Sales { get; set; }
publicstring Income { get; set; }
publicint Index { get; set; }
public DateTime Birthday { get; set; }
public ObservableCollection<ObsEmployeeProductivity> Productivity { get; set; }
privatestring _Country;
publicstring Country
{
get { return _Country; }
set { if (_Country != value) { OnCountryChanged(value); } }
}
publicstring CountryFlag { get; set; }
protectedvoidOnCountryChanged(string countryName)
{
// syncronizing country name and country flag
_Country = countryName;
CountryFlag = DataGenerator.GetCountryFlag(countryName);
City = DataGenerator.GetCity(countryName);
OnPropertyChanged("Country");
}
publicevent PropertyChangedEventHandler PropertyChanged;
protectedvirtualvoidOnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
publicclassObsEmployeeProductivity
{
publicdouble Value { get; set; }
publicint Week { get; set; }
}
publicstaticclassObsEmployeeData
{
publicstatic ObservableCollection<ObsEmployeeInfo> Create(int? count, bool? useProductivity)
{
if (count == null) count = 100;
var employees = new ObservableCollection<ObsEmployeeInfo>();
for (int i = 0; i < count; i++)
{
var age = Math.Round(DataGenerator.GetNumber(20, 40));
var gender = DataGenerator.GetGender();
var firstName = DataGenerator.GetNameFirst(gender);
var lastName = DataGenerator.GetNameLast();
var street = DataGenerator.GetStreet();
var country = DataGenerator.GetCountry();
var city = DataGenerator.GetCity(country);
var email = firstName.ToLower() + "@" + DataGenerator.GetEmail();
var photoPath = DataGenerator.GetPhoto(gender);
var employee = new ObsEmployeeInfo
{
Index = i,
Address = street + ", " + city,
Age = age,
Birthday = DataGenerator.GetBirthday(),
City = city,
Email = email,
Gender = gender,
ID = DataGenerator.Pad(1001 + i, 4),
FirstName = firstName,
LastName = lastName,
Name = firstName + " " + lastName,
Photo = photoPath,
Phone = DataGenerator.GetPhone(),
Street = DataGenerator.GetStreet(),
Salary = DataGenerator.GetNumber(40, 200) * 1000,
Sales = DataGenerator.GetNumber(200, 980) * 1000,
};
employee.Country = country;
employee.Income = DataGenerator.GetIncomeRange(employee.Salary);
if (useProductivity.HasValue && useProductivity.Value)
{
employee.Productivity = GetProductivity(52);
}
employees.Add(employee);
}
return employees;
}
publicstatic ObservableCollection<ObsEmployeeProductivity> GetProductivity(int weekCount)
{
var productivity = new ObservableCollection<ObsEmployeeProductivity>();
for (var w = 1; w <= weekCount; w++)
{
varvalue = DataGenerator.GetNumber(-50, 50);
var prod = new ObsEmployeeProductivity
{
Value = value,
Week = w
};
productivity.Add(prod);
};
return productivity;
}
}
}
cs
functiononUpdatingTemplateColumn(grid, args) {
let content = args.content;
var row = args.cellInfo.dataRow;
if (content.childElementCount === 0) {
var deleteButton = document.createElement("button");
deleteButton.id = row;
var deleteSpan = document.createElement("span");
deleteSpan.textContent = "DELETE";
deleteButton.appendChild(deleteSpan);
deleteButton.onclick = function () {
var button = deleteButton;
DotNet.invokeMethodAsync('Infragistics.Samples', 'ButtonClickActionAtBlazorLevel', button.id);
}
content.appendChild(deleteButton);
}
}
// this code allows calling above functions from a .razor file
igRegisterScript("onUpdatingTemplateColumn", onUpdatingTemplateColumn, false);js
/*
CSS styles are loaded from the shared CSS file located at:
https://static.infragistics.com/xplatform/css/samples/
*/css
Overview
Editing in the Blazor data grid is configured by using the EditMode option of the Blazor grid. This property takes three different options, listed below:
None: Editing is not enabled.
Cell: Allow cells to enter edit mode and commit the value on exiting edit mode.
CellBatch: Allows cells to enter edit mode but changes will be cached later until they are committed.
Row: Allow rows to enter edit mode and commit the value on exit.
When set to CellBatch, in order to commit the changes you must perform the commitEdits method from the grid. The grid will italicize the cells until they are committed providing control over when to push changes back to the datasource.
In addition, error handling can be performed by hooking the onCellValueChanging event and inspecting new values before they are committed. The grid exposes a setEditError method that can output an error message. This keeps the cell in edit mode until a valid value is entered. Otherwise the grid's rejectEdit method can be performed to revert the invalid value. If no invalid value is found, you can also commit your changes by calling the grid's acceptEdit method.
Commits can be approved or declined at the grid level by hooking onDataCommitting via the acceptCommit or rejectCommit methods passing the commitID event argument as the parameter. This event also exposes a changes collection which stores all the modifications prior to being committed. For example, you can check if a commit was from an add, update, or delete operation via the TransactionType property exposed on the changes collection and perform an acceptCommit or rejectCommit when necessary.
Excel Style Editing
EditOnKeyPress enables you to instantly begin editing when typing similar to how Excel behaves. In addition you may set the EditModeClickAction property to SingleClick to allow users to quickly edit cells while navigating to other cells. By default double-clicking is required to enter edit mode.
Code Snippet
The following demonstrates how to configure editing on the data grid and committing the data.
The following demonstrates how incorporate error by checking if cells are empty when leaving edit mode and accepts commits that are from updated cells only.
<IgbDataGridHeight="100%"Width="100%"
@ref="DataGridRef"CellValueChanging="OnCellValueChanging"DataCommitting="OnDataCommitting"></IgbDataGrid>@code {public IgbDataGrid DataGridRef;
publicvoidOnCellValueChanging(IgbGridCellValueChangingEventArgs e)
{
//check if value is empty upon exiting edit mode.if (e.NewValue == "")
{
this.DataGridRef.SetEditError(e.EditID, "Error, cell is empty");
//or revert changesthis.DataGridRef.RejectEdit(e.EditID);
}
else
{
this.DataGridRef.AcceptEdit(e.EditID);
}
}
publicvoidOnDataCommitting(IgbGridDataCommittingEventArgs e)
{
if (e.Changes[0].TransactionType == TransactionType.Update)
{
//commit was passedthis.DataGridRef.AcceptCommit(e.CommitID);
}
else
{
//commit was preventedthis.DataGridRef.RejectCommit(e.CommitID);
}
}
}razor