Skip to content

Instantly share code, notes, and snippets.

@shawty
Last active October 24, 2023 09:48
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save shawty/2bf50db5f942d37ec0737b1068739eb1 to your computer and use it in GitHub Desktop.
Save shawty/2bf50db5f942d37ec0737b1068739eb1 to your computer and use it in GitHub Desktop.
Blazor component to allow editing of a data table using a simple grid and drop down
@using Microsoft.AspNetCore.Components
@using Microsoft.AspNetCore.Components.Web
@using MyProject.DataModels
@inject MyProject.Services.ClientGridData _gridDataService
@inject MyProject.Services.Clients _dropDownDataService
<div class="row d-flex align-items-center">
<div class="col">
<div class="form-group">
<select class="form-control" @onchange="@(e => DropDownChanged(e))" disabled="@RowBeingEdited">
<option value="-1" disabled selected>Please Select An Item</option>
@foreach (var dropDownOption in AvailableDropDownData)
{
<option value="@dropDownOption.Key">@dropDownOption.Value</option>
}
</select>
</div>
</div>
<div class="col text-right">
@if (SelectedDropDownOption > 0)
{
<button class="btn btn-success" @onclick="@AddNew" disabled="@RowBeingEdited">Add New Project Type</button>
}
</div>
</div>
@if (GridData.Count == 0 || SelectedDropDownOption == 0)
{
<div class="row">
<div class="col">
@if (SelectedDropDownOption == 0)
{
<p class="lead text-danger">Please select a drop down item to work with.</p>
}
else if (GridData.Count == 0)
{
<p class="lead text-warning">There are no records in the grid data table for the selected drop down.</p>
}
</div>
</div>
}
else
{
<table class="table table-bordered">
<thead class="bg-light">
<tr>
<th style="width: 200px;">Grid Col One</th>
<th>Grid Col Two</th>
<th style="width: 200px;">&nbsp;</th>
</tr>
</thead>
<tbody>
@foreach (var gridItem in GridData)
{
<tr class="@(gridItem.Value.editMode ? "table-danger" : "")">
@if (gridItem.Value.editMode)
{
<td><input class="form-control" type="text" @bind="@gridItem.Value.data.TypeName" /></td>
<td><input class="form-control" type="text" @bind="@gridItem.Value.data.Description" /></td>
}
else
{
<td>@gridItem.Value.data.TypeName</td>
<td>@gridItem.Value.data.Description</td>
}
<td class="text-right">
<button class="btn btn-primary btn-sm @(gridItem.Value.editMode ? "hidden" : "")" @onclick="@(() => StartEditMode(gridItem.Value.data.Id))" disabled="@RowBeingEdited">Edit</button>
<button class="btn btn-success btn-sm @(gridItem.Value.editMode ? "" : "hidden")" @onclick="@(() => SaveRowEdit(gridItem.Value.data.Id))">Save</button>
<button class="btn btn-danger btn-sm @(gridItem.Value.editMode ? "" : "hidden")" @onclick="@(() => CancelEditMode(gridItem.Value.data.Id))">Cancel</button>
@if (!NewRecord)
{
<button class="btn btn-danger btn-sm @(gridItem.Value.editMode ? "" : "hidden")" @onclick="@(() => Delete(gridItem.Value.data.Id))">Delete</button>
}
</td>
</tr>
}
</tbody>
</table>
}
@code {
private string _tempColOne = "";
private string _tempColTwo = "";
public int SelectedDropDownOption { get; set; } = 0;
public bool RowBeingEdited { get; set; } = false;
public bool NewRecord { get; set; } = false;
public Dictionary<int, (GridItem data, bool editMode)> GridData { get; set; }
= new Dictionary<int, (GridItem data, bool editMode)>();
public Dictionary<int, string> AvailableDropDownData =>
_dropDownDataService
.FetchAll()
.ToDictionary(r => r.Value, r => r.Text);
protected void DropDownChanged(ChangeEventArgs e)
{
if (Int32.TryParse((String)e.Value, out var index) && index >= 0)
{
SelectedDropDownOption = index;
GridData = _gridDataService
.FetchMany(r => r.DropDownKey == SelectedDropDownOption)
.ToDictionary(r => r.Id, r => (data: r, editMode: false));
}
}
protected void AddNew()
{
if (RowBeingEdited)
{
// We can't go into edit mode to add new if we are already editing
return;
}
GridItem newgridItem = new GridItem() { Id = 0, DropDownKey = SelectedDropDownOption, ColOne = "", ColTwo = "" };
GridData.Add(0, (data: newgridItem, editMode: true));
RowBeingEdited = true;
NewRecord = true;
}
protected void Delete(int gridItemId)
{
_gridDataService.Delete(gridItemId);
GridData.Remove(gridItemId);
RowBeingEdited = false;
}
private void SetRowEdit(int gridItemId)
{
var prjType = GridData[gridItemId];
prjType.editMode = true;
GridData[gridItemId] = prjType;
RowBeingEdited = true;
}
private void UnSetRowEdit(int gridItemId)
{
var prjType = GridData[gridItemId];
prjType.editMode = false;
GridData[gridItemId] = prjType;
RowBeingEdited = false;
}
protected void StartEditMode(int gridItemId)
{
SetRowEdit(gridItemId);
_tempColOne = GridData[gridItemId].data.ColOne;
_tempColTwo = GridData[gridItemId].data.ColTwo;
}
protected void CancelEditMode(int gridItemId)
{
UnSetRowEdit(gridItemId);
if (NewRecord)
{
NewRecord = false;
GridData.Remove(0);
return;
}
GridData[gridItemId].data.ColOne = _tempColOne;
GridData[gridItemId].data.ColTwo = _tempColTwo;
}
protected void SaveRowEdit(int gridItemId)
{
if (NewRecord)
{
var newData = _gridDataService.Add(GridData[gridItemId].data);
GridData.Remove(0); // Remove the temp entry (We can't change a dictionarys key)
GridData.Add(newData.Id, (data: newData, editMode: false));
NewRecord = false;
RowBeingEdited = false;
return;
}
_gridDataService.Update(GridData[gridItemId].data);
UnSetRowEdit(gridItemId);
}
}
@shawty
Copy link
Author

shawty commented Nov 13, 2019

Fairly simple blazor component for editing data based on a drop down key, and forming a fairly simple data set (In my case other drop downs based on a drop down of client id's).

Wrote it mainly because I really couldn't be bothered doing the full set of index/add/edit/delete razor pages for 20 sets of simple data items, so I wrote an index and a component to go on it :-)

Only tested with Blazor server side, esp as it uses a services based approach rather than HTTP requests, shouldn't take much to adapt tho if you want it on the client.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment