Je suis plutôt nouveau dans le monde ASP.net MVC et j'essaie de comprendre comment rendre un groupe de cases à cocher fortement typées dans un modèle de vue. Dans les formulaires Web, je voudrais simplement utiliser le contrôle checkboxlist mais je suis un peu perdu avec MVC.
Je construis un simple formulaire de contact pour une entreprise de planification de mariage et je dois transmettre les valeurs de case à cocher que l'utilisateur sélectionne à mon contrôleur.
Les cases à cocher du formulaire doivent ressembler à ceci:
Votre aide serait grandement appréciée. Merci!
Voici ce que j'ai jusqu'à présent.
MANETTE
[HttpPost]
public ActionResult Contact(ContactViewModel ContactVM)
{
if (!ModelState.IsValid)
{
return View(ContactVM);
}
else
{
//Send email logic
return RedirectToAction("ContactConfirm");
}
}
VOIR MODÈLE
public class ContactViewModel
{
[Required]
public string Name { get; set; }
[Required]
public string Phone { get; set; }
[Required]
[DataType(DataType.EmailAddress)]
public string Email { get; set; }
[Required]
public string Subject { get; set; }
public IEnumerable<SelectListItem> SubjectValues
{
get
{
return new[]
{
new SelectListItem { Value = "General Inquiry", Text = "General Inquiry" },
new SelectListItem { Value = "Full Wedding Package", Text = "Full Wedding Package" },
new SelectListItem { Value = "Day of Wedding", Text = "Day of Wedding" },
new SelectListItem { Value = "Hourly Consultation", Text = "Hourly Consultation" }
};
}
}
//Not sure what I should do for checkboxes...
}
VUE
@model NBP.ViewModels.ContactViewModel
@{
ViewBag.Title = "Contact";
Layout = "~/Views/Shared/_Layout.cshtml";
}
@using (Html.BeginForm())
{
<div id="ContactContainer">
<div><span class="RequiredField">* </span>Your Name:</div>
<div>
@Html.TextBoxFor(model => model.Name)
</div>
<div><span class="RequiredField">* </span>Your Phone:</div>
<div>
@Html.TextBoxFor(model => model.Phone)
</div>
<div><span class="RequiredField">* </span>Your Email:</div>
<div>
@Html.TextBoxFor(model => model.Email)
</div>
<div>Subject:</div>
<div>
@Html.DropDownListFor(model => model.Subject, Model.SubjectValues)
</div>
<div>Vendor Assistance:</div>
<div>
<!-- CHECKBOXES HERE -->
</div>
<div>
<input id="btnSubmit" type="submit" value="Submit" />
</div>
</div>
}
Vous pouvez enrichir votre modèle de vue:
public class VendorAssistanceViewModel
{
public string Name { get; set; }
public bool Checked { get; set; }
}
public class ContactViewModel
{
public ContactViewModel()
{
VendorAssistances = new[]
{
new VendorAssistanceViewModel { Name = "DJ/BAND" },
new VendorAssistanceViewModel { Name = "Officiant" },
new VendorAssistanceViewModel { Name = "Florist" },
new VendorAssistanceViewModel { Name = "Photographer" },
new VendorAssistanceViewModel { Name = "Videographer" },
new VendorAssistanceViewModel { Name = "Transportation" },
}.ToList();
}
[Required]
public string Name { get; set; }
[Required]
public string Phone { get; set; }
[Required]
[DataType(DataType.EmailAddress)]
public string Email { get; set; }
[Required]
public string Subject { get; set; }
public IEnumerable<SelectListItem> SubjectValues
{
get
{
return new[]
{
new SelectListItem { Value = "General Inquiry", Text = "General Inquiry" },
new SelectListItem { Value = "Full Wedding Package", Text = "Full Wedding Package" },
new SelectListItem { Value = "Day of Wedding", Text = "Day of Wedding" },
new SelectListItem { Value = "Hourly Consultation", Text = "Hourly Consultation" }
};
}
}
public IList<VendorAssistanceViewModel> VendorAssistances { get; set; }
}
Manette:
public class HomeController : Controller
{
public ActionResult Index()
{
return View(new ContactViewModel());
}
[HttpPost]
public ActionResult Index(ContactViewModel model)
{
if (!ModelState.IsValid)
{
return View(model);
}
//Send email logic
return RedirectToAction("ContactConfirm");
}
}
Vue:
@using (Html.BeginForm())
{
<div id="ContactContainer">
<div><span class="RequiredField">* </span>Your Name:</div>
<div>
@Html.TextBoxFor(model => model.Name)
</div>
<div><span class="RequiredField">* </span>Your Phone:</div>
<div>
@Html.TextBoxFor(model => model.Phone)
</div>
<div><span class="RequiredField">* </span>Your Email:</div>
<div>
@Html.TextBoxFor(model => model.Email)
</div>
<div>Subject:</div>
<div>
@Html.DropDownListFor(model => model.Subject, Model.SubjectValues)
</div>
<div>Vendor Assistance:</div>
<div>
@for (int i = 0; i < Model.VendorAssistances.Count; i++)
{
<div>
@Html.HiddenFor(x => x.VendorAssistances[i].Name)
@Html.CheckBoxFor(x => x.VendorAssistances[i].Checked)
@Html.LabelFor(x => x.VendorAssistances[i].Checked, Model.VendorAssistances[i].Name)
</div>
}
</div>
<div>
<input id="btnSubmit" type="submit" value="Submit" />
</div>
</div>
}
Utilisez un tableau de chaînes dans votre modèle de vue. Vous pouvez ensuite utiliser l'aide que j'ai piraté ensemble. si vous ne voulez pas utiliser l'auxiliaire et l'énum, voyez le code HTML au bas. Le classeur renverra un tableau de chaînes contenant uniquement les valeurs de chaîne sélectionnées. si aucun n'est sélectionné, il retourne une valeur nulle pour votre tableau. Vous devez en rendre compte, vous avez été prévenu :)
Voir le modèle:
[Display(Name = "Which Credit Cards are Accepted:")]
public string[] CreditCards { get; set; }
Assistant:
public static HtmlString CheckboxGroup<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> propertySelector, Type EnumType)
{
var groupName = GetPropertyName(propertySelector);
var modelValues = ModelMetadata.FromLambdaExpression(propertySelector, htmlHelper.ViewData).Model;//propertySelector.Compile().Invoke(htmlHelper.ViewData.Model);
StringBuilder literal = new StringBuilder();
foreach (var value in Enum.GetValues(EnumType))
{
var svalue = value.ToString();
var builder = new TagBuilder("input");
builder.GenerateId(groupName);
builder.Attributes.Add("type", "checkbox");
builder.Attributes.Add("name", groupName);
builder.Attributes.Add("value", svalue);
var contextValues = HttpContext.Current.Request.Form.GetValues(groupName);
if ((contextValues != null && contextValues.Contains(svalue)) || (modelValues != null && modelValues.ToString().Contains(svalue)))
{
builder.Attributes.Add("checked", null);
}
literal.Append(String.Format("</br>{1} <span>{0}</span>", svalue.Replace('_', ' '),builder.ToString(TagRenderMode.Normal)));
}
return (HtmlString)htmlHelper.Raw(literal.ToString());
}
private static string GetPropertyName<T, TProperty>(Expression<Func<T, TProperty>> propertySelector)
{
var body = propertySelector.Body.ToString();
var firstIndex = body.IndexOf('.') + 1;
return body.Substring(firstIndex);
}
HTML:
@Html.CheckboxGroup(m => m.CreditCards, typeof(VendorCertification.Enums.CreditCardTypes))
Utilisez ceci si les extensions d'assistance vous effraient:
<input id="CreditCards" name="CreditCards" type="checkbox" value="Visa"
@(Model.CreditCards != null && Model.CreditCards.Contains("Visa") ? "checked=true" : string.Empty)/>
<span>Visa</span><br />
<input id="CreditCards" name="CreditCards" type="checkbox" value="MasterCard"
@(Model.CreditCards != null && Model.CreditCards.Contains("MasterCard") ? "checked=true" : string.Empty)/>
<span>MasterCard</span><br />