2

I have the following html table definition in my main view

<table id="myDynamicTable" cellpadding="0" cellspacing="0" class="burTable" width="964px">
        <thead>
            <tr>
                <th style="white-space: nowrap;display: inline;width: 40px" >
                    ColOne
                </th>
                <th style="white-space: nowrap;display: inline;width: 90px">
                    ColTow
                </th>
                <th style="white-space: nowrap;display: inline;width: 54px">
                    ColThree
                </th>
                <th style="white-space: nowrap;display: inline;width: 60px">
                    ColFour
                </th>
                <th style="white-space: nowrap;display: inline;width: 399px">
                    ColFive
                </th>
                <th style="white-space: nowrap;display: inline;width: 474px">
                    ColSix
                </th>
            </tr>
        </thead>
        <tbody>
          @if (Model.myViewModel.Count() > 0)
            {
                int i = 1;
                foreach (var item in Model.myViewModel)
                {
                    <tr >
                        <td class="tdBorder">
                            @Html.DisplayFor(x => item.AutoNumber, new { @readonly = "readonly" })
                            @Html.HiddenFor(x => item.Code, new { id = "Code" + @i })
                        </td>
                        <td>
                            @Html.TextBoxFor(x => item.SerialNumber, new { id = "SerialNumber" + @i, @Class = "numberOnly", maxlength = 15 })
                        </td>
                        <td>
                            @Html.DropDownList("ddlItemType" + @i, new SelectList(ViewBag.ddlItemTypeList as System.Collections.IEnumerable, "Value", "Text", item.ItemTypeId))
                        </td>
                        <td>
                            @Html.TextBoxFor(x => item.Date, new { id = "Date" + @i })
                        </td>
                        <td>
                            @Html.DropDownList("ddlUnit" + @i, new SelectList(ViewBag.UnitList as System.Collections.IEnumerable, "Value", "Text", item.UnitId))
                        </td>
                        <td>
                            @Html.TextBoxFor(x => item.Comment, new { id = "Comment" + @i, @class = "Comment RestrictCharacters", maxlength = 1000 })
                        </td>
                    </tr>
                    i += 1;
                }

            }
            else
            {
                <tr id="FirstRow" class="tdBorder">
                    <td class="tdBorder">
                       @Html.TextBox("AutoNumber", null, new { @width = 60, id = "AutoNumber" })
                    </td>
                    <td>
                        @Html.TextBox("SerialNumber", null, new { @width = 150, id = "SerialNumber" })
                    </td>
                    <td>
                         @Html.DropDownList("ddlItemType", new SelectList(ViewBag.ddlItemTypeList as System.Collections.IEnumerable, "Value", "Text"), new { @width = 60, id = "ddlItemType" })
                    </td>
                    <td>
                        @Html.TextBox("Date", null, new { @width = 60, id = "Date" })
                    </td>
                    <td>
                        @Html.DropDownList("ddlUnit", new SelectList(ViewBag.UnitList as System.Collections.IEnumerable, "Value", "Text"), new { @width = "auto", id = "ddlUnit" })
                    </td>
                    <td>
                        @Html.TextBox("Comment", null, new { @width = 700, id = "Comment" })
                    </td>
                </tr>
            }
        </tbody>
    </table>

I want to be able to add new rows using the BeginCollectionItem concept explained in here http://blog.stevensanderson.com/2010/01/28/editing-a-variable-length-list-aspnet-mvc-2-style/ and Add row in table with jquery whic connected with model in mvc

Below is the definition of my partial view which i want to use as a template to add new rows. @using MyProject.Utilities @model MyProject.ViewModel.ReportDetailsViewModel

@using (Html.BeginCollectionItem("NewRow"))
{
    <tr id="NewRow" class="tdBorder">
        <td class="tdBorder">
            @Html.TextBox("AutoNumber", null, new { @width = 60, id = "AutoNumber" })
        </td>
        <td>
            @Html.TextBox("SerialNumber", null, new { @width = 150, id = "SerialNumber" })
        </td>
        <td>
            @Html.DropDownListFor(model => model.ItemTypeId, Model.ItemTypeList, new { @id = "ddlItemType" })
        </td>
        <td>
            @Html.TextBox("Date", null, new { @width = 60, id = "Date" })
        </td>
        <td>
            @Html.DropDownList("ddlUnit", new SelectList(ViewBag.UnitList as System.Collections.IEnumerable, "Value", "Text"), new { @width = "auto", id = "ddlUnit" })
            @Html.DropDownListFor(model => model.UnitId, Model.UnitList)
        </td>
        <td>
            @Html.TextBox("Comment", null, new { @width = 700, id = "Comment" })
        </td>
    </tr>
}

In my main view, i'm trying to add new rows like below

 var tableBody = $('#myDynamicTable tbody');
    var url = '@Url.Action("Add", "Report")';
    $('#btnAddRow').click(function () {
        $.get(url, function (response) {
            tableBody.append(response);
        });
    });

The problem is, it appears like the rows are being added after the table body but not inside the body after the last row.

