Skip to content

Instantly share code, notes, and snippets.

@shawty shawty/GridEditor.razor
Last active Nov 13, 2019

Embed
What would you like to do?
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

This comment has been minimized.

Copy link
Owner 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
You can’t perform that action at this time.