Jimmy Jimmy - 1 month ago 5
jQuery Question

MVC 3 - Render additional Editor templates for children objects

I'm trying to create a form that allows the user to create an an entity with 0-multiple children objects, the main object being a

Lead
which has 0-many
Beneficiary
and
Payer
objects. The relation between the three is as follows:

Lead has many Beneficiaries (one to many)
Lead has many Payers (many to many) joined through LeadsPayers


In my editor for my lead view model I have a loop that generates the editor for each beneficiary and payer attached to the lead but I want to be able to have a button that will dynamically add another beneficiary or payer to the lead and use the editor template so i don't have duplicated html in my javascript code.

I have this working to bind everything to the
Lead
when my form gets posted to the controller I just don't know how to reuse the editor template code to generate compatible html with my current form, has anyone done this before? There has to be a better way than an ajax button that renders the html

Answer

This helped me get on the right track but wasn't fully what I wanted to do and as this doesn't seem easily supported in MVC here is my work around to get this all to work with model binding in the controller.

My end goal

To dynamically add children objects to a form with the proper html so that they would be auto bound to the parent when passed to the control method, meaning I needed HTML like this

<input name='Lead_Beneficiaries_1__{Property}' id=... />

And not like this (which is what the blog post results in)

<input name='Beneficiary__{Property}' />

Which doesn't auto bind to the parent when posted to the controller.

Solution

Instead of using Ajax to render the editor template html from the controller, I auto render one editor template when the form is loaded and then more can be loaded as needed by the user. JQuery code

$("#addBeneficiary").click(function(e) {
    e.preventDefault();
    var beneficiary = $(".beneficiary:last").clone();
    var count = parseInt(beneficiary.find("input:first").attr("id").match(/\d+/), 10);
    beneficiary.find("input").each(function(indx, element) { 
        var name = $(element).attr('name').replace(count, count+1),
            id   = $(element).attr('id').replace(count, count+1);
        $(element).attr('name', name);
        $(element).attr('id', id);
        $(element).val(''); 
    });
    $("#beneficiaries").append(beneficiary);
});

I just wrapped my editor template in a div so it can be easily grabbed as a whole from jquery, cloned it, emptied the values of the inputs and incremented the counter for each element so when posted I get a collection of children entities on my parent without having to explicitly catch them in the method or pull them from the formcollection dictionary.

While this probably isn't the best solution, it gets the job done in the way I intended and I didn't end up duplicating HTML for the editor template. Also if the form errors since the parent object has the multiple children they get auto rendered automatically by my form code and nothing is lost because of client side additions.