I'm try to update web form in my application web. When i try to add an empty new rows in my existing table, it's duplicate the last rows and data.
Update form illustration :
This is the code i used to perform this:
Entrepot Update controller code :
public async Task<bool> Update(Entrepot model)
{
try
{
if (model != null)
{
List<Emplacement> details = await GetEmplacementByEntrepotId(model.Id);
if (details.Count > 0)
{
_dtCtx.Emplacements.RemoveRange(details);
_dtCtx.SaveChanges();
}
foreach (var item in model.Emplacements)
{
item.Identification = item.Lane + "-" + item.Shelf + "-" + item.Storage;
item.EditDate = DateTime.Now.Date;
item.EditBy = GlsVariable.Login;
}
model.EditDate = DateTime.Now.Date;
model.EditBy = GlsVariable.Login;
_dtCtx.Entrepots.Attach(model);
_dtCtx.Entry(model).State = EntityState.Modified;
await _dtCtx.Emplacements.AddRangeAsync(model.Emplacements);
await _dtCtx.SaveChangesAsync();
return true;
}
return false;
}
catch (Exception ex)
{
_errors = GlsVariable.ItemUpdateFailure + " " + " - Erreur sql server surnevue!" + Environment.NewLine + "Erreur info : " + " " + ex.Message;
return false;
}
}
Update.cshtml
@model StockComApp.Models.Entrepot
@{
ViewData["Title"] = "Paramétrages - Stock";
}
<!-- Content Header (Page header) -->
<div class="content-header">
<div class="container-fluid">
<div class="row mb-2">
<div class="col-sm-6">
<h1 class="m-0">Paramétrages - Stock</h1>
</div><!-- /.col -->
</div><!-- /.row -->
</div><!-- /.container-fluid -->
</div>
<!-- /.content-header -->
<!-- Main content -->
<!-- Modal form -->
<section class="content">
<div class="container-fluid">
<div class="row">
<!-- left column -->
<div class="col-md-12">
<!-- jquery validation -->
<div class="card card-success">
<div class="card-header">
<h3 class="card-title">Entrepot - Modification</h3>
</div>
<!-- /.card-header -->
<!-- form start -->
<form id="genericForm" asp-action="Update" asp-controller="Entrepot">
<div class="card-body">
<div class="row">
<div hidden>
<tr>
<td>
<label asp-for="Id" class="control-label"></label>
</td>
<td>
<input asp-for="Id" class="form-control" autocomplete="off" readonly />
</td>
</tr>
<tr>
<td>
<label asp-for="CreateBy" class="control-label"></label>
</td>
<td>
<input asp-for="CreateBy" class="form-control" autocomplete="off" readonly />
</td>
</tr>
<tr>
<td>
<label asp-for="CreateDate" class="control-label"></label>
</td>
<td>
<input type="text" asp-format="{0:dd/MM/yyyy}" asp-for="CreateDate" class="form-control" autocomplete="off" />
</td>
</tr>
</div>
<div class="col-md-6 mx-auto">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<label asp-for="Name" class="control-label">Désignation entrepot</label>
<input asp-for="Name" class="form-control" autocomplete="off" />
<span asp-validation-for="Name" class="text-danger"></span>
</div>
<div class="col-md-6 mx-auto">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<label asp-for="Telephone" class="control-label"></label>
<input asp-for="Telephone" class="form-control" autocomplete="off" />
<span asp-validation-for="Telephone" class="text-danger"></span>
</div>
</div>
<div class="row">
<div class="col-md-12 mx-auto">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<label asp-for="Address" class="control-label"></label>
<textarea asp-for="Address" class="form-control" autocomplete="off"></textarea>
<span asp-validation-for="Address" class="text-danger"></span>
</div>
</div>
<br />
<div class="card card-success">
<div class="card-header text-center">
<div class="d-flex align-items-center">
<h5 class="mx-auto">Modification - Emplacements</h5>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-12">
<table style="height: 200px; overflow-y:auto;" id="tableEmplacement" class="table table-sm table-borderless table-hover table-responsive">
<thead>
<tr class="text-center" style="height:20px">
<th>
Désignation
</th>
<th>
Allée
</th>
<th>
Rayon
</th>
<th>
Rangement
</th>
<th>
<button type="button" id="btnadd" class="btn btn-sm btn-flat btn-success"
onclick="AddItem(this);" style="position:relative;">
Ajouter <i class="fa-solid fa-square-plus fa-xl"></i>
</button>
</th>
</tr>
</thead>
<tbody>
@for (int i = 0; i < Model.Emplacements.Count; i++)
{
<tr>
<td>
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<input asp-for="Emplacements[i].Name" class="form-control textInput">
<span asp-validation-for="Emplacements[i].Name" class="text-danger"></span>
</td>
<td>
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<input asp-for="Emplacements[i].Lane" class="form-control textInput">
<span asp-validation-for="Emplacements[i].Lane" class="text-danger"></span>
</td>
<td>
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<input asp-for="Emplacements[i].Shelf" class="form-control textInput">
<span asp-validation-for="Emplacements[i].Shelf" class="text-danger"></span>
</td>
<td>
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<input asp-for="Emplacements[i].Storage" class="form-control textInput">
<span asp-validation-for="Emplacements[i].Storage" class="text-danger"></span>
</td>
<td>
<button type="button" id="btnremove-@i" class="btn btn-sm btn-danger delbtn visible"
onclick="DeleteItem(this);" style= "position:relative;">
Retirer <i class="fa-solid fa-minus fa-xl"></i>
</button>
</td>
</tr>
}
</tbody>
</table>
<input type="hidden" id="lastIndex" value="0" />
</div>
</div>
</div>
<!-- /.card-body -->
<div class="card-footer">
<div class=" row col-sm-12">
<div class="col-sm-2"></div>
<input type="submit" value="Modifier" class="btn btn-sm btn-success btn-flat col-sm-4 m-1" />
<a asp-action="DisplayList" asp-controller="Entrepot" class="btn btn-sm btn-secondary btn-flat col-sm-4 m-1">Retour</a>
</div>
</div>
</form>
</div>
<!-- /.card -->
</div>
</div>
<!-- /.row -->
</div><!-- /.container-fluid -->
</section>
<!-- /.content -->
Script javascript :
<script>
function DeleteItem(btn) {
var table = document.getElementById('tableEmplacement');
var rows = table.getElementsByTagName('tr');
if (rows.length == 2) {
alert('Impossible de supprimer toutes les lignes');
return false;
}
else {
$(btn).closest('tr').remove();
}
}
function AddItem(btn) {
var table = document.getElementById('tableEmplacement');
var rows = document.getElementsByTagName('tr');
var rowOuterHtml = rows[rows.length - 1].outerHTML;
var lastRowIndex = rows.length - 1; // document.getElementById('lastIndex').value;
var nextRowIndex = eval(lastRowIndex) + 1;
rowOuterHtml = rowOuterHtml.replaceAll("_" + lastRowIndex + "_" , "_" + nextRowIndex + "_");
rowOuterHtml = rowOuterHtml.replaceAll("[" + lastRowIndex + "]" , "[" + nextRowIndex + "]");
rowOuterHtml = rowOuterHtml.replaceAll("-" + lastRowIndex, "-" + nextRowIndex);
var newRow = table.insertRow();
newRow.innerHTML = rowOuterHtml;
var inp = document.getElementsByClassName('textInput');
for (var x = 0; x < inp.length; x++) {
if (inp[x].type == 'text' && inp[x].id.indexOf("_" + nextRowIndex + "_") > 0) {
inp[x].value = "";
}
}
ValidatorMsg();
}
function ValidatorMsg() {
var $form = $("#genericForm");
$form.unbind();
$form.data("validator", null);
$.validator.unobtrusive.parse($form);
sform.validate($form.data("unobtrusiveValidation").options);
}
</script>
By using this code i can update Entrepot - Emplacement, but the problem is that when i update the emplacement informations i can't add new empty rows. The code duplicate the existing rows in the table.
You get the wrong last index, modify this line:
var lastRowIndex = rows.length - 2;