Search code examples
asp.net-mvcmodelradio-buttoneditorfor

Adding new attributes on RadioButton through MVC model variable


I have MVC class and one of the variables has been declared as:

[UIHint("YesNoRadio")]
[Required(ErrorMessage = "test")]
public bool? Emergency { get; set; }

this creates HTML as

<div class="radio-inline"><label>
<input data-val="true" data-val-required="Test" id="Emergency" name="Emergency" type="radio" value="true">Yes</label>
</div>
<div class="radio-inline"><label>
<input id="Emergency" name="Emergency" type="radio" value="false">No</label>
</div>

what i want is to add new attribute, lets say div-effect = "emergencyExplain" and radio button to come as

<label><input id="Emergency" name="Emergency" type="radio" value="false" div-effect = "emergencyExplain">No</label>

YesNoRadio.cshtml is below:

@model bool?    
<div class="radio-inline">
    <label>
        @if (Model.HasValue && Model.Value)
        {
            @Html.RadioButtonFor(x => x, "true", new { @checked = "checked" });
        }
        else
        {
            @Html.RadioButtonFor(x => x, "true");
        }
        Yes
    </label>
</div>
<div class="radio-inline">
    <label>
        @if (Model.HasValue && !Model.Value)
        {
            @Html.RadioButtonFor(x => x, "false", new { @checked = "checked" });
        }
        else
        {
            @Html.RadioButtonFor(x => x, "false");
        }
        No
    </label>
</div>

and its called as:

@Html.EditorFor(m => m.Emergency, new { htmlAttributes = new { @class = "form-control" } })

New to MVC form creation so any help in pointing in right direction will be appreciated.

Thanks


Solution

  • Using the [UIHint] attribute just instructs the EditorFor() method to use that template. It does not pass any additional data to the template other that the modell property. You need to use this overload of EditorFor() where you pass the name of the template and an object representing the additionalViewData.

    You have no shown the model property that contains the value that you want to add to the data-effect attribute, but assuming its

    public string Effect { get; set; }
    

    and you set its value in the GET method before you pass the model to the view, then delete the [UIHint] attribute from the Emergency property and modify the main view to

    @Html.EditorFor(m => m.Emergency, "YesNoRadio", new { effect = Model.Effect })
    

    Then change the YesNoRadio.cshtml template to

    <div class="radio-inline">
        <label>
            @Html.RadioButtonFor(x => x, true, new { id = "", div_effect = ViewData["effect"] })
            <span>Yes</span>
        </label>
        <label>
            @Html.RadioButtonFor(x => x, false, new { id = "", div_effect = ViewData["effect"] })
            <span>No</span>
        </label>
    </div>
    

    Which will generate

    <input data-val="true" data-val-required="Test" div-effect="emergencyExplain" name="Emergency" type="radio" value="True">
    

    A few things to note about your current view code.

    1. Using new { htmlAttributes = new { @class = "form-control" } } wont do anything when using a custom EditorTemplate - its only applicable using the built-in templates (how would it know which element to apply that class to). If you want the class name applied to the radio buttons, add that in the RadioButtonFor() method in the template
    2. You do not need to (and should not) set the checked attribute. That attribute is set by the RadiobuttonFor() method based on the value of the property (if its null, no buttons will be selected, and if its true or false then the appropriate button will be selected
    3. Note also the use of new { id = "" } which removes the id attribute which would other wise be generating duplicates which is invalid html