2011-04-14 4 views
19

Desidero ottenere alcune opzioni (ad esempio il metodo di pagamento in contanti, carta di credito, ecc.) E associarle ai pulsanti di opzione. Credo che non ci sia RadioButtonList in MVC 3.StrongBacked RadioButtonlist

Inoltre, una volta collegate le radio, voglio mostrare all'utente l'opzione selezionata in precedenza durante la modifica della risposta.

+0

C'è un aiutante html sul mio blog che possono aiutare a http://jonlanceley.blogspot.com/2011/06/mvc3-radiobuttonlist-helper.html – Jon

risposta

37

Come sempre si inizia con un modello:

public enum PaiementMethod 
{ 
    Cash, 
    CreditCard, 
} 

public class MyViewModel 
{ 
    public PaiementMethod PaiementMethod { get; set; } 
} 

poi un controller:

public class HomeController : Controller 
{ 
    public ActionResult Index() 
    { 
     var model = new MyViewModel(); 
     return View(model); 
    } 

    [HttpPost] 
    public ActionResult Index(MyViewModel model) 
    { 
     return View(model); 
    } 
} 

e, infine, una visione:

@model MyViewModel 
@using (Html.BeginForm()) 
{ 
    <label for="paiement_cash">Cash</label> 
    @Html.RadioButtonFor(x => x.PaiementMethod, "Cash", new { id = "paiement_cash" }) 

    <label for="paiement_cc">Credit card</label> 
    @Html.RadioButtonFor(x => x.PaiementMethod, "CreditCard", new { id = "paiement_cc" }) 

    <input type="submit" value="OK" /> 
} 

E se volete qualche soluzione più generica che incapsula questo in un aiutante potresti trovare utile il following answer.

+3

Bene grazie a Darin.Ma il mio requisito è quello di associare i pulsanti di opzione dai valori del database e assegnare la coppia Testo/Valore al pulsante di opzione in modo che possa essere assegnato alla proprietà di Model. – Vivek

+0

Ottimo lavoro! – Funky

+0

perfetto! cercavo questo da un po 'ora – bcahill

0

Si dovrebbe legare le opzioni per SelectList nel ViewModel e impostare l'attributo selezionato su true per l'opzione selezionata in precedenza

4

Questo è il modo che mi piace di legare RadioButtonLists. Il modello di vista ha una collezione di oggetti fortemente tipizzati. Ad esempio, forse PaymentOptions è una tabella di codici. Insieme alla raccolta è selezionato SelectedPaymentOptionKey (o Selected * Id se si prefissano le chiavi primarie con Id). Inizialmente questa chiave sarà predefinita 0, ma sul postback, manterrà il valore dell'elemento selezionato.

public class PaymentSelectionVM 
{ 
    public ICollection<PaymentOption> PaymentOptions { get; set; } 
    public int SelectedPaymentOptionKey { get; set; } 
} 

public ViewResult PaymentSelection() 
{ 
    var paymentOptions = db.PaymentOptions.ToList(); 
    return View(
    new PaymentSelectionVM { 
     PaymentOptions = paymentOptions, 

     //This is not required, but shows how to default the selected radiobutton 
     //Perhaps you have a relationship between a Customer and PaymentOption already, 
     //SelectedPaymentOptionKey = someCustomer.LastPaymentOptionUsed.PaymentOptionKey 
     // or maybe just grab the first one(note this would NullReferenceException on empty collection) 
     //SelectedPaymentOptionKey = paymentOptions.FirstOrDefault().PaymentOptionKey 
    }); 
} 

Poi nel Vista:

@foreach (var opt in Model.PaymentOptions) 
{   
    @*Any other HTML here that you want for displaying labels or styling*@ 
    @Html.RadioButtonFor(m => m.SelectedPaymentOptionKey, opt.PaymentOptionKey) 
} 

Il m.SelectedPaymentOptionKey serve a due scopi. Innanzitutto, raggruppa i pulsanti Radio in modo che la selezione si escluda a vicenda (ti incoraggerei a utilizzare qualcosa come FireBug per ispezionare l'html generato solo per tua comprensione. La cosa meravigliosa di MVC è che l'HTML generato è abbastanza semplice e standard quindi non dovrebbe essere difficile per te essere in grado di prevedere il comportamento dei tuoi punti di vista. C'è pochissima magia in corso qui.). In secondo luogo, manterrà il valore dell'elemento selezionato sul postback.

E infine nel gestore di posta abbiamo la SelectedPaymentOptionKey disponibili:

[HttpPost] 
public ActionResult PaymentSelection(PaymentSelectionVM vm) 
{ 
    currentOrder.PaymentOption = db.PaymentOptions.Find(vm.SelectedPaymentOptionKey); 
    .... 
} 

Il vantaggio di questo rispetto all'utilizzo di SelectListItems è si ha accesso a più di proprietà dell'oggetto, nel caso che si sta visualizzando una griglia/tabella e devono visualizzare molti valori dell'oggetto. Mi piace anche che non ci siano stringhe codificate che vengono passate negli helper Html come hanno fatto altri approcci.

Lo svantaggio è che si ottengono i pulsanti di opzione che hanno tutti lo stesso ID, il che non è una buona pratica. Questo è facilmente risolto modificando a questo:

@Html.RadioButtonFor(m => m.SelectedPaymentOptionKey, opt.PaymentOptionKey, new { id = "PaymentOptions_" + opt.PaymentOptionKey}) 

Infine, la convalida è un po 'eccentrico con la maggior parte tutte le tecniche del pulsante di scelta che ho visto. Se ne avessi davvero bisogno, collegherei qualche jquery per compilare una SelectedPaymentOptionsKey nascosta ogni volta che si fa clic sui pulsanti di opzione e posizionare lo [Required] o altra convalida sul campo nascosto.

Un'altra soluzione per il problema di convalida ASP.NET MVC 3 unobtrusive validation and radio buttons

Questo sembra promettente, ma non ho avuto la possibilità di testarlo: http://memoriesdotnet.blogspot.com/2011/11/mvc-3-radiobuttonlist-including.html