The other issue i'm having is the new row columns not aligning with the existing first row as well as also not picking the style sheets applied to the controls in the existing first row.

Below is the screenshot of what i'm so far getting and i'm struggling to alight these new rows with the existing first row.

Screenshot of table

Community
  • 1
  • 1
StackTrace
  • 9,190
  • 36
  • 114
  • 202
  • Not related, but you also need to use the partial in your `foreach` loop for existing items (otherwise binding will fail) –  Jan 29 '16 at 08:30
  • Is you image showing the result of adding 6 new rows? (and another unrelated note - you need to remove the `new { id = "..." }` from the HtmlHelper methods - your generating invalid html) –  Jan 29 '16 at 08:33
  • @StephenMuecke (1): thanks for youe comment about using partial in my foreach loop for existing items.,,,,(2) Yes, which ever number of rows i add come up, issue is with layout/alignment with table in main view and picking up the styles applied to controls in main views table. – StackTrace Jan 29 '16 at 08:42
  • 1
    Well you have `new { @width = 150 }` which I'm now guessing you think makes the element 150px wide - it doesn't :). It would have needed to be `new { style = "width:150px;" }` but just delete all them. Instead give your inputs a class name and use css to style them. –  Jan 29 '16 at 08:46
  • 1
    What happens if you remove the css and javascript parts from the partialview? Also, what happens if you remove the `BeginCollectionItem` code and return plain (unbound) html in the view (as a temporary measure)? Finally - what's the rendered html in the browser after adding a row? (ie try to find the minimum code that recreates the problem ([MVCE](http://stackoverflow.com/help/mcve)) – freedomn-m Jan 29 '16 at 08:47
  • Also remove `id="NewRow"` from the `` element (more duplicate `id` attributes) –  Jan 29 '16 at 08:47
  • @freedomn-m like you said, when i remove the both the javascript, css & the BeginCollectionItem code from the partial view only, the new rows become now properly aligned with the table in the main view. Leaving any of either Javascript, CSS or BeginCollectionItem breaks the layout again. Problem is my controls (DropdownLists) still do not pick the styles in the main view. – StackTrace Jan 29 '16 at 09:32
  • @StephenMuecke i guess removing the BeginCollectionItem code from the partial view definition will break the binding, is that right? – StackTrace Jan 29 '16 at 09:33
  • Yes, You need `Html.BeginCollectionItem()`, but that has nothing to do with the styling. But your image does not align with the code you have shown anyway - for example the first column has `width: 40px` and the last has `width: 474px` (10 times) yet the image shows them to be similar widths. –  Jan 29 '16 at 09:40
  • @StephenMuecke the width wasn't aligning with the code because i was using width:xxx_px instead of style = "width:xxx_px;". i have fixed that. Any idea why using "Html.BeginCollectionItem()" breaks the table layout? – StackTrace Jan 29 '16 at 10:33
  • It should have nothing to do with it (and neither should your javascript) so not sure what your doing wrong. But there is a lot in your code which does not make sense - e.g. what is the `span.ui-dropdownchecklist-selector` style - you don't even have any span elements - and in case partials should not have ` –  Jan 29 '16 at 10:37
  • What exactly is `Html.BeginCollectionItem()` adding to your html? (check the rendered html). The post you've linked to uses divs, so doesn't have this issue. It may be creating a new table (unlikely, but needs to be checked) and the browser is then rendering it as you see. – freedomn-m Jan 29 '16 at 10:54

1 Answers1

0
var tableBody = $('#myDynamicTable tbody');
        var url = '@Url.Action("Add", "Report")';
        $('#btnAddRow').click(function () {
            $.get(url, function (response) {
    $('#myDynamicTable tbody <tr />').html(response).appendTo(tableBody);          
            }); 
        });

change your jquery code as above. Then remove tr wrapper from partial view

@using MyProject.Utilities 
@model MyProject.ViewModel.ReportDetailsViewModel

@using (Html.BeginCollectionItem("NewRow"))
{

        <td class="tdBorder">
            @Html.TextBox("AutoNumber", null, new { @width = 60, id = "AutoNumber" })
        </td>
        <td>
            @Html.TextBox("SerialNumber", null, new { @width = 150, id = "SerialNumber" })
        </td>
        <td>
            @Html.DropDownListFor(model => model.ItemTypeId, Model.ItemTypeList, new { @id = "ddlItemType" })
        </td>
        <td>
            @Html.TextBox("Date", null, new { @width = 60, id = "Date" })
        </td>
        <td>
            @Html.DropDownList("ddlUnit", new SelectList(ViewBag.UnitList as System.Collections.IEnumerable, "Value", "Text"), new { @width = "auto", id = "ddlUnit" })
            @Html.DropDownListFor(model => model.UnitId, Model.UnitList)
        </td>
        <td>
            @Html.TextBox("Comment", null, new { @width = 700, id = "Comment" })
        </td>

}
Krishan
  • 2,356
  • 6
  • 36
  • 47