Hey guys, I am Venkat and this is part 20 of web development with Blazor video series. In
our previous video we discussed how to perform CRUD operations using Blazor Data Grid. It's
a powerful and easy to use component. Out of the box, it provides several customizations,
so we can very easily and quickly implement most of the real world application use cases.
At the moment, when we try to edit one of these rows, notice the edit row is put in line in the
data grid itself, we provide values for each of these fields and then click the update button
to update the data in the underlying database table. Similarly, when we try to add a new row,
again this new row is placed in line in the data grid itself, same idea, provide the values for
these fields and then click the update button. So, basically everything is done in line in the data
grid itself, but what if I want to perform both the add and update operations in a separate dialog
instead of inline in the grid? Well, out of the box, data grid supports three edit modes - Normal,
Dialog and Batch. What we saw just now in action is the default normal edit mode,
now, to explicitly set edit mode on this ,
we set Mode property and the value for this is EditMode enum, and as you can see from
intellisense, it has three values - Batch, Dialog, Normal. The default, if we don't explicitly set
edit mode is Normal, and we have seen that in action just now. Let's try Dialog.
Now, when we try to edit a row, notice the edit row is in a separate dialog
instead of in line in the data grid. Let's provide new values,
and then click save, data updated in the grid. Let's confirm if the update really made its way
to the underlying database table by executing this select query, and take a look at this first row,
data updated as expected. Now, this edit mode dialog is highly customizable. At the top we
have the dialog header, notice the text that we have at the moment - Details of 2, this value 2
is the primary key value, in our case employee id value. Now, to make it a bit more meaningful,
I want to change this header text to - Details of whatever is the first name of the employee,
in this case the first name is Sam, so we want to display the text - Details of Sam. Similarly,
in the footer we have these two buttons - Save and Cancel. Whether I'm editing an existing
employee record or adding a new record, in both the cases the text on the button
is "Save". We want to change it to "Add" when we are adding a new employee row, and to "Update"
when we are updating an existing employee row. So, let's see how to customize both the dialog
header and footer. To customize the dialog header, inside this component, we use
, inside this let's include a element, and in here
we want to display the header text, for that we're going to call a separate method called
GetHeaderText(), we don't have this method yet, we'll create it in just a bit, and to this method
we want to pass the employee object that we are trying to edit, and remember, inside the data grid
we have access to an implicit parameter called context and we can type typecast this parameter
to Employee type, because our data grid is binding to a list of Employee objects. Our obvious next
step is to create this method. So, let's do that in the code block at the bottom right here.
Return type of our new method is string, because it's going to return the header text.
The name of our method is GetHeaderText, and to this we pass the Employee object
that we are editing, let's call the parameter also employee. If employee.EmployeeId = 0,
this means we are creating a new employee, so we want to return "Add New Employee"
else we are editing an existing employee so we want to return
Edit whatever is the employee first name and to get employee first name,
employee.FirstName details, oh we forgot to wrap this string in double quotes.
Now, when we edit an employee record, notice the header text, edit employee first name details,
and when we are adding a new employee row, notice it is Add New Employee. Now, let's customize the
text that we have on the Save button in the dialog footer. When we are adding a new employee we want
the text to be "Add", when editing and updating - Update. To customize edit dialog footer, just like
, we also have . In here we need two buttons - Save and Cancel,
for that first let's bring in the buttons namespace Syncfusion.Blazor.Buttons,
and in the let's include Save and Cancel buttons,
we don't have these two event handlers, so let's create them in the code block.
When "Cancel" button is clicked we want to cancel editing and close the dialog, so for that we call
CloseEdit() method on the employee grid, and when we click the "Save" button, we want to save added
or edited record and then close the dialog, so for that we call EndEdit() on employee grid. Now,
if you're wondering what is this employeeGrid property? Well, if you remember it's a property
that we created in our previous video right here, and this is the property that we have
set as the value for @ref attribute on our data grid itself right here, so this property holds a
reference to our grid, so we can call methods like EndEdit(), CloseEdit(), Refresh() etc on the grid,
and then if you take a look at this button right here, we are at the moment hard coding the text
to "Save". Now, we want to dynamically change this to Add and Update depending on when we are adding
or updating an employee record, so instead of hard coding the text here, let's bind it to a variable,
and let's call this variable SaveButtonText, we don't have this variable yet, we'll create it
in just a bit. Now, it is this method that dynamically sets our dialog header text, so we
can make use of the same method to dynamically set the button text as well, so let's scroll down to
GetHeaderText() method, when adding a new employee button text must be "Add" and when updating an
employee it must be Update. Finally, let's not forget to declare this SaveButtonText property,
that's the reason we have these compilation errors, so let's create our property right here.
The property type is string, and the name of the property is SaveButtonText
Now, when we try to add a new employee, the button text is "Add", and when we try to edit
it's "Update". Finally, let's try "Batch" mode. This is even more interesting,
in batch mode as the name implies changes are made in batch. For example, to this data grid I can add
5 rows, edit 3 rows, delete 2 rows and then when I click "Update", that's when all these changes
are made in batch, not individually. Notice, when I double click on a row to edit, the entire row
is not in edit mode, only the specific cell where I clicked is in edit mode, I can change the value
and then press the tab key, notice the green background color indicates that a change is made
but is not saved yet, similarly I can change the last name, press the tab key, date of birth same
idea. We have a small issue with department column, we'll come to that in just a bit. Now,
when I double click on "Gender" column, again I can change gender value and then when I press the
tab key, again we have a green background color indicating the value has changed but not saved
yet. With department, notice, again when I double click, the cell is in edit mode, at the moment the
selected value is IT, let's change it to Admin, and then when I click on any other cell, you know
the row gets out of edit mode, but notice it still has the old department which is IT, but again if
I put the cell in edit mode by clicking it, now we can see in edit mode it has the value that we have
changed, but when we get out of edit mode, we see the old value, so let's fix this bug first.
At the moment, department grid column is being bound to Department.DepartmentName property,
let's actually bind it to Employee.DepartmentId property, so for that we'll use a syntax similar
to what we have right here, using @nameof keyword and then we want to bind to DepartmentId property.
Now, in the department column we see department ids but for an end user department names make
more sense, so in the just like this let's include
Now, we want a method to which we pass department id value
and it returns us the department name, and then we'll call that method here inside the template,
so it displays the department name, so let's first write that method in the code block right here.
Return type is "string" because it returns us the department name.
Let's name the method GetDepartmentById, and we need to pass it department id. Now,
this "Departments" property already contains the list of all departments,
so we're going to use it to retrieve the department by id, so Departments.FirstOrDefault
d.DepartmentId = whatever is the incoming id, and what do we want from it, we want the department
name, so we simply want to return this from this method, but we also want to make a check
if this incoming id value is 0, that means the employee does not have a department yet,
and in that case we simply want to return null, so let's do an if check, if id equals 0 return null,
else we want to return the department name. All that is left is to call this
method inside the template, let's include a element and then we want to call our
method GetDepartmentNameById(), and to this method we have to pass the department id,
and remember inside the grid we have access to an implicit parameter called context,
let's typecast it to Employee and then we can get the employee department id
Now, let's put this department cell in edit mode, change it from IT to Admin and then when
I press the tab key, we see the changed value and we also have the green background color
indicating that the cell value is changed. Let's also change gender, first name and last name
and let's also perform a delete, so let's delete this employee row with id 9, so we select the row,
click the delete button. So, at the moment in the grid we have an update and delete, before I click
the update button, let's go to visual studio and in the output window make sure you have
your web server selected and let's delete all the sql commands that are already logged,
and then let's click update. We have a dialog, click ok, looks like the changes are saved,
but then if we take a look at the output window in visual studio, notice none of
the update or delete sql statements are logged here, this means the changes are not saved in
the underlying database table, this also means, notice what happens when we reload the web page,
all our changes are reverted, notice this employee row with id 1, we have the changes undone, and if
you remember we deleted this employee row with id 9, again this is back. So, now what we want to do
is save these changes in the underlying database table as well. Now, here's the important point to
keep in mind, when we click update button in the data grid to batch save data, OnBatchSave event is
raised, so this is the event we want to handle to save changes in the underlying database table. So,
in the component you want to handle OnBatchSave, let's name the even
handler BatchSaveHandler, we don't have this method yet, so let's create it right here.
This method receives a parameter of type BeforeBatchSaveArgs, at this point you might be
wondering how do I know I have to pass an object of this type? Well, intellisense is your friend,
so if we scroll all the way up to the event and when I hover the mouse over this OnBatchSave,
you can see from intellisense the even handler method takes a parameter of type
BeforeBatchSaveArgs, in our case the type of value our grid is binding to is Employee
object, that's why they're using a parameter of type BeforeBatchSaveArgs object,
create a variable, name it updates and then on the incoming args parameter we have BatchChanges
and on that we have ChangedRecords, this property returns the list of all updates,
similarly DeletedRecords returns all deleted records and AddedRecords returns all the
added records, so let's hold on to changed records in this updates variable, similarly
we have inserts and deletes and then let's use a for each loop, employee, let's also call the
loop variable employee in updates, we already have our client-side employee service injected,
so on the EmployeeService we have UpdateEmployee() method and to this let's pass the employee object,
similarly process inserts and deletes, and let's not forget to use await keyword
because UpdateEmployee() is an async method. Let's save our changes and take a look at the browser.
Let's edit this first, row change first name and last name, let's delete this employee row with id
9, and let's also add a new employee row, first name batch 1, last name batch 2, include a random
date of birth, department admin, gender female and let's set the email to batch1@batch1.com,
and then before we click update, let's clear everything that we have in the output window
and then click update, click ok, and if we take a look at visual studio, notice we have
our updates, and inserts and deletes here before we wrap up, on this
I'm going to set AllowNextRowEdit to true, this is false by default,
when I double click on this first name cell, it's in edit mode, when I press the tab key, it moves
on to the next cell, as I keep pressing the tab key it moves to the last cell in the first row, at
this point when I press the tab key again, notice it advances to the first cell in the second row,
but this id column is not editable, so the grid is smart enough not to put the cell in edit mode,
when I press the tab key again, it moves on to the second cell in the second row, to go back,
I press shift tab, notice from second cell we moved on to the first cell in the second row,
at this point, when I press shift tab again, we go to the last cell in a previous column, in our
case last cell in the first row, so by setting this property AllowNextRowEdit to true, basically
we are able to advance editing from one row to the next by pressing the tab key, if we want
to move in the opposite direction use shift tab. That's it in this video. Thank you for listening.