Datagrid cell events
I need to understand how to triggere an event after cell edit to calculate the sum of three cells in the same row and put the result in a fourth cell of the same row.
I tried to use CellSaved Event and OnCellEdit event but I can't succeed to get it fired.
Can you address me to a workig example on thi task?
Thanks
Michele
<SfGrid name="gridAss" Height="100%" Width="100%" @ref="@TSGrid" DataSource="@listTS" Locale="it" RowHeight="30" AllowPaging="false" AllowResizing="true" AllowSorting="true" ContextMenuItems="@(new List<object>() { "AutoFit", "AutoFitAll", "SortAscending", "SortDescending"})"
AllowSelection="true" AllowFiltering="true" EnablePersistence="true" style="padding: 5px">
<GridEditSettings AllowEditing="true" AllowAdding="false" AllowDeleting="false"></GridEditSettings>
<GridSelectionSettings PersistSelection="true" Type="Syncfusion.Blazor.Grids.SelectionType.Single"></GridSelectionSettings>
<GridEvents CellSaved="CellSaveHandler" CellDeselected="CellDeselectedHandler" TValue="objTms"></GridEvents>
<GridFilterSettings Type="Syncfusion.Blazor.Grids.FilterType.Menu"></GridFilterSettings>
<GridColumns>
<GridColumn Field=@nameof(objTms.ID) Visible="false" HeaderText="ID" IsPrimaryKey="true" Width="40"></GridColumn>
<GridColumn Field=@nameof(objTms.COD_AMM) Visible="false" HeaderText="CA" Width="40"></GridColumn>
<GridColumn Field=@nameof(objTms.dateTS) Visible="false" AllowEditing="false" HeaderText="Giorno" Type="ColumnType.DateOnly" Format="dd" AutoFit></GridColumn>
<GridColumn Field=@nameof(objTms.dayTS) AllowEditing="false" HeaderText="Giorno" Type="ColumnType.String" AutoFit></GridColumn>
<GridColumn Field=@nameof(objTms.totOre) HeaderText="Tot. ore" Type="ColumnType.TimeOnly" MinWidth="100px" AutoFit="true"></GridColumn>
<GridForeignColumn Field=@nameof(objTms.activityType1) HeaderText="Attività 1" ForeignKeyValue="descr" ForeignKeyField="EID" ForeignDataSource="activityList" Type="ColumnType.String" MinWidth="200px" AutoFit="true"></GridForeignColumn>
<GridColumn Field=@nameof(objTms.nOre1) HeaderText="N° ore" Type="ColumnType.TimeOnly" MinWidth="110px" AutoFit="true"></GridColumn>
<GridForeignColumn Field=@nameof(objTms.activityType2) HeaderText="Attività 2" ForeignKeyValue="descr" ForeignKeyField="EID" ForeignDataSource="activityList" Type="ColumnType.String" MinWidth="200px" AutoFit="true"></GridForeignColumn>
<GridColumn Field=@nameof(objTms.nOre2) HeaderText="N° ore" Type="ColumnType.TimeOnly" MinWidth="100px" AutoFit="true"></GridColumn>
<GridForeignColumn Field=@nameof(objTms.activityType3) HeaderText="Attività 3" ForeignKeyValue="descr" ForeignKeyField="EID" ForeignDataSource="activityList" Type="ColumnType.String" MinWidth="200px" AutoFit="true"></GridForeignColumn>
<GridColumn Field=@nameof(objTms.nOre3) HeaderText="N° ore" Type="ColumnType.TimeOnly" MinWidth="100px" AutoFit="true"></GridColumn>
<GridColumn Field=@nameof(objTms.notes) HeaderText="N° ore" Type="ColumnType.String" MinWidth="150px" AutoFit="true"></GridColumn>
</SfGrid>
@code{
public void CellSaveHandler(CellSaveArgs<objTms> args)
{
if (args.ColumnName == "nOre1" | args.ColumnName == "nOre2" | args.ColumnName == "nOre3")
{
TimeSpan totalHours = (args.RowData.nOre1?.ToTimeSpan() ?? TimeSpan.Zero) +
(args.RowData.nOre2?.ToTimeSpan() ?? TimeSpan.Zero) +
(args.RowData.nOre3?.ToTimeSpan() ?? TimeSpan.Zero);
args.RowData.totOre = TimeOnly.FromTimeSpan(totalHours);
}
// Here, you can customize your code.
}
public void CellDeselectedHandler(CellDeselectEventArgs<objTms> args)
{
TimeSpan totalHours = (args.Data.nOre1?.ToTimeSpan() ?? TimeSpan.Zero) +
(args.Data.nOre2?.ToTimeSpan() ?? TimeSpan.Zero) +
(args.Data.nOre3?.ToTimeSpan() ?? TimeSpan.Zero);
args.Data.totOre = TimeOnly.FromTimeSpan(totalHours);
}
}
This is an extract of what I tried to do
Hi Michele,
While validating your query, we have seen that you are using the CellSaved events without specifying the selection mode as Cell. By default, the selection mode is set to 'Row' in the data grid. So unless you change the selection mode to 'Cell', the cell saving events won't get triggered. To achieve your requirement, we've made a simple sample. Please take a look.
Concern Code Snippet:
|
<GridEvents RowUpdating="RowUpdatingHandler" TValue="OrderDetails"></GridEvents> …. public void RowUpdatingHandler(RowUpdatingEventArgs<OrderDetails> args) { args.Data.TotalFreight = args.Data.Freight + args.Data.Freight2 + +args.Data.Freight3; } |
Concern Sample link:
Please get back to us if you face any issues.
Regards,
Sanjay Kumar Suresh
Thanks for your answer but this solution works only to update the sum when you leave the row.
I need something more complex because what I have to do is an edit forms which enable/disable fields or change datasource for combos for activities 2 and 3 given what is inserted in the first activity type and Number of hours.
So for example if the user insert 8 working hours in activity1, then all other fields need to be readonly, while if they insert less than 8h then I need to enable activity2.
I tried to use template to achive this:
<div hidden="@rendering" style="height: calc(100vh - 6rem)">
<table class="m-0" style="width:99%;height:99%">
<tr>
<td>
<SfGrid name="gridAss" Height="100%" Width="100%" @ref="@TSGrid" DataSource="@listTS" Locale="it" RowHeight="30" AllowPaging="false" AllowResizing="true" AllowSorting="true" ContextMenuItems="@(new List<object>() { "AutoFit", "AutoFitAll", "SortAscending", "SortDescending"})"
AllowSelection="true" AllowFiltering="true" EnablePersistence="true" style="padding: 5px">
<GridSelectionSettings PersistSelection="true" Type="Syncfusion.Blazor.Grids.SelectionType.Single"></GridSelectionSettings>
<GridEditSettings AllowEditing="true" AllowAdding="false" AllowDeleting="false" Mode="EditMode.Dialog">
<HeaderTemplate>
@{
var obj = (context as objTms);
<div class="col-form-label">
Dettagli attività del giorno: @obj.dateTS.ToString("dd/MM/yyyy")
</div>
}
</HeaderTemplate>
<Template>
@{
var obj = (context as objTms);
<div class="form-row">
<div class="form-group col-sm-9">
<SfDropDownList ID="activityType1" DataSource="@activityList" TItem="EnumItem" TValue="int?" Placeholder="Attività 1" FloatLabelType="FloatLabelType.Always" @bind-Value="@obj.activityType1" CssClass="form-control">
<DropDownListFieldSettings Text="descr" Value="EID"></DropDownListFieldSettings>
</SfDropDownList>
</div>
<div class="form-group col-sm-3">
<SfTimePicker ID="nOre1" @bind-Value="@obj.nOre1TO" Placeholder="N° Ore" FloatLabelType="FloatLabelType.Always" CssClass="form-control">
<TimePickerEvents TValue="TimeOnly?" ValueChange="nOreChangeHandler"></TimePickerEvents>
</SfTimePicker>
</div>
</div>
<div class="form-row">
<div class="form-group col-sm-9">
<SfDropDownList ID="activityType2" Readonly="roAct2" DataSource="@activityList" TItem="EnumItem" TValue="int?" Placeholder="Attività 2" FloatLabelType="FloatLabelType.Always" @bind-Value="@obj.activityType2" CssClass="form-control">
<DropDownListFieldSettings Text="descr" Value="EID"></DropDownListFieldSettings>
</SfDropDownList>
</div>
<div class="form-group col-sm-3">
<SfTimePicker ID="nOre2" @bind-Value="@obj.nOre2TO" Readonly="roAct2" Placeholder="N° Ore" FloatLabelType="FloatLabelType.Always" CssClass="form-control">
<TimePickerEvents TValue="TimeOnly?" ValueChange="nOreChangeHandler"></TimePickerEvents>
</SfTimePicker>
</div>
</div>
<div class="form-row">
<div class="form-group col-sm-9">
<SfDropDownList ID="activityType3" Readonly="roAct3" DataSource="@activityList" TItem="EnumItem" TValue="int?" Placeholder="Attività 3" FloatLabelType="FloatLabelType.Always" @bind-Value="@obj.activityType3" CssClass="form-control">
<DropDownListFieldSettings Text="descr" Value="EID"></DropDownListFieldSettings>
</SfDropDownList>
</div>
<div class="form-group col-sm-3">
<SfTimePicker ID="nOre3" @bind-Value="@obj.nOre3TO" Readonly="roAct3" Placeholder="N° Ore" FloatLabelType="FloatLabelType.Always" CssClass="form-control">
<TimePickerEvents TValue="TimeOnly?" ValueChange="nOreChangeHandler"></TimePickerEvents>
</SfTimePicker>
</div>
</div>
}
</Template>
</GridEditSettings>
<GridEvents TValue="objTms" RowSelected="@Ass_Grid_Selected" OnBeginEdit="OnBeginEdit" QueryCellInfo="QueryCellInfoHandler"></GridEvents> @* DataBound="Ass_Grid_DataBound" *@
<GridFilterSettings Type="Syncfusion.Blazor.Grids.FilterType.Menu"></GridFilterSettings>
<GridColumns>
<GridColumn Field=@nameof(objTms.ID) Visible="false" HeaderText="ID" IsPrimaryKey="true" Width="40"></GridColumn>
<GridColumn Field=@nameof(objTms.COD_AMM) Visible="false" HeaderText="CA" Width="40"></GridColumn>
<GridColumn Field=@nameof(objTms.dateTS) Visible="false" AllowEditing="false" HeaderText="Giorno" Type="ColumnType.DateOnly" Format="dd" AutoFit></GridColumn>
<GridColumn Field=@nameof(objTms.dayTS) AllowEditing="false" HeaderText="Giorno" Type="ColumnType.String" AutoFit></GridColumn>
<GridColumn Field=@nameof(objTms.totOreTO) HeaderText="Tot. ore" Type="ColumnType.TimeOnly" MinWidth="100px" AutoFit="true"></GridColumn>
<GridForeignColumn Field=@nameof(objTms.activityType1) HeaderText="Attività 1" ForeignKeyValue="descr" ForeignKeyField="EID" ForeignDataSource="activityList" Type="ColumnType.String" MinWidth="200px" AutoFit="true"></GridForeignColumn>
<GridColumn Field=@nameof(objTms.nOre1TO) HeaderText="N° ore" Type="ColumnType.TimeOnly" MinWidth="110px" AutoFit="true"></GridColumn>
<GridForeignColumn Field=@nameof(objTms.activityType2) HeaderText="Attività 2" ForeignKeyValue="descr" ForeignKeyField="EID" ForeignDataSource="activityList" Type="ColumnType.String" MinWidth="200px" AutoFit="true"></GridForeignColumn>
<GridColumn Field=@nameof(objTms.nOre2TO) HeaderText="N° ore" Type="ColumnType.TimeOnly" MinWidth="100px" AutoFit="true"></GridColumn>
<GridForeignColumn Field=@nameof(objTms.activityType3) HeaderText="Attività 3" ForeignKeyValue="descr" ForeignKeyField="EID" ForeignDataSource="activityList" Type="ColumnType.String" MinWidth="200px" AutoFit="true"></GridForeignColumn>
<GridColumn Field=@nameof(objTms.nOre3TO) HeaderText="N° ore" Type="ColumnType.TimeOnly" MinWidth="100px" AutoFit="true"></GridColumn>
<GridColumn Field=@nameof(objTms.notes) HeaderText="Note" Type="ColumnType.String" MinWidth="150px" AutoFit="true"></GridColumn>
</GridColumns>
</SfGrid>
</td>
</tr>
</table>
</div>
using combobox and textbox events to achive the result (I just started with some attempts), but I can't succeed in refresh the edit popup form done with template even if I call statehaschanged().
public void OnBeginEdit(BeginEditArgs<objTms> args)
{
isDirty = true;
selDay = args.RowData;
TimeSpan totalHours = new();
if (selDay.activityType1 == 0) { totalHours = (selDay.nOre1 ?? TimeSpan.Zero); }
if (selDay.activityType2 == 0) { totalHours = totalHours + (selDay.nOre2 ?? TimeSpan.Zero); }
if (selDay.activityType3 == 0) { totalHours = totalHours + (selDay.nOre3 ?? TimeSpan.Zero); }
selDay.totOre = totalHours;
roAct2 = true; roAct3 = true;
if (totalHours < TimeSpan.Parse("08:00"))
{
if (selDay.activityType1 == null) { roAct2 = true; roAct3 = true; }
else if (selDay.activityType2 == null) { roAct2 = false; roAct3 = true; }
else { roAct2 = false; roAct3 = false; }
}
}
public void nOreChangeHandler(Syncfusion.Blazor.Calendars.ChangeEventArgs<TimeOnly?> args)
{
//Calcolo le ore lavorative come somma di nOre1, nOre2 e nOre3 se activityType è uguale a zero
TimeSpan totalHours = new();
if (selDay.activityType1 == 0) { totalHours = (selDay.nOre1 ?? TimeSpan.Zero); }
if (selDay.activityType2 == 0) { totalHours = totalHours + (selDay.nOre2 ?? TimeSpan.Zero); }
if (selDay.activityType3 == 0) { totalHours = totalHours + (selDay.nOre3 ?? TimeSpan.Zero); }
roAct2 = true; roAct3 = true;
if (totalHours < TimeSpan.Parse("08:00"))
{
if (selDay.activityType1 == null) { roAct2 = true; roAct3 = true; }
else if (selDay.activityType2 == null) { roAct2 = false; roAct3 = true; }
else { roAct2 = false; roAct3 = false; }
}
selDay.totOre = totalHours;
StateHasChanged();
}
public void QueryCellInfoHandler(QueryCellInfoEventArgs<objTms> args)
{
if ((args.Data.totOre ?? TimeSpan.Zero) == TimeSpan.Parse("08:00"))
{
args.Cell.AddClass(new string[] { "complete" });
}
else if ((args.Data.totOre ?? TimeSpan.Zero) < TimeSpan.Parse("08:00"))
{
args.Cell.AddClass(new string[] { "incomplete" });
}
else
{
args.Cell.AddClass(new string[] { "error" });
}
}
Is there a way to force a refresh of the controls (combo datasource, readonly true or false, and so on) in template edit form?
Regards
Michele
Hi Michele,
Based on your issue, we would like to let you know that we have optimized the
Grid component's rendering during external actions to enhance performance.
Therefore, we recommend using the grid's public method PreventRender(false)
in the ValueChange event to update the UI real time and achieve your desired
result. Please refer to the attached code snippet for further reference.
|
</div> <div class="form-group col-sm-3"> <SfTimePicker ID="nOre1" @bind-Value="@obj.nOre1TO" Placeholder="N° Ore" Width="120" FloatLabelType="FloatLabelType.Always" > <TimePickerEvents TValue="TimeSpan" ValueChange="nOreChangeHandler"></TimePickerEvents> </SfTimePicker> </div>
</div> public void nOreChangeHandler(Syncfusion.Blazor.Calendars.ChangeEventArgs<TimeSpan> args) {
if (args.Value >= TimeSpan.FromHours(8)) { roAct3 = true; roAct2 = true; } else if (args.Value < TimeSpan.FromHours(8)) { roAct3 = false; roAct2 = true; } TSGrid.PreventRender(false);
}
|
Sample: https://blazorplayground.syncfusion.com/embed/VDBeNBWjIKJzwkQp?appbar=true&editor=true&result=true&errorlist=true&theme=bootstrap5
Regards,
Naveen
- 4 Replies
- 3 Participants
-
MI Michele
- Feb 4, 2025 04:54 PM UTC
- Feb 10, 2025 04:15 PM UTC