2013-08-30 15 views
42

Widziałem kilka wątków na ten temat, ale żaden nie wydaje się dotyczyć MVC4, ponieważ metoda/helper rozszerzenia RFButtonFor nie istnieje.Wyliczenie MVC4 i listy przycisków radiowych

że mam listy enum - tj Airlines:

public enum Airlines 
{ 
    Unknown = 0, 
    BritishAirways = 1, 
    VirginAtlantic = 2, 
    AirFrance = 3 
} 

Jak mogę powiązać to do listy przycisk radiowy na mój widok i być w stanie odzyskać wybrany element? Co powiesz na możliwość wyboru "wybierz jeden przedmiot", jeśli nie dokonano wyboru?

Odpowiedz

15

Co masz na myśli przez RadioButtonFor nie istnieje? Używam MVC4 i używam tego w moim kodzie. Na liście można ustawić wiele do tej samej nazwie

@Html.RadioButtonFor(x => x.Airlines, Airlines.Unknown) 
@Html.RadioButtonFor(x => x.Airlines, Airlines.BritishAirways) 
@Html.RadioButtonFor(x => x.Airlines, Airlines.VirginAtlantic) 
@Html.RadioButtonFor(x => x.Airlines, Airlines.AirFrance) 

będą one powiązane z modelem więc na odświeżenie strony widać Airlines ustawiony na wybranej pozycji i podczas ładowania strony zostanie wybrany przycisk radiowy dopasowanie.

+0

myślę Ahmed oznaczało, że 'RadioButtonFor' nie istniał * przed * do MVC4 i że przykłady he stwierdził, że nie użył metody pomocnika. –

+0

Jak dodać etykiety z prawidłowym zestawem atrybutów "for"? –

+0

Nie jestem pewien, czy podążam. Zwykle z taką listą mam tylko 1 etykietę na górze, mówiąc: wybierz najlepszy ... –

40

Można utworzyć niestandardowy szablon edytora dla enum Airlines, który będzie renderować listę przycisków radiowych. W modelu masz właściwość typu Airlines i oznacz tę właściwość atrybutem Required i ustaw ErrorMessage = "select one item". Nie zapomnij dołączyć walidacji jQuery do sprawdzania poprawności strony klienta, jeśli chcesz, zazwyczaj wystarczy dodać @Scripts.Render("~/bundles/jqueryval") do swojego układu lub widoku. Jeśli nie używasz sprawdzania poprawności jQuery, musisz uczynić właściwość zerowalną w modelu, ponieważ wartości domyślne są domyślnie ustawione na pierwszą wartość, więc MVC nie uzna go za nieprawidłowy. Pamiętaj, że jeśli zmienisz właściwość na zerowalną, będziesz musiał zmienić również typ modelu swojego szablonu edytora, tak aby był również zerowalny.

UPDATE

Aby włączyć edytora szablonów do renderowania listę przycisk radiowy dla każdego wyliczenia, zmienić szablon do poniższego:

@model Enum 
@foreach (var value in Enum.GetValues(Model.GetType())) 
{ 
    @Html.RadioButtonFor(m => m, value) 
    @Html.Label(value.ToString()) 
} 

ORIGINAL

szablonu edytora , Airlines.cshtml, w widokach \ Shared \ EditorTemplates katalogu:

@model MvcTest.Models.Airlines 
@foreach (var value in Enum.GetValues(typeof(MvcTest.Models.Airlines))) 
{ 
    @Html.RadioButtonFor(m => m, value) 
    @Html.Label(value.ToString()) 
} 

Model:

public class TestModel 
{ 
    [Required(ErrorMessage = "select one item")] 
    public Airlines Airline { get; set; } 
} 

Metody działania:

public class HomeController : Controller 
{ 
    [HttpGet] 
    public ActionResult Index() 
    { 
     return View(new TestModel()); 
    } 

    [HttpPost] 
    public ActionResult Index(TestModel model) 
    { 
     if (ModelState.IsValid) 
     { 
      return RedirectToAction("Index"); 
     } 

     return View(model); 
    } 
} 

Widok:

@model MvcTest.Models.TestModel 
@{ 
    ViewBag.Title = "Index"; 
    Layout = "~/Views/Shared/_Layout.cshtml"; 
} 
<h2>Index</h2> 
@using (Html.BeginForm()) 
{ 
    @Html.EditorFor(m => m.Airline) 
    <input type="submit" value="Submit" /> 
    @Html.ValidationSummary(false) 
} 
+0

