Search code examples
javascriptasp.net-mvcasp.net-core

Update - add rows in table in Master Detail model - ASP.NET Core


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 :

Update form

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.


Solution

  • You get the wrong last index, modify this line:

    var lastRowIndex = rows.length - 2;