In one of my projects I needed to dynamically display fields to enter information for a collection of objects. Specifically speaking I had a POCO "User" class with FK to a POCO "Child" class. I needed a way to generate text boxes based on how many kids a user had. This involves several steps and here's what I had to do.
1. Create a partial view with the fields you need to capture the info for a "Child"
3. Create the javascript that will call the action above from another control. ex: onclick event of a link that should add the control for adding a "Child"
1. Create a partial view with the fields you need to capture the info for a "Child"
@{
var seed = ViewBag.Seed;
@{
@*MVC renders fields for a collection by appending an index, which I am setting up below*@
var ageIdText = "Children_" + seed + "__Age";
var ageNameText = "Children[" + seed + "].Age";
var genderIdText = "Children_" + seed + "__Gender";
var genderNameText = "Children[" + seed + "].Gender";
var deleteIdText = "Children_" + seed + "__Delete";
var deleteNameText = "Children[" + seed + "].Delete";
}
Remove
}
MVC renders controls for collections by attaching an index for the collection. I had to code this in to render based on the number of controls that need to be displayed. Ex: the age text field will be Children_[1]__Age and so forth. I will explain the reason for having a delete field a little later.
2. Create an action in the controller that will return the partial view
public ActionResult RenderChildren(int? id, int? seed, string viewType)
{
//if no of children to be rendered in the view was not send in the request url, then render only one child
if (id.HasValue)
ViewBag.Children = id;
else
ViewBag.Children = 1;
//if the collection index was not indicated, then start rendering the controls from 0.
//This will come in handy when there are already controls on the page and we want to add more.
if (seed.HasValue)
ViewBag.Seed = seed;
else
ViewBag.Seed = 0;
return PartialView(viewType);
}
It is important to keep track on the index for the collection, or you will get unexpected results.
3. Create the javascript that will call the action above from another control. ex: onclick event of a link that should add the control for adding a "Child"
function addChild(method,container,type) {
var noofChild = $(container).find('.mark-for-delete').length;
$.get('/account/'+method+'?seed=' + (noofChild)+"&viewtype="+type, function (template) { $(container).append(template); });
}
4. Call the javascript
Add a child
function deleteChildren(element, deleteElement) {
$container = $(element).parent();
$container.find(deleteElement).val('True');
$container.hide();
}
This will take care of dynamically rendering the required number of fields for "Child"
5. Handling the deletes - I also needed to provide the user to delete existing fields
RemoveTo handle the delete I need some more javascript code that will add some value to the hidden field that I added to my partial view. This value can then be picked up via the model while updating the database. I do have a property in the "Child" POCO class for setting the delete value. This field is not mapped to the database.
No comments:
Post a Comment