Reputation: 5900
Pretty new to MVC and the like. I have a class the looks like this:
public class SomeExampleModel
{
public int Id { get; private set; }
public string Name { get; private set;}
public string Street { get; private set; }
public IList<Contact> Contacts { get; private set; }
...
}
Where Contact
looks like:
public class Contact
{
public int Id { get; private set; }
public int SomeExampleModelId { get; private set; }
public ContactType Type { get; private set; }
public string ContactValue { get; private set; }
...
}
Now the problem is, I have a Post Create
action and Create.cshtml view to add new SomeExampleModel
to my database. It works great for all the basic properties, but there isn't anything for the Contacts property (which is a separate table in the database).
How would I be able to add contacts (single for now, plural in the future) using forms on my view?
EDIT: I am sorry if I was not clear. The problem is not getting data to save in the database correctly. I have tested that already and it works fine if I just manually insert a SomeExampleModel record into the database with the SomeExampleContext. What I dont know is how to draft my View so that it allows users to add Contacts to the record
Upvotes: 0
Views: 223
Reputation: 4361
Here is one approach using an EditorTemplate
. I have made minor changes to your model classes (this works; however, note that this is only for you to understand the concept. You can extend upon this)
Models
public class SomeExampleModel
{
public int Id { get; set; }
public string Name { get; set;}
public string Street { get; set; }
public IList<Contact> Contacts { get; set; }
}
public class Contact
{
public int Id { get; set; }
public int SomeExampleModelId { get; set; }
public ContactType Type { get; set; }
public string ContactText { get { return Type.ToString(); } }
public string ContactValue { get; set; }
}
public enum ContactType
{
email,
Phone,
mobile,
fax
}
Make a note that I've created a property ContactText
that returns the enum text (for display purposes)
Create a editor template for Contact (named Contact.cshtml
; Template name must match the class name). Find below the screen shot on where to place your editor template.
Here is the code for Contact.cshtml
@model Test1.Models.Contact
<table>
@Html.HiddenFor(a=>a.Type)
<tr>
<td>@Html.Label(Model.ContactText)</td>
<td>@Html.TextBoxFor(a => a.ContactValue)</td>
</tr>
</table>
Here is the code for the 'Create' view (ExampleCreateView.cshtml
in my case)
@model Test1.Models.SomeExampleModel
@{
ViewBag.Title = "ExampleCreateView";
}
<h2>ExampleCreateView</h2>
<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
@using (Html.BeginForm()) {
@Html.ValidationSummary(true)
<fieldset>
<legend>SomeExampleModel</legend>
@Html.HiddenFor(model=>model.Id)
<table>
<tr>
<td>@Html.LabelFor(model=>model.Name)</td>
<td>@Html.EditorFor(model=>model.Name)</td>
</tr>
<tr>
<td>@Html.LabelFor(model=>model.Street)</td>
<td>@Html.EditorFor(model=>model.Street)</td>
</tr>
<tr>
<td>@Html.LabelFor(model=>model.Contacts)</td>
<td>@Html.EditorFor(model=>model.Contacts)</td>
</tr>
</table>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>
Make a note on how I've used @Html.EditorFor
for the Contacts
property.
Here is how the Get, Post actions will look like
public ActionResult ExampleCreateView()
{
SomeExampleModel model = new SomeExampleModel();
Contact contactEmail = new Contact();
contactEmail.Type = ContactType.email;
Contact contactFax = new Contact();
contactFax.Type = ContactType.fax;
Contact contactPhone = new Contact();
contactPhone.Type = ContactType.Phone;
Contact contactMobile = new Contact();
contactMobile.Type = ContactType.mobile;
List<Contact> contacts = new List<Contact>();
contacts.Add(contactEmail);
contacts.Add(contactFax);
contacts.Add(contactPhone);
contacts.Add(contactMobile);
model.Contacts = contacts;
return View(model);
}
[HttpPost]
public ActionResult ExampleCreateView(SomeExampleModel model)
{
//Your operations
return View(model);
}
Run the application. This is how the view looks like
Screen shot of what you will get in the POST action
Upvotes: 1
Reputation: 4770
The way I would do it is to have two separate actions - one that does the initial create of SomeExampleModel
, and a separate action for adding a Contact
to that model.
That way your create SomeExampleModel
view would just have Name and street, and when it saved you would show a readonly version of the SomeExampleModel
. The readonly version of SomeExampleModel
would list all related contacts in a table below the Name and Street, with an edit and delete link, and an 'add new' contact link under the table
e.g.
<table>
@foreach (var contact in Model.Contacts)
{
<tr>
<td>@contact.ContactType</td>
<td>@contact.ContactValue</td>
<td>@Html.Action("Edit", "Edit", "Contact", new { id = contact.Id }</td>
<td>@Html.Action("Delete", "Delete", "Contact", { id = contact.Id }</td>
</tr>
}
</table>
@Html.Action("Add new contact", "Add", "Contact" new { id = Model.Id }
Initially, there would be no contacts listed, then later you would have multiple contacts.
Upvotes: 0