Dziękujemy! Spróbuję tego i wkrótce się z tobą skontaktuję. Co powinienem zrobić, jeśli nie chcę, aby pewne wyliczenie było widoczne na liście? Powiedzmy, że wszystkie wyliczenia, z którymi mam do czynienia, będą miały "Nieznane". w jaki sposób mogę się upewnić, że nie zostanie on renderowany, ale także upewniając się, że wybrano wartość na liście? –

+1

OK, próbując tego nie działa dla mnie. Nie dostaję listy przycisków radiowych, ale zamiast tego tylko pole tekstowe. jak mogę zrobić częściowy widok może i dać mu wyliczenie i mieć ten częściowy widok wziąć enum i ogólnie wypluć przyciski opcji dla każdego elementu w wyliczeniach, ale także mający odświeżenie/przesłanie powiązać wybraną wartość z modelem widoku? –

+0

Jeśli chcesz zachować pewną wartość z listy, po prostu umieść w pętli instrukcję "if" i sprawdź ją. Tworzenie widoku częściowego zamiast szablonu edytora powinno być dość łatwe, różnica jest po prostu semantyką, ponieważ szablony edytora są częściowymi widokami. Po prostu utwórz częściowy widok w dowolnym katalogu * view \ controller *, ale umieszczenie go w katalogu współdzielonym może mieć więcej sensu, a następnie skopiuj kod z szablonu edytora do niego. Następnie użyj '@ Html.Partial (" partialViewName ", model)' i przekaż wyliczenie z głównego modelu widoku jako model. – asymptoticFault

28

Proponuję podobne podejście do innych odpowiedzi , ale z następującymi szablon edytora; EnumRadioButtonList.cshtml, w Wyświetleń \ Shared \ EditorTemplates katalogu:

@model Enum 
@foreach (var value in Enum.GetValues(Model.GetType())) 
{ 
    var id = TagBuilder.CreateSanitizedId(string.Format(
     "{0}_{1}_{2}", ViewData.TemplateInfo.HtmlFieldPrefix, Model.GetType(), value)); 
    <div> 
     @Html.RadioButton(string.Empty, value, value.Equals(Model), new { id }) 
     @Html.Label(value.ToString(), new { @for = id }) 
    </div> 
} 

HTML id każdego przycisku radiowego musi być unikalna.Dlatego powyższy kod przedrostka id z nazwą powiązanej właściwości za pomocą przy użyciu ViewData.TemplateInfo.HtmlFieldPrefix. Zapewnia to unikalne s, jeśli model zawierał wiele właściwości, które używały tego wyliczenia, i jeśli ten szablon edytora był używany dla każdego z nich.

Towarzyszące label dla każdego przycisku radiowego będzie mieć prawidłowo ustawiony atrybut for. Oznacza to, że użytkownik może wybrać przycisk opcji, klikając tekst etykiety, o wiele większy i lepszy cel kliknięcia niż sam przycisk opcji.

Dla modelu MVC wiążących, przyciski radiowe będą miały ich HTML name wartość nieruchomości ustawiony, że nieruchomości, który został określony w EditorFor rozmowy (Airline w tym scenariuszu).

Aby go użyć:

@Html.EditorFor(m => m.Airline, "EnumRadioButtonList") 
+1

Podoba mi się to podejście, działa na leczeniu – sacha

+0

To rozwiązanie doskonale nadaje się do edycji strony. Jednak na stronie Utwórz, w której nie ma jeszcze zaznaczonego elementu dla przycisku wyliczającego, otrzymuję komunikat "Odwołanie do obiektu nie jest ustawione na instancję obiektu". Wszelkie prace nad tym problemem? – corix010

+1

Podejrzewam, że "Model", który przechodzisz, to 'null' ... –

2

poprawiłem najwyższą ocenę odpowiedzi przez asymptoticfault trochę odzwierciedla wybranych wartości zbyt. Zapisz jako EnumRadioButton.cshtml do udostępnionego folderu poglądów EditorTemplates:

@model Enum 
@foreach (var value in Enum.GetValues(Model.GetType())) 
{ 
    if (Equals(Model, value)) 
    { 
     @Html.RadioButtonFor(m => m, value, new {@checked = "checked"}) 
    } 
    else 
    { 
     @Html.RadioButtonFor(m => m, value) 
    } 

    @Html.Label(value.ToString()) 
} 

Zastosowanie:

@Html.EditorFor(item => Model.MyEnumType, "EnumRadioButton") 
Powiązane problemy