1

I have below table in MVC.

    <table id="tbl" class="table table-bordered table-striped table-hover">
    <thead>
       <tr>
           <th>S.No</th>
           <th>Category</th>
           <th>ItemDescription</th>
           <th>Quantity </th>
           <th>UnitCost</th>
           <th>NoOfDays</th>
           <th>Amount</th>
           <th>Action</th>
        </tr>
    </thead>
    <tbody>
    @{
        var rows = Model.BudgetDetails.Count;
        for (int i = 0; i < rows; i++)
        {
          <tr>
             <td class="hidden">
               @Html.HiddenFor(a => a.BudgetDetails[i].EventBudgetID, new { @class="budgetID" })
               @Html.HiddenFor(a => a.BudgetDetails[i].BudgetCategory_ID, new { @class = "budgetCategoryID" })
            </td>
            <td>@Html.DisplayFor(a => a.BudgetDetails[i].RowNo)</td>
            <td>@Html.DisplayFor(a => a.BudgetDetails[i].BudgetCategory)</td>
            <td>@Html.DisplayFor(a => a.BudgetDetails[i].ItemDescription)</td>
            <td>@Html.DisplayFor(a => a.BudgetDetails[i].Quantity)</td>
            <td>@Html.DisplayFor(a => a.BudgetDetails[i].UnitCost)</td>
            <td>@Html.DisplayFor(a => a.BudgetDetails[i].NoOfDays)</td>
            <td>@Html.DisplayFor(a => a.BudgetDetails[i].ApprovedAmount)</td>
            <td><span class="btn btn-warning"><i class='fa fa-pencil'></i></span>
                <span class="btn btn-danger"><i class='fa fa-remove'></i></span>
            </td>
        </tr>
        }
       }
     </tbody>
    <tfoot>
       <tr>
          <td><input type="hidden" id="txtEventBudgetID" value="0" /></td>
          <td>@Html.DropDownList("Category", new SelectList(EventManagement.DAL.SetupDAL.GetActiveBudgetCategories(), "BudgetCategoryID", "BudgetCategory"), "-Select Category-", new { @class = "form-control select2" })
        </td>
        <td><input type="text" id="txtItem" class="txtGrid3" placeholder="Item Description" /> </td>
        <td><input type="text" id="txtQuantity" class="txtGrid2" placeholder="Quantity" /></td>
        <td><input type="text" id="txtUnitCost" class="txtGrid2" placeholder="Unit Cost" /></td>
        <td><input type="text" id="txtNoOfDays" class="txtGrid2" placeholder="Days" /></td>
       <td></td>
       <td><span class="btn btn-info"><i class='fa fa-plus'></i></span></td>
   </tr>
 </tfoot>
</table>

and with below JQuery code i am adding new row to table on run time.

$('span.btn-info').click(function () {
       var $tbl = $('#tbl tbody');
       var totalRow = $tbl.find('tr').length;
       var categoryID = $('#Category :selected').val(),
           category = $('#Category :selected').text(),
           item = $('#txtItem').val(),
           qty = $('#txtQuantity').val(),
           cost = $('#txtUnitCost').val(),
           days = $('#txtNoOfDays').val();
       if (categoryID == '') {
          alert('Category Required!!!');
          return;
       }
       if (item == '') {
          alert('Item Description Required!!!');
          return;
      }
      if (qty == '') {
         alert('Quantity Required!!!');
         return;
      }
      if (cost == '') {
          alert('Unit Cost Required!!!');
           return;
      }
      if (days == '') {
          alert('Number of Days Required!!!');
          return;
      }
      $tbl.find('tr').each(function (key, data) {
             var $this = $(this);
             $this.find('td:eq(0) input.budgetID').attr('name', 'BudgetDetails[' + key + '].EventBudgetID');
             $this.find('td:eq(0) input.budgetCategoryID').attr('name', 'BudgetDetails[' + key + '].BudgetCategory_ID');
             $this.find('td:eq(1)').text((key + 1));
             $this.find('td:eq(3) input').attr('name', 'BudgetDetails[' + key + '].ItemDescription');
             $this.find('td:eq(4) input').attr('name', 'BudgetDetails[' + key + '].Quantity');
             $this.find('td:eq(5) input').attr('name', 'BudgetDetails[' + key + '].UnitCost');
             $this.find('td:eq(6) input').attr('name', 'BudgetDetails[' + key + '].NoOfDays');
      });

      var html = '<tr>';
      html += '<td class="hidden"><input class="budgetID" name="BudgetDetails[' + totalRow + '].EventBudgetID" val="' + $('#txtEventBudgetID').val() + '"/>';
      html += '<input  class="budgetCategoryID" name="BudgetDetails[' + totalRow + '].BudgetCategory_ID" val="' + categoryID + '"/></td>';
      html += '<td>' + (totalRow + 1) + '</td>';
      html += '<td>' + category + '</td>';
      html += '<td><input type="hidden" name="BudgetDetails[' + totalRow + '].ItemDescription" val="' + item + '"/>' + item + '</td>';
      html += '<td><input type="hidden" name="BudgetDetails[' + totalRow + '].Quantity" val="' + qty + '"/>' + qty + '</td>';
      html += '<td><input type="hidden" name="BudgetDetails[' + totalRow + '].UnitCost" val="' + cost + '"/>' + cost + '</td>';
      html += '<td><input type="hidden" name="BudgetDetails[' + totalRow + '].NoOfDays" val="' + days + '"/>' + days + '</td>';
      html += '<td>' + (qty * cost * days) + '</td>';
      html += '<td><span class="btn btn-warning"><i class="fa fa-pencil"></i></span>';
      html += '<span class="btn btn-danger"><i class="fa fa-remove"></i></span></td>';
      html += '</tr>';
      $tbl.append(html);

    }

Rows are added successfully, below is my ActionMethod Code.

[HttpPost]
public ActionResult EventDetails(ViewModels.ClsEventDetailsViewModel d)
{
   try
   {
      d.User_ID = LoginUserID;
      if (EventCalenderDAL.SaveBudgetDetails(d))
      {
          ShowMessage(MessageBox.Success, OperationType.Saved, "Saved successfully.");
      }
      else
      {
      ShowMessage(MessageBox.Error, OperationType.Error, "Failed to Save");
      }

      return View();
  }
  catch (Exception ex)
  {
      ShowMessage(MessageBox.Error, OperationType.Error, ex.Message);
      return View();
  }
}

Problem : By adding break point in controller, i found that BudgetDetailslist contains two objects(i added two rows on run time), but properties of both objects were empty. Actual data was not passed to Controller. Below is the snapshot of debugging.

enter image description here

Whats wrong with this code.

Shahid Iqbal
  • 2,095
  • 8
  • 31
  • 51
  • 2
    What a awful way to dynamically add collection items . Refer [this answer](https://stackoverflow.com/questions/28019793/submit-same-partial-view-called-multiple-times-data-to-controller/28081308#28081308) for some examples - Option 2 if you want to do all this client side). And its `value="..."` not `val="..."` –  Oct 10 '17 at 07:07
  • Thanks it worked. Nice catch. – Shahid Iqbal Oct 10 '17 at 07:10
  • You will also only get the `EventBudgetID` and `BudgetCategory_ID` properties for any existing items because you do no include inputs for the other properties (and it will all fail if you have to return the view because `ModelState` is invalid) –  Oct 10 '17 at 07:13

0 Answers0