Created
April 15, 2011 04:24
-
-
Save jsonw23/921135 to your computer and use it in GitHub Desktop.
Example Contact Form to illustrate tricky model binding situations in ASP.NET MVC 3
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Collections.Generic; | |
namespace GeekJ.Examples.ContactForm.Models | |
{ | |
public class Contact | |
{ | |
public string FirstName { get; set; } | |
public string LastName { get; set; } | |
public string Email { get; set; } | |
private IList<Phone> _phoneNumbers; | |
public IList<Phone> PhoneNumbers | |
{ | |
get | |
{ | |
if (_phoneNumbers == null) | |
_phoneNumbers = new List<Phone>(); | |
return _phoneNumbers; | |
} | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Web.Mvc; | |
using GeekJ.Examples.ContactForm.Models; | |
namespace GeekJ.Examples.ContactForm.Controllers | |
{ | |
public class ContactController : Controller | |
{ | |
public ActionResult Index() | |
{ | |
return View(); | |
} | |
public ActionResult New(Contact newContact) | |
{ | |
if (Request.HttpMethod == "POST") | |
{ | |
} | |
return View(new Contact()); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@using GeekJ.Examples.ContactForm.Models | |
@model GeekJ.Examples.ContactForm.Models.Contact | |
@{ | |
ViewBag.Title = "New Contact"; | |
for (int i = 0; i < 5; i++) | |
{ | |
Model.PhoneNumbers.Add(new Phone()); | |
} | |
} | |
<h2>New</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>Contact</legend> | |
<div class="editor-label"> | |
@Html.LabelFor(model => model.FirstName) | |
</div> | |
<div class="editor-field"> | |
@Html.EditorFor(model => model.FirstName) | |
@Html.ValidationMessageFor(model => model.FirstName) | |
</div> | |
<div class="editor-label"> | |
@Html.LabelFor(model => model.LastName) | |
</div> | |
<div class="editor-field"> | |
@Html.EditorFor(model => model.LastName) | |
@Html.ValidationMessageFor(model => model.LastName) | |
</div> | |
<div class="editor-label"> | |
@Html.LabelFor(model => model.Email) | |
</div> | |
<div class="editor-field"> | |
@Html.EditorFor(model => model.Email) | |
@Html.ValidationMessageFor(model => model.Email) | |
</div> | |
<div class="editor-label"> | |
@Html.LabelFor(model => model.PhoneNumbers) | |
</div> | |
<div class="editor-field"> | |
@for (int i = 0; i < Model.PhoneNumbers.Count(); i++) { | |
@Html.DropDownListFor(model => model.PhoneNumbers[i].Type, new SelectList(new string[] { | |
"Home", "Work", "Mobile", "Fax" | |
})) | |
@Html.TextBoxFor(model => model.PhoneNumbers[i].Number) | |
<br /> | |
} | |
</div> | |
<p> | |
<input type="submit" value="Create" /> | |
</p> | |
</fieldset> | |
} | |
<div> | |
@Html.ActionLink("Back to List", "Index") | |
</div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@using GeekJ.Examples.ContactForm.Models | |
@model GeekJ.Examples.ContactForm.Models.Contact | |
@{ | |
ViewBag.Title = "New Contact"; | |
} | |
<h2>New</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> | |
<script src="@Url.Content("~/Scripts/jQuery.tmpl.min.js")" type="text/javascript"></script> | |
<script src="@Url.Content("~/Scripts/jquery.datalink.js")" type="text/javascript"></script> | |
<script type="text/javascript"> | |
var contact = { | |
PhoneNumbers: [ | |
{ Type: "", Number: "" } | |
] | |
} | |
$(function () { | |
$("#phoneNumberTemplate").tmpl(contact).appendTo("#phoneNumbersContainer") | |
link(); | |
$("#phoneNumbersContainer input").live("change", function () { | |
var used = 0; | |
for (var i = 0; i < contact.PhoneNumbers.length; i++) { | |
if (contact.PhoneNumbers[i].Number != "") { | |
used++; | |
} | |
} | |
if (used == $("#phoneNumbersContainer :text").length) { | |
contact.PhoneNumbers.push({ Type: "", Number: "" }); | |
$("#phoneNumbersContainer").empty(); | |
$("#phoneNumberTemplate").tmpl(contact).appendTo("#phoneNumbersContainer") | |
link(); | |
} | |
}); | |
$("form").submit(function () { | |
for (var i = 0; i < contact.PhoneNumbers.length; i++) { | |
if (contact.PhoneNumbers[i].Number == "") { | |
$(".phoneNumber:eq(" + i + ")").remove(); | |
} | |
} | |
}); | |
}); | |
function link() { | |
$("div.phoneNumber").each(function (i) { | |
$(this).link(contact.PhoneNumbers[i], { | |
Type: { | |
name: "_Type", | |
convert: function (value, source, target) { | |
$(":hidden[name$=Type]", $(source).parent()).val(value); | |
return value; | |
} | |
}, | |
Number: { | |
name: "_Number", | |
convert: function (value, source, target) { | |
$(":hidden[name$=Number]", $(source).parent()).val(value); | |
return value; | |
} | |
} | |
}); | |
}); | |
} | |
</script> | |
<script id="phoneNumberTemplate" type="text/x-jquery-tmpl"> | |
{{each PhoneNumbers}} | |
<div class="phoneNumber"> | |
@Html.Hidden("PhoneNumbers[${$index}].Type", "${$value.Type}") | |
@Html.DropDownList("_Type", new SelectList(new string[] { | |
"Home", "Work", "Mobile", "Fax" | |
}), "${$value.Type}") | |
@Html.Hidden("PhoneNumbers[${$index}].Number", "${$value.Number}") | |
@Html.TextBox("_Number", "${$value.Number}") | |
</div> | |
{{/each}} | |
</script> | |
@using (Html.BeginForm()) { | |
@Html.ValidationSummary(true) | |
<fieldset> | |
<legend>Contact</legend> | |
<div class="editor-label"> | |
@Html.LabelFor(model => model.FirstName) | |
</div> | |
<div class="editor-field"> | |
@Html.EditorFor(model => model.FirstName) | |
@Html.ValidationMessageFor(model => model.FirstName) | |
</div> | |
<div class="editor-label"> | |
@Html.LabelFor(model => model.LastName) | |
</div> | |
<div class="editor-field"> | |
@Html.EditorFor(model => model.LastName) | |
@Html.ValidationMessageFor(model => model.LastName) | |
</div> | |
<div class="editor-label"> | |
@Html.LabelFor(model => model.Email) | |
</div> | |
<div class="editor-field"> | |
@Html.EditorFor(model => model.Email) | |
@Html.ValidationMessageFor(model => model.Email) | |
</div> | |
<div class="editor-label"> | |
@Html.LabelFor(model => model.PhoneNumbers) | |
</div> | |
<div class="editor-field"> | |
<div id="phoneNumbersContainer"></div> | |
</div> | |
<p> | |
<input type="submit" value="Create" /> | |
</p> | |
</fieldset> | |
} | |
<div> | |
@Html.ActionLink("Back to List", "Index") | |
</div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@using GeekJ.Examples.ContactForm.Models | |
@model GeekJ.Examples.ContactForm.Models.Contact | |
@{ | |
ViewBag.Title = "New Contact"; | |
for (int i = 0; i < 5; i++) | |
{ | |
Model.PhoneNumbers.Add(new Phone()); | |
} | |
} | |
<h2>New</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>Contact</legend> | |
<div class="editor-label"> | |
@Html.LabelFor(model => model.FirstName) | |
</div> | |
<div class="editor-field"> | |
@Html.EditorFor(model => model.FirstName) | |
@Html.ValidationMessageFor(model => model.FirstName) | |
</div> | |
<div class="editor-label"> | |
@Html.LabelFor(model => model.LastName) | |
</div> | |
<div class="editor-field"> | |
@Html.EditorFor(model => model.LastName) | |
@Html.ValidationMessageFor(model => model.LastName) | |
</div> | |
<div class="editor-label"> | |
@Html.LabelFor(model => model.Email) | |
</div> | |
<div class="editor-field"> | |
@Html.EditorFor(model => model.Email) | |
@Html.ValidationMessageFor(model => model.Email) | |
</div> | |
<p> | |
<input type="submit" value="Create" /> | |
</p> | |
</fieldset> | |
} | |
<div> | |
@Html.ActionLink("Back to List", "Index") | |
</div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace GeekJ.Examples.ContactForm.Models | |
{ | |
public class Phone | |
{ | |
public string Type { get; set; } | |
public string Number { get; set; } | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment