0

I am editing a complex type (AddEventViewModel).

AddEventViewModel has a list of EventContacts called EventContactList.

I have an editor template for EventContactList that displays an EventContact for every item in the list in the model.

When the AddEventViewModel is initialised it will add an empty EventContact to the list and this means that a single Editor Template is displayed on the Add Event page.

Under the editor template I have a button called 'Add additional event contact'.

I would like this button to update the AddEventViewModel, adding an additional EventContact to the EventContactList so that the page will display a 2nd Editor Template on the page for the new empty EventContact.

I do not want to cause validation rules to fire and I do not want the user to lose their scroll position, is this possible?

0

3 Answers 3

1

You might also consider to clone the existing fields, clear the values and change the name using javascript. This will be faster as you don’t have to ask the server for a new Contact so.

Example:

<ul id="ContactsList">
 <li class="newContact">Contact Name :
     <input type="text" name="Contacts[0].Name" value="">
         Email : 
     <input type="text" name="Contacts[0].Email" value="">
 </li>
</ul>

jQuery add to your button click event something like:

var cln = $('li.newContact:first').clone();
var nextNumber = $("#ContactsList li").size();
$("input[name]", cln).each(function() {
    var nm = $(this).attr("name").replace(/\[(.+)\]/g, "[" + nextNumber + "]") ;
    $(this).prop("name", nm);
    $(this).val("");
});
cln.appendTo('#ContactsList');
Sign up to request clarification or add additional context in comments.

Comments

1

Thank you for your answers, I have spent a lot of time looking in to the possibility of using knockout or hand coding javascript to achieve the desired result, however, it felt like a lot of work for something so trivial.

I have now solved this problem in what I believe to be the most simple way possible, firstly I added a button to the form that will add a new editor template using AJAX.

@Ajax.ActionLink("Add additional contact",
                    "AddContact",
                    "Event",
                    new AjaxOptions()
                        {
                            HttpMethod = "GET",
                            InsertionMode = InsertionMode.InsertBefore,
                            UpdateTargetId = "contacts"
                        })

Next I added the AddContact actionresult to the view to return a partial view result (the edit template)

public ActionResult AddContact()
{
    return PartialView("EditorTemplates/EventContactDto", new EventContactDto());
}

Although this adds the template to the page it does not add it to the model when the form is submitted (because the ID's are not correct so it does not get added to the list).

To resolve this problem I used Steven Sandersons BeginCollectionItem Helper which can be downloaded from Nuget.

All I needed to do once the package was installed was add the following to the editor template so that it set up the ID's using MVC's conventions:

@using (Html.BeginCollectionItem("EventContactList"))
{
... the form ...
}

Now when the page is submitted the new contacts are in the model ready to be inserted into the database.

I hope this answer will help others and save them the hours that I have spent researching this!

Comments

0

Don't you just need a controller to make the insert, and an ajax handler to render the result to the page?

Without more code, it is hard to say exactly how you should do this.

You could also use knockout or backbone to "observe" the variables and update/add template HTML in place. Then you just pass in a new view model, and when you get the one back (with a primary key etc.) you render that in your view.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.