0

I have a HTML form that has two DIVs, one DIV is a fixed area this means that the inputs are not dynamic, and the second DIV is dynamic this means that I have a button that can clone the DIV as many times as a I want.

This is the jquery clode for cloning a new DIV:

 $('#btn-addsection').click(function (e) {
                var me = $(this);
                e.preventDefault();

                var lastRepeatingGroup = $('.repeating-section').last();
                var cloned = lastRepeatingGroup.clone(false)
                cloned.insertAfter(lastRepeatingGroup);

                var attrs = ['for', 'id', 'name'];

                var tags = section.find('input, label'),
                    idx = section.index();

                tags.each(function () {
                    var $this = $(this);
                    if ($this.is('input')) {
                        $this.val('');
                    }
                    $.each(attrs, function (i, attr) {
                        var attr_val = $this.attr(attr);
                        if (attr_val) {
                            $this.attr(attr, attr_val.replace(/_\d+$/, '_' + (idx)))
                        }
                    })
                })


            });

The above code will clone the DIV and will add a underscore "_" plus the next index to the field so I can identify it as a field for a second or third, etc. DIV cloned.

When I post to server I use:

 var formData = $('#form-newquote :input').serializeArray();

This is my Save method on server:

public JsonResult SaveQuote(QuoteModel model)
        {

            var response = this.JsonResponse;

            response = new JsonResponse
            {
                data = null,
                message = string.Empty,
                num = 0,
                success = true,
                code = null
            };

            return Json(response, JsonRequestBehavior.AllowGet);
        }

This is my QuoteModel:

enter image description here

The red mark is where I will many as many cloned items. My problem is how to send from jquery to server all my dynamic fields so on server I can map them to my QuoteSelectionMode object.

Any clue?

VAAA
  • 14,531
  • 28
  • 130
  • 253
  • Apart from the fact the `.serializearray()` will not work for properties which are complex properties or collections (it will not even work for a `bool` if you have use `CheckBoxFor()`, you `.replace(..)` code means that you view is not generated correctly in the first place and therefore could never bind to a model. If you want to do this all client side, then you might want to look at the 2nd option in [this answer](https://stackoverflow.com/questions/28019793/submit-same-partial-view-called-multiple-times-data-to-controller/28081308#28081308) –  Sep 10 '17 at 22:21

1 Answers1

0

You should use $('form').serialize() instead. I have never personally used serializeArray. But looking at the documentation, it creates an array of objects with name and value properties which I don't think ModelBinder will be able map to the QuoteModel.

Changing it to serialize() still won't bind your Sections property because of how you're handling name attribute.

It's crucial to set the name attribute properly whenever you're dealing with properties which are Collcetions of objects. In your case, your inputs should be like:

<input type="text" name="Sections[0].PropertName" />
<input type="text" name="Sections[0].PropertName2" />
<select name="Sections[0].PropertName3" />

When cloned, you should produce this:

<input type="text" name="Sections[1].PropertName" />
<input type="text" name="Sections[1].PropertName2" />
<select name="Sections[1].PropertName3" />

Besides this, make sure in your ajax, you've given same parameter name as your controller:

$.ajax({
    url: "/ControllerName/SaveQuote",
    data: { model: formData },
    ...........

Also, consider using knockout for this kind of recurring templates. Cloning using jquery is error-prone and you'll have to write a lot of junk code. In KO, observalbleArray.push(new viewModel()) and you're set.

adiga
  • 34,372
  • 9
  • 61
  • 83