Search code examples
asp.net-coremodel-view-controllerradio-buttonasp.net-core-3.1model-binding

mvc. net core radio buttons to select value for each and model binder


I have 4 radio buttons, and I want to select value for each radio buttons and bind them to a model binder so that each property will have a value either true or false. At the moment, we need radio buttons not checkboxes. I need to group them so only one radio button should be selected, rest of them will have a value = false. For example, if I select Yes - Math - the radio button should have a value true for it, and rest them should be false.

So here is my razor view class

<div class="radio-class">
                        <input class="radios__input" id="IsMath" name="SubjectRadio" type="radio" value="true">
                        <label class="label" for="IsMath">Yes - Math</label>
                    </div>
                    <div class="radios__item">
                        <input class="radios__input" id="IsPhysics" name="SubjectRadio" type="radio" value="true">
                        <label class="label" for="IsPhysics">Yes - Physics</label>
                    </div>
                    <div class="radios__item">
                        <input class="radios__input" id="IsChemistry" name="SubjectRadio" type="radio" value="true">
                        <label class="label" for="IsChemistry">Yes - Chemistry</label>
                    </div>
                    <div class="radios__item">
                        <input class="radios__input" id="IsNoSubjects" name="SubjectRadio" type="radio" value="true">
                        <label class="label" for="IsNoSubjects">No Subjects</label>
                    </div>

Here is my model like this:

 [BindProperty]
    public bool? IsPhysics { get; set; } = false;

    [BindProperty]
    public bool? IsChemistry { get; set; } = false;

    [BindProperty]
    public bool? IsMath { get; set; } = false;

    [BindProperty]
    public bool? IsNoSubjects { get; set; } = false;

I never get the individual values for it. I want the true value for the one I selectrest of them will be a false value. Can anyone help? I do not want to change a code to radiobutton list at the moment, or If that is the way. However still I need to pass true and false to each properties after the selection of radio buttons.

I am using Post method to submit the values.


Solution

  • Model Binding binds the property by name attribute instead of id attribute. So you need change your code like below:

    <div class="radio-class">
        <input class="radios__input" name="IsMath" id="SubjectRadio" type="radio" value="true">
        <label class="label" for="IsMath">Yes - Math</label>
    </div>
    <div class="radios__item">
        <input class="radios__input" name="IsPhysics" id="SubjectRadio" type="radio" value="true">
        <label class="label" for="IsPhysics">Yes - Physics</label>
    </div>
    <div class="radios__item">
        <input class="radios__input" name="IsChemistry" id="SubjectRadio" type="radio" value="true">
        <label class="label" for="IsChemistry">Yes - Chemistry</label>
    </div>
    <div class="radios__item">
        <input class="radios__input" name="IsNoSubjects" id="SubjectRadio" type="radio" value="true">
        <label class="label" for="IsNoSubjects">No Subjects</label>
    </div>
                
    <button type="submit">Submit</button> 
    

    Besides, not sure your form sends post or get request, but if you send the get request, be sure change the property to [BindProperty(SupportsGet = true)].


    A Whole working demo you could follow:

    View(Index.cshtml)

    <form>
        <div class="radio-class">
            <input class="radios__input" name="IsMath" id="SubjectRadio" type="radio" value="true">
            <label class="label" for="IsMath">Yes - Math</label>
        </div>
        <div class="radios__item">
            <input class="radios__input" name="IsPhysics" id="SubjectRadio" type="radio" value="true">
            <label class="label" for="IsPhysics">Yes - Physics</label>
        </div>
        <div class="radios__item">
            <input class="radios__input" name="IsChemistry" id="SubjectRadio" type="radio" value="true">
            <label class="label" for="IsChemistry">Yes - Chemistry</label>
        </div>
        <div class="radios__item">
            <input class="radios__input" name="IsNoSubjects" id="SubjectRadio" type="radio" value="true">
            <label class="label" for="IsNoSubjects">No Subjects</label>
        </div>
                    
        <button type="submit">Submit</button>       
    </form>
    

    Controller

    public class HomeController : Controller
    {
        public IActionResult Index()
        {            
            return View();        
        }
        [BindProperty(SupportsGet =true)]
        public bool? IsPhysics { get; set; } = false;
    
        [BindProperty(SupportsGet = true)]
        public bool? IsChemistry { get; set; } = false;
    
        [BindProperty(SupportsGet = true)]
        public bool? IsMath { get; set; } = false;
    
        [BindProperty(SupportsGet = true)]
        public bool? IsNoSubjects { get; set; } = false;
    }
    

    Result

    enter image description here

    Update:

    If you want to make the radio button only selects one option, the name attribute must be the same.

    For how to make model binding work, two ways you could follow.

    The fist way you can get the reiced value of radio button and manually set the property value:

    View

    <form method="post" asp-action="Create">
        <div class="radio-class">
            <input class="radios__input" id="IsMath" name="SubjectRadio" type="radio" value="IsMath">
            <label class="label" for="IsMath">Yes - Math</label>
        </div>
        <div class="radios__item">
            <input class="radios__input" id="IsPhysics" name="SubjectRadio" type="radio" value="IsPhysics">
            <label class="label" for="IsPhysics">Yes - Physics</label>
        </div>
        <div class="radios__item">
            <input class="radios__input" id="IsChemistry" name="SubjectRadio" type="radio" value="IsChemistry">
            <label class="label" for="IsChemistry">Yes - Chemistry</label>
        </div>
        <div class="radios__item">
            <input class="radios__input" id="IsNoSubjects" name="SubjectRadio" type="radio" value="IsNoSubjects">
            <label class="label" for="IsNoSubjects">No Subjects</label>
        </div>
    
        <button type="submit">Submit</button>
    </form>
    

    Controller:

    public IActionResult Index()
    {            
        return View();        
    }
    [HttpPost]
    public IActionResult Create(string SubjectRadio)
    {
        switch(SubjectRadio)
        {
            case "IsPhysics":
                IsPhysics = true;
                break;
            case "IsChemistry":
                IsChemistry= true;  
                break;
            case "IsMath":
                IsMath= true; break;
            default:IsNoSubjects=true; break;
        }
        return View();
    }
    [BindProperty(SupportsGet =true)]
    public bool? IsPhysics { get; set; } = false;
    
    [BindProperty(SupportsGet = true)]
    public bool? IsChemistry { get; set; } = false;
    
    [BindProperty(SupportsGet = true)]
    public bool? IsMath { get; set; } = false;
    
    [BindProperty(SupportsGet = true)]
    public bool? IsNoSubjects { get; set; } = false;
    

    The second way is that you can use the ajax:

    View

    <form method="post">
        <div class="radio-class">
            <input class="radios__input" id="IsMath" name="SubjectRadio" type="radio">
            <label class="label" for="IsMath">Yes - Math</label>
        </div>
        <div class="radios__item">
            <input class="radios__input" id="IsPhysics" name="SubjectRadio" type="radio">
            <label class="label" for="IsPhysics">Yes - Physics</label>
        </div>
        <div class="radios__item">
            <input class="radios__input" id="IsChemistry" name="SubjectRadio" type="radio">
            <label class="label" for="IsChemistry">Yes - Chemistry</label>
        </div>
        <div class="radios__item">
            <input class="radios__input" id="IsNoSubjects" name="SubjectRadio" type="radio">
            <label class="label" for="IsNoSubjects">No Subjects</label>
        </div>
    
        <button type="submit">Submit</button>
    </form>
    
    @section Scripts
    {
        <script>
            $('form').on('submit', function(e){
                e.preventDefault();
                var id = $('input[type=radio][name=SubjectRadio]:checked').attr('id');
                var data;
                switch(id){
                    case "IsMath":
                        data = { "IsMath":true}; break;
                    case "IsPhysics":
                        data = { "IsPhysics":true}; break;
                    case "IsChemistry":
                        data = { "IsChemistry": true }; break;
                    default:
                        data = { "IsNoSubjects": true }; break;
                }
                $.ajax({
                    type: 'POST',
                    url: '/Home/Create',
                    data: data,
                    success: function () {
                        //do your stuff...
                    }
                });
    
            });
        </script>
    }
    

    Controller

    public IActionResult Index()
    {            
        return View();        
    }
    [HttpPost]
    public IActionResult Create()
    {
            
        //...
    }
    [BindProperty]
    public bool? IsPhysics { get; set; } = false;
    [BindProperty]
    public bool? IsChemistry { get; set; } = false;
    
    [BindProperty]
    public bool? IsMath { get; set; } = false;
    
    [BindProperty]
    public bool? IsNoSubjects { get; set; } = false;