0

I am able to successfully accept one entry to my database. But, the rest of the entries are not from my dynamically added fields.

Here is my Create for Sibling:

 [HttpPost]
 [ValidateAntiForgeryToken]
 public ActionResult Create(List<sibling> siblings)
    {

        if (ModelState.IsValid)
        {
            foreach(sibling x in siblings)
            {
                db.siblings.Add(x);
                db.SaveChanges();
            }
            return RedirectToAction("Index");
        }
        return View(siblings);

Here is my Sibling model:

public partial class sibling
{
    public int sibling_id { get; set; }
    public int child_id { get; set; }
    public Nullable<int> age { get; set; }
    public string gender { get; set; }

    public virtual child child { get; set; }
}

This is my Create.cshtml:

@model dummyApp.Schema.TestModels.sibling

@{
ViewBag.Title = "Create";
}

@section Scripts{
<script type="text/javascript">

    $(document).ready(function () {
        //var max_fields = 10; //maximum input boxes allowed
        var wrapper = $(".input_fields_wrap"); //Fields wrapper
        var add_button = $(".add_field_button"); //Add button ID

        var x = 1; //initlal text box count
        $(add_button).on("click", function (e) { //on add input button click
            e.preventDefault();
            //if (x < max_fields) { //max input box allowed
                x++; //text box increment
                $(wrapper).append('<div class="form-group">\
                                        <p>Child ID: <input type="number" name="siblings[' + x + '].child_id"/></p>       \
                                        <p>Age: <input type="number" name="siblings[' + x + '].age"/></p> \
                                        <p>Gender: <input type="text" name="siblings[' + x + '].gender"/></p>   \
                                        <a href="#" class="remove_field">Remove</a>     \
                                    </div>'); //add input box
            //}
        });

        $(wrapper).on("click", ".remove_field", function (e) { //user click on remove text
            e.preventDefault(); $(this).parent('div').remove(); x--;
        })
    });

</script>
 }
 <h2>Create</h2>

 @using (Html.BeginForm())
{
@Html.AntiForgeryToken()

<div class="form-horizontal">
    <h4>sibling</h4>

    <div class="input_fields_wrap">
        <button class="add_field_button btn btn-info">Add More Fields</button>
        <br><br>
        <div class="form-group">
            <p>Child ID: <input type="text" name="siblings[0].child_id" /></p>
            <p>Age: <input type="text" name="siblings[0].age" /></p>
            <p>Gender: <input type="text" name="siblings[0].gender" /></p>
        </div>
    </div>

    <div class="form-group">
        <br>
        <div class="col-md-offset-0 col-md-10">
            <input type="submit" value="Create" class="btn btn-default" />
        </div>
    </div>

</div>
 }

 <div>
@Html.ActionLink("Back to List", "Index")

Fritz
  • 89
  • 7
  • where did you call "Create" method? – Ashkan S Sep 04 '16 at 06:18
  • you can do something like Html.Action("ActionName","ControllerName", Model) – Ashkan S Sep 04 '16 at 06:19
  • can you edit the question with this info? – Kira Sep 04 '16 at 06:20
  • @AshkanSirous That is already taken care of by my view - after the user clicks on the create button. So, calling the "Create" Method is not a problem at all for me. What I just need is for my "Create" Method to accept the list completely. – Fritz Sep 04 '16 at 06:22
  • where is the code that passes your list from client-side? – Kira Sep 04 '16 at 06:25
  • no, you should pass your list as javascript array through form get / post request or ajax get / post request – Kira Sep 04 '16 at 06:27
  • take a look at this. it is not the same as your problem, but he is trying to do the same http://stackoverflow.com/questions/5663385/asp-net-mvc-html-submit-button-not-sent-with-post – Ashkan S Sep 04 '16 at 06:32
  • @AshkanSirous I followed the same thing in what you linked but still the same result. It seems that my Create is still posting for some reason but only for the first entry. If it helps my views were originally generated through MVC 5 Scaffolding so the CRUD functions were generated automatically. – Fritz Sep 04 '16 at 06:45

1 Answers1

1

Your initial value of x is 1 and you are doing x++ before passing it to the dynamic html which you create in javascript; which will render elements as siblings[2].child_id. This breaks the continuity of index as aiblings[1] is missing and model binder will stop binding when it reaches a break in the sequence.

As a solution,

Update - it is always better to go with Non-Sequential Indices approach as the first approach mentioned will break in case there is a delete functionality which will inturn deletes one item in between thus breaking the sequence.

Developer
  • 6,240
  • 3
  • 18
  • 24
  • Thank you so much for pointing that out in my Javascript code! I did not get to notice it. Such a minor fault. – Fritz Sep 04 '16 at 07:03
  • That happens ;) .Sometimes all we need is an extra pair of eyes. Cheers. – Developer Sep 04 '16 at 07:06
  • This will not work at all - just delete one of the items and post it (binding will fail) –  Sep 04 '16 at 07:13
  • @StephenMuecke - For that I have mentioned the other approach - Non-Sequential Indices, I'll update this specifically in my answer, thanks for that. – Developer Sep 04 '16 at 07:22
  • I applied the non-sequential indices approach to my code as well. It's now working flawlessly! – Fritz Sep 23 '16 at 14:46