ASP.NET MVC Ja / Nein-Optionsfelder mit stark gebundenem Modell MVC

132

Weiß jemand, wie man ein Ja / Nein-Optionsfeld an eine boolesche Eigenschaft eines stark typisierten Modells in ASP.NET MVC bindet?

Modell

public class MyClass
{
     public bool Blah { get; set; }
}

Aussicht

<%@  Page Title="blah"  Inherits="MyClass"%>
    <dd>
        <%= Html.RadioButton("blah", Model.blah) %> Yes
        <%= Html.RadioButton("blah", Model.blah) %> No
    </dd>

Vielen Dank

LÖSUNG:

Vielen Dank für Brian für die Regie, aber es war das Gegenteil von dem, was er geschrieben hat. Wie so -

<%@  Page Title="blah"  Inherits="MyClass"%>
<dd>
    <%= Html.RadioButton("blah", !Model.blah) %> Yes
    <%= Html.RadioButton("blah", Model.blah) %> No
</dd>
Brianstewey
quelle
4
Das "Problem" bei diesen Lösungen (und ich verwende den Ben Cull-Stil in meinem Projekt) ist, dass Sie mit ihnen keine Etiketten erstellen können. Beide Optionsfeldeingänge haben dieselbe ID und denselben Namen. Wenn Sie also Html.LabelFor verwenden, wird eine Verknüpfung zum ersten Optionsfeldeingang im DOM mit dieser ID hergestellt. Wie gesagt, ich verwende diese Lösungen für Optionsfelder, um ein boolesches Feld darzustellen. Ich wollte nur, dass die Leute wissen, dass Labels ein bisschen wackelig sind.
Gromer
2
In Jeff Bobishs Antwort erfahren Sie, wie Sie das Label-Problem elegant beheben können.
René

Antworten:

74

Der zweite Parameter ist ausgewählt, verwenden Sie also das! um den Wert no auszuwählen, wenn der Boolesche Wert falsch ist.

<%= Html.RadioButton("blah", !Model.blah) %> Yes 
<%= Html.RadioButton("blah", Model.blah) %> No 
Brian Mains
quelle
198

Wenn Sie MVC 3 und Razor verwenden, können Sie auch Folgendes verwenden:

@Html.RadioButtonFor(model => model.blah, true) Yes
@Html.RadioButtonFor(model => model.blah, false) No
Ben Cull
quelle
56

Hier ist ein vollständigeres Beispiel, bei dem fieldsetaus Gründen der Barrierefreiheit a verwendet wird und die erste Schaltfläche als Standard angegeben wird. Ohne a fieldsetkann nicht programmgesteuert bestimmt werden, wofür die Optionsfelder insgesamt bestimmt sind.

Modell

public class MyModel
{
    public bool IsMarried { get; set; }
}

Aussicht

<fieldset>
    <legend>Married</legend>

    @Html.RadioButtonFor(e => e.IsMarried, true, new { id = "married-true" })
    @Html.Label("married-true", "Yes")

    @Html.RadioButtonFor(e => e.IsMarried, false, new { id = "married-false" })
    @Html.Label("married-false", "No")
</fieldset>

Sie können @checkeddem anonymen Objekt ein Argument hinzufügen , um das Optionsfeld als Standard festzulegen:

new { id = "married-true", @checked = 'checked' }

Beachten Sie, dass Sie an eine Zeichenfolge binden können, indem Sie trueund falsedurch die Zeichenfolgenwerte ersetzen .

Daniel Imms
quelle
Sie sollten tatsächlich new {id = Html.Id ("ried-true ")} verwenden, um potenzielle Probleme mit dem Bereich generierter ID-Präfixe zu reduzieren.
Eoleary
26

Aufbauend auf Bens Antwort fügte ich Attribute für die ID hinzu, damit ich Beschriftungen verwenden konnte.

<%: Html.Label("isBlahYes", "Yes")%><%= Html.RadioButtonFor(model => model.blah, true, new { @id = "isBlahYes" })%>
<%: Html.Label("isBlahNo", "No")%><%= Html.RadioButtonFor(model => model.blah, false, new { @id = "isBlahNo" })%>

Ich hoffe das hilft.

ctc
quelle
7
Normalerweise steht das Etikett nach einem Optionsfeld.
Daniel Imms
6
Das Anbringen eines Etiketts um ein Optionsfeld ist vollkommen gültig.
Scott Baker
23

Durch Hinzufügen von Beschriftungs-Tags um die Optionsfelder mithilfe von normalem HTML wird auch das Problem "Beschriftung für" behoben:

<label><%= Html.RadioButton("blah", !Model.blah) %> Yes</label>
<label><%= Html.RadioButton("blah", Model.blah) %> No</label>

Durch Klicken auf den Text wird nun das entsprechende Optionsfeld ausgewählt.

Jeff Bobish
quelle
8

oder MVC 2.0:

<%= Html.RadioButtonFor(model => model.blah, true) %> Yes
<%= Html.RadioButtonFor(model => model.blah, false) %> No
Stafford Williams
quelle
5

Wenn ich meinen Hut in den Ring werfen kann, gibt es meiner Meinung nach einen saubereren Weg als die vorhandenen Antworten, um die Optionsfeldfunktion wiederzuverwenden.

Angenommen, Sie haben die folgende Eigenschaft in Ihrem ViewModel :

Public Class ViewModel
    <Display(Name:="Do you like Cats?")>
    Public Property LikesCats As Boolean
End Class

Sie können diese Eigenschaft über eine wiederverwendbare Editorvorlage verfügbar machen :

Erstellen Sie zunächst die Datei Views/Shared/EditorTemplates/YesNoRadio.vbhtml

Fügen Sie dann den folgenden Code zu YesNoRadio.vbhtml hinzu :

@ModelType Boolean?

<fieldset>
    <legend>
        @Html.LabelFor(Function(model) model)
    </legend>

    <label>
        @Html.RadioButtonFor(Function(model) model, True) Yes
    </label>
    <label>
        @Html.RadioButtonFor(Function(model) model, False) No
    </label>
</fieldset>

Sie können den Editor für die Eigenschaft aufrufen, indem Sie den Vorlagennamen in Ihrer Ansicht manuell angeben :

@Html.EditorFor(Function(model) model.LikesCats, "YesNoRadio")

Vorteile:

  • Schreiben Sie HTML in einem HTML-Editor, anstatt Zeichenfolgen im Code dahinter anzuhängen.
  • Erhält die DisplayName DataAnnotation
  • Ermöglicht das Umschalten des Optionsfelds durch Klicken auf Beschriftung
  • Am wenigsten möglicher Code, um in Form zu bleiben (1 Zeile). Wenn etwas mit der Art und Weise, wie es gerendert wird, nicht stimmt, nehmen Sie es mit der Vorlage auf.
KyleMit
quelle
Das ist gut, aber was ist mit einer dritten Option für Boolean? @ Html.RadioButtonFor (Funktion (Modell) Model.IsVerified, True) <span> Ja </ span> @ Html.RadioButtonFor (Funktion (Modell) Model.IsVerified, False) <span> Nein </ span> @ Html.RadioButtonFor (Funktion (Modell) Model.IsVerified, Nothing)) <span> Ausstehend </ span>
JoshYates1980
1

Am Ende habe ich dies in eine Erweiterungsmethode verpackt, damit (1) ich das Etikett und das Radio gleichzeitig generieren konnte und (2) ich mich nicht mit der Angabe meiner eigenen IDs herumschlagen musste:

public static class HtmlHelperExtensions
{
    public static MvcHtmlString RadioButtonAndLabelFor<TModel, TProperty>(this HtmlHelper<TModel> self, Expression<Func<TModel, TProperty>> expression, bool value, string labelText)
    {
        // Retrieve the qualified model identifier
        string name = ExpressionHelper.GetExpressionText(expression);
        string fullName = self.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(name);

        // Generate the base ID
        TagBuilder tagBuilder = new TagBuilder("input");
        tagBuilder.GenerateId(fullName);
        string idAttr = tagBuilder.Attributes["id"];

        // Create an ID specific to the boolean direction
        idAttr = String.Format("{0}_{1}", idAttr, value);

        // Create the individual HTML elements, using the generated ID
        MvcHtmlString radioButton = self.RadioButtonFor(expression, value, new { id = idAttr });
        MvcHtmlString label = self.Label(idAttr, labelText);

        return new MvcHtmlString(radioButton.ToHtmlString() + label.ToHtmlString());
    }
}

Verwendung:

@Html.RadioButtonAndLabelFor(m => m.IsMarried, true, "Yes, I am married")
Attacke
quelle