-1

I have a problem where I need to call jQuery code to fetch a value from an HTML element like following:

@using (Html.BeginForm("Login", "Home",new { Checked = $('#checkbox5').checked }, FormMethod.Post,new { @class = "form-horizontal", role = "form" }))
{  
@Html.AntiForgeryToken()  
}

Note that besides passing the entire model into my Login action I'm trying to pass an optional parameter named "Checked". This parameter basically states whether the "remember me" checkbox has been checked on the form or not.

The checkbox itself is not the one that .NET uses by default like:

@Html.CheckboxFor(somepropertyhere);

But instead a regular checkbox like this:

   <input id="checkbox5" type="checkbox">
     <label for="checkbox5">
     Remember me?
     </label>

How can I fetch this checkbox's value when passing it as an extra parameter besides my model?

So that my method in the end would look like:

Public ActionResult Login(bool Checked, LoginViewModel model)
{
// To have the checked value here now...
}

P.S. And I can't use Html.CheckboxFor for some reasons, but I don't wanna get too much into details since the question wouldn't make sense then (maybe it doensn't even now I'm not sure if this is doable what I'm trying to achieve).

Can someone help me out?

User987
  • 3,273
  • 10
  • 38
  • 85
  • P.S. guys, it doesn't have to be a bool value, what matters is that I get "true" or "false" value inside the action... – User987 Jan 30 '17 at 13:26
  • @charlietfl can you be more specific? – User987 Jan 30 '17 at 13:27
  • 1
    if you want to send any variable, you should set name for field, and on serverside you can call it with name – Yigit Yuksel Jan 30 '17 at 13:27
  • Guys can u reply in a form of answer with some example? I'm not quite sure how to do any of these – User987 Jan 30 '17 at 13:28
  • Remove `new { Checked = $('#checkbox5').checked }` from the `BeginForm(...)` (that makes no sense) and give your checkbox a `name` attribute (a form only posts back the name/value pairs of successful controls) - use `` but this is never going to give you correct 2-way model binding and validation, especially if you need to return the view. –  Jan 31 '17 at 01:40

4 Answers4

1

if you want to send any variable, you should set name for field, and on serverside you can call it with name

<input id="checkbox5" type="checkbox" **name="checkbox_name"** value="true">
 <label for="checkbox5">
 Remember me?
 </label>

on server side

Public ActionResult Login(bool checkbox_name = false, LoginViewModel model){
// To have the checked value here now...
}
Yigit Yuksel
  • 865
  • 1
  • 17
  • 30
  • Hey Yigit, I did it like this but the checkbox_name is always null for some reason – User987 Jan 30 '17 at 13:35
  • you should set variable value="true", i ve updated the answer. – Yigit Yuksel Jan 30 '17 at 13:37
  • The parameters dictionary contains a null entry for parameter 'checkbox_name' of non-nullable type 'System.Boolean' for method 'System.Web.Mvc.ActionResult Login(.LoginViewModel, Boolean)' in 'Controllers.HomeController'. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter. Parameter name: parameters This is what I get now :/ – User987 Jan 30 '17 at 13:46
  • can you check send parameters over developer tools ? – Yigit Yuksel Jan 30 '17 at 13:49
1

You can get checkbox value in Controller using Checkbox Field name like this :

bool isRememberMe=Request.Form["CheckBoxName"];
Ghanshyam Singh
  • 1,236
  • 2
  • 13
  • 24
1

You can't use JavaScript within a Razor block, because they run at entirely different times. The Razor code runs server-side, long before the response is ever sent to the client. JavaScript runs client-side, only after the server has sent its response to the client, and Razor has already done its work.

On first load, the value of your checkbox will always be the default, which in your case is false. That's why none of the other answers help you. The user would have to interact with the checkbox and submit the form first, and then the checkbox would have that user-set value within the post action that handles the form. If you returned to the form, because of an error, then you could utilize the checkbox value.

To actually alter the form action without posting first, you'd have to handle the click event of the checkbox and manually change it via JavaScript. However, that's extremely brittle. If you want the value of the checkbox on post, then just bind it to something your action accepts. For example:

@Html.CheckBox("checked", Request["checked"] as bool? ?? false)

Then:

[HttpPost]
public ActionResult MyPostAction(MyClass model, bool checked)
Chris Pratt
  • 207,690
  • 31
  • 326
  • 382
0

I really don't understand why you don't want to use a new property model for the RememberMe value, but I think this might work for you:

Assuming your View looks like this:

@using (Html.BeginForm("Login", "Home", FormMethod.Post, new { @class = "form-horizontal", role = "form", id = "login-form" }))
{
    @Html.AntiForgeryToken()

    <div class="form-group">
        @Html.LabelFor(x => x.Username, new { @class = "form-control" })
        @Html.TextBoxFor(x => x.Username, new { @class = "form-control" })
    </div>

    <div class="form-group">
        @Html.LabelFor(x => x.Password, new { @class = "form-control" })
        @Html.PasswordFor(x => x.Password, new { @class = "form-control" })
    </div>

    <div class="form-group">
        <input id="checkbox5" type="checkbox">
        <label for="checkbox5">Remember me?</label>
    </div>

    <div class="form-group">
        <button type="submit" class="btn btn-primary">Login</button>
    </div>
}

And assuming your Controller looks like this:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Login(LoginViewModel model, bool rememberMe)
{
    // Do something with 'rememberMe'
    // Do something with 'model'
    return RedirectToAction("Index");
}

Then you must need a Javascript like this in your login view to replace the form action before the submit event was completed:

$(function () {

    var form = $("#login-form");
    var checkbox5 = $("#checkbox5");

    form.submit(function () {
        var checked = checkbox5.is(":checked") ? "true" : "false";
        var action = updateQueryStringParameter(form.action || '', "rememberme", checked);
        form.attr('action', action);
    });

    // stolen from http://stackoverflow.com/a/6021027/1605778
    function updateQueryStringParameter(uri, key, value) {
        var re = new RegExp("([?&])" + key + "=.*?(&|$)", "i");
        var separator = uri.indexOf('?') !== -1 ? "&" : "?";
        if (uri.match(re)) {
            return uri.replace(re, '$1' + key + "=" + value + '$2');
        }
        else {
            return uri + separator + key + "=" + value;
        }
    }
});

Let me know if this works for you.

Just to give more context: when you have a parameter of a primitive type (like bool or int) in your action, MVC expects this parameter in the Url; but the values of the Complex Types (like LoginViewModel) should pass as a Request Body in the HTTP POST. So if you want to pass both (complex and primitive) you need to be careful to pass all primitive types in the url and the values of complex types in the request body.

The POST of the Login Form could looks like:

POST /Home/Login?rememberMe=false

username=admin&password=secret
miguelerm
  • 124
  • 2
  • 5