Search code examples
javascriptasp.net-core-mvc

Added row by JavaScript doesn't appear when I press save


So I have this class

public class Tires {
  public int ID { get; set; }
  public string ArName { get; set; }
  public string EnName { get; set; }
  public Boolean IsMain { get; set; }
  public List<TireRecord> NewRecords { get; set; }
}
public class TireRecord {
  public string ArName { get; set; }
  public string EnName { get; set; }
  public bool IsMain { get; set; }
}

I want to add multiple rows then save it to database. I add the rows by JavaScript and it adds rows but when I press save I can't reach the row as if they don't exist.

Here is my view

@model WebApplication6.Models.Tires

@{
    Layout = null;
}

<!DOCTYPE html>
<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Index</title>
</head>
<body>
    <form method="post" asp-action="Index" asp-controller="Tires">
        <h4>Tires</h4>
        <hr />

       <table>
           <thead>
              <tr>
                  <th>Arabic Name</th>
                  <th>English Name</th>
                 <th>Is Active</th>
             </tr>
         </thead>
         <tbody id="table-body">
             @for (var i = 0; i < Model.NewRecords.Count; i++)
             {
                 <tr>
                    <td><input type="text" asp-for="NewRecords[i].ArName" /></td>
                   <td><input type="text" asp-for="NewRecords[i].EnName" /></td>
                  <td><input type="checkbox" asp-for="NewRecords[i].IsMain" /></td>
             </tr>
        }
   </tbody>
      </table>

     <button type="button" id="add-button">Add</button>
    <button type="submit" id="save-button">Save</button>
    <div>
   <a asp-action="Index">Back to List</a>
    </div>
   </form>

  <script>
 const addButton = document.getElementById('add-button');
 const tableBody = document.getElementById('table-body');
 let newRowCounter = @Model.NewRecords.Count;

   addButton.addEventListener('click', () => {
 newRowCounter++;

  const newRow = document.createElement('tr');
newRow.innerHTML = <td><input type="text" name="NewRecords[${newRowCounter}].ArName" /></td>
  <td><input type="text" name="NewRecords[${newRowCounter}].EnName" /></td>
  <td><input type="checkbox" name="NewRecords[${newRowCounter}].IsMain" /></td>;
      tableBody.appendChild(newRow);
 });
  </script>
</body>
</html>

and in my Controller

IRepositories<Tires> Tires_;
public List<TireRecord> NewRecords { get; set; }

Tires model;
public TiresController(IRepositories<Tires> Tires1)
{
    Tires_ = Tires1;
    NewRecords = new List<TireRecord>();

   model = new Tires
    {
        // Initialize other properties if needed
        NewRecords = new List<TireRecord>() // Initialize the NewRecords property
    };
}
[HttpPost]
public IActionResult Index(Tires model)
{
   

    return RedirectToAction("DisplayRecords");
}
public ActionResult Index()
{

    return View(model);
    
}

I tried everything -- Google, YouTube, even AI -- but nothing works. I just want to save them in the end.


Solution

  • First is you could use this instead, it works.

    newRow.innerHTML = '<td><input type="text" name = "NewRecords['+NewRowCounter+'].ArName" /></td><td><input type="text" name = "NewRecords['+NewRowCounter+'].EnName" /></td><td><input type="checkbox" name = "NewRecords['+NewRowCounter+'].IsMain"/></td>';
    

    Second is List index start form 0. So use newRowCounter++; after newRow.innerHTML, then will be all good.
    I use this data for a test

            public IActionResult Index()
            {
                var model=new Tires { 
                                    NewRecords =new List<TireRecord>
                                    {
                                        new TireRecord {ArName=" arname01",EnName="EnName01",IsMain=false}
                                    }                                   
                };
                return View(model);
            }
    

    enter image description here