2

I have a table of dropdowns and I'm trying to duplicate the table (tbody) with the click of the button. I got it to duplicate but the data is passed over. This is a MVC application using ASP.NET Framework. How can I do this without the data passing over as well as the ID incrementing by 1. Here's my HTML code:

<div id="AddImpactDiv" class="row" style="background-color: rgb(240,240,240); padding: 20px;">
    <div class="col-xs-12">
        <table id="AddImpactTable" style="width:100%">
            <tbody id="AddImpactBody">
                <tr>
                    <td style="width:33.3%" data-name="ImpactType">
                        Impact Type:
                    </td>
                    <td style="width:33.3%" data-name="ImpactStatement">
                        Impact Statement:
                    </td>
                    <td style="width:33.3%" data-name="Impact">
                        Impact:
                    </td>
                </tr>
                <tr>
                    <td data-name="ImpactTypeDD">
                        <div class="col-xs-12" id="ImpactTypeDiv" data-url="@Url.Action("GetImpactType", "Aspects")">
                            @Html.DropDownListFor(model => model.ImpactType, Model.ImpactTypeList, new { @class = "form-control req-field", @required = "required" })
                        </div>
                    </td>
                    <td data-name="ImpactStatementDD">
                        <div class="col-xs-12" id="ImpactDiv" data-url="@Url.Action("GetImpact", "Aspects")">
                            @Html.DropDownListFor(model => model.Impact, Model.ImpactList, new { @class = "form-control req-field", @required = "required" })
                        </div>
                    </td>
                    <td data-name="ImpactDD">
                        <div class="col-xs-12" id="FrequencyDiv" data-url="@Url.Action("GetFrequency", "Aspects")">
                            @Html.DropDownListFor(model => model.Frequency, Model.FrequencyList, new { @class = "form-control req-field", @required = "required" })
                        </div>
                    </td>
                </tr>
                <tr>
                    <td width="33%"></td>
                    <td width="16.7%" data-name="Consequence">
                        <div style="padding-left:15px">
                            <p align="left">Consequence Score: </p>
                        </div>
                        <div class="col-xs-5" style="padding-top:7px" id="ConsequenceScoreDiv" data-url="@Url.Action("GetConsequenceScore", "Aspects")">
                            @Html.DropDownListFor(model => model.Consequence, Model.ConsequenceList, new { @class = "form-control req-field", @required = "required" })
                        </div>
                    </td>
                    <td width="16.7%" data-name="Frequency">
                        <div style="padding-left:15px">
                            <p align="left">Impact: </p>
                        </div>
                        <div class="col-xs-5" style="padding-top:7px" id="FrequencyScoreDiv" data-url="@Url.Action("GetFrequencyScore", "Aspects")">
                            @Html.DropDownListFor(model => model.Frequency, Model.FrequencyList, new { @class = "form-control req-field", @required = "required" })
                        </div>
                    </td>
                </tr>
            </tbody>
        </table>
    </div>
    <div class="col-xs-2">
        <button id="addImpact" type="button" class="form-control btn btn-primary">Add Impact</button>
    </div>
</div>

and my Jquery:

    $("#addImpact").click(function () {
    $("#AddImpactTable").clone().insertAfter("#AddImpactTable");
});
Angela
  • 49
  • 2
  • After reading through your source code, I think I see what you're trying to achieve. You essentially have an "Add New Item" button at the bottom of the table where the existing data structure and form controls should be presented again. Should the user be able to only add 1 more item, or many items at once? – bkwdesign Feb 23 '18 at 17:11
  • @bkwdesign Yes that's what I'm trying to do. The button "addImpact" basically takes the table above and clones it once. They can clone it more if the user wants, but one click=one duplicate. I got it to clone, but it also takes the data from the table before. – Angela Feb 23 '18 at 18:44
  • Your view makes no sense if your wanting to clone it - its based on a single object, and all you would be doing is duplicating the `name` attributes so it could never bid to your model - only the first set of form controls will be bound (not to mention all the invalid html) –  Feb 24 '18 at 09:06
  • I suggest you refer the options in [this answer](http://stackoverflow.com/questions/28019793/submit-same-partial-view-called-multiple-times-data-to-controller/28081308#28081308) and for a more detailed example refer [this answer](http://stackoverflow.com/questions/40539321/partial-view-passing-a-collection-using-the-html-begincollectionitem-helper/40541892#40541892) –  Feb 24 '18 at 09:07

1 Answers1

0

I wouldn't recommend cloning your table with jQuery. It's going to make your client side code unnecessarily messy and hack-ish. If you proceed down this route:

  1. the HTML element id's that are supposed to be unique, won't be

  2. You'll need to do other things to the names of your cloned menu fields to make them post back in a certain manner to the controller

FIRST: I would start by changing the model being passed into the razor code. You want an IList<MyImpactBizObj> or an IEnumerable<MyImpactBizObj> - the first item in the list would be the actual object with data being rendered as you have it, and then the other items in the list are empty stand-ins with default values.

SECOND: for the actual razor code for rendering your 'multi item form' will need to follow the guidelines set forth in this must-read tutorial from Phil Haack MVC model binding to a list

THIRD: Everytime you click the 'Add Impact' button, POST back to the MyImpactConroller.EditImpacts() and perhaps you have a hidden field that your submit button manipulates to pass in the desired length of your form, so it can be re-rendered with the correct number of items.

So, the controller signature might be: MyImpactConroller.EditImpacts(int formLength, IList<MyImpactBizObj> items) and if your controller logic notices a value in formLength it knows to simply re-render the existing grid, otherwise, if it detects that you are saving your work.. then process the posted items

The 'Add Impact' button can be a submit button with a different value. You'll have to google up on how to respond to different sumbit buttons on the same form, but, it can be done.


UPDATE - switched around steps 2 and 3 above, with different advice in step 3


bkwdesign
  • 1,953
  • 2
  • 28
  • 50