locked
Preserve the checkbox statues on valid post back RRS feed

  • Question

  • User-540818677 posted

    I have the following view model class:-

        public class ContactinfoCreate
        {
            public ContactInfo ContactInfo { get; set; }
            public string CustomCheck { get; set; }
        }

    and the following checkbox inside my view:-

    @model LandingPageFinal3.ViewModels.ContactinfoCreate
    <form action="@(!Context.Request.Path.Value.ToString().ToLower().Contains("/info") ? "/I/Home/SearchNPI" : "/info/Home/SearchNPI")" method="post" class="">
    <input type="checkbox" @*class="custom-control-input"*@ id="CustomCheck" name="CustomCheck"> <span style="color: #4d9b84"> By submitting the NPI above, you agree that the information entered provided is your own NPI and information is not to be distributed.</span>
                        
    
    <button type="submit" id="getmyestimate" disabled class="standard">
    Get My Estimate
    </button>
    
    </form>
    

    and the following post action method:-

    [AllowAnonymous]
            [HttpPost]
            [ValidateAntiForgeryToken]
            public async Task<IActionResult> SearchNPI(ContactinfoCreate ci)
            {
                if (ModelState.IsValid)
                {}
                else
                 return View("Index", ci);
            } 
    

    but the problem if the model state is not valid, and the view is returned back to the user the checkbox will always be unchecked.. so can anyone advice how i can preserve the checkbox status?

    Saturday, July 11, 2020 9:25 AM

All replies

  • User475983607 posted

    Only checked checkbox values are sent.  You either have to check for null or use checkbox trick and add a hidden field.  A tag helper will implement the trick for you.

    https://www.w3schools.com/tags/att_input_type_checkbox.asp

    https://www.learnrazorpages.com/razor-pages/forms/checkboxes

    Using your code in Chrome.

        public class GeneralController : Controller
        {
            // GET: General
            public ActionResult Index()
            {
                return View();
            }
    
            [HttpPost]
            public ActionResult Index(ContactinfoCreate ci)
            {
                return View(ci);
            }
        }
    @model MvcBasic.Models.ContactinfoCreate
    @{
        ViewData["Title"] = "Index";
    }
    
    <h1>Index</h1>
    
    <form method="post">
        <div>
            <input type="checkbox" id="CustomCheck" name="CustomCheck" checked="@((Model?.CustomCheck ?? "off") == "on")" />
        </div>
        <div>
            <input id="Submit1" type="submit" value="submit" />
        </div>
    </form>

    Saturday, July 11, 2020 10:58 AM
  • User-540818677 posted

    Only checked checkbox values are sent.  You either have to check for null or use checkbox trick and add a hidden field.  A tag helper will implement the trick for you.

    https://www.w3schools.com/tags/att_input_type_checkbox.asp

    https://www.learnrazorpages.com/razor-pages/forms/checkboxes

    Using your code in Chrome.

        public class GeneralController : Controller
        {
            // GET: General
            public ActionResult Index()
            {
                return View();
            }
    
            [HttpPost]
            public ActionResult Index(ContactinfoCreate ci)
            {
                return View(ci);
            }
        }
    @model MvcBasic.Models.ContactinfoCreate
    @{
        ViewData["Title"] = "Index";
    }
    
    <h1>Index</h1>
    
    <form method="post">
        <div>
            <input type="checkbox" id="CustomCheck" name="CustomCheck" checked="@((Model?.CustomCheck ?? "off") == "on")" />
        </div>
        <div>
            <input id="Submit1" type="submit" value="submit" />
        </div>
    </form>

    Thanks for the reply.. but i thought the model binder will do this work for us?

    Saturday, July 11, 2020 1:34 PM
  • User475983607 posted

    johnjohn123123

    but i thought the model binder will do this work for us?

    The model binder is working as expected and populates the action method input arguments; the model.   The problem is the markup does nothing with the model values.  

    Saturday, July 11, 2020 2:24 PM
  • User-540818677 posted

    johnjohn123123

    but i thought the model binder will do this work for us?

    The model binder is working as expected and populates the action method input arguments; the model.   The problem is the markup does nothing with the model values.  

    But i defined the checkbox name to be equal the model property name (CustomCheck)/... so i thought the model binder will map the value..

    Saturday, July 11, 2020 3:51 PM
  • User-474980206 posted

    The model binder will bind a check value. But the browser only posts the value is checked, so the value is null if not checked. But in you original code you never set a value to the checkbox so it’s null in either case.

    the checkbox helper renders value=true, as it expects to bind to a bool. As suggested, it renders a hidden with the same with a value of “false”. Then on post back there is always a value. The knows the double value is true.

    you also have a coding error. The checked attribute of an input does not require a value, so checked=“false” makes the checkbox checked.

    Sunday, July 12, 2020 4:06 PM
  • User711641945 posted

    Hi johnjohn123123,

    Just using the tag helper:

    <form action="@(!Context.Request.Path.Value.ToString().ToLower().Contains("/info") ? "/I/Home/SearchNPI" : "/info/Home/SearchNPI")" method="post" class="">
        <input type="checkbox" asp-for="CustomCheck"> 
    
        <button type="submit" id="getmyestimate" class="standard">
            Get My Estimate
        </button>
    </form>

    Best Regards,

    Rena

    Monday, July 13, 2020 9:34 AM