TK1
TK1

Reputation: 396

Post value from a disabled checkbox

I know that disabled inputs do not post value to the server. Also, a checkbox cannot have the readonly property. I would like to get the functionality of a "readonly checkbox", where the checkbox is disabled and I can read the value of the checkbox on the page post.

The following code is something similar to what I need to do in my application. On the click of the first checkbox (RememberMe), I check the second checkbox (Seriously) and add the disable attribute to it.

Here is the model:

public class LogOnModel
{
    [Required]
    [Display(Name = "User name")]
    public string UserName { get; set; }

    [Required]
    [DataType(DataType.Password)]
    [Display(Name = "Password")]
    public string Password { get; set; }

    [Display(Name = "Remember me?")]
    public bool RememberMe { get; set; }

    [Display(Name = "Seriously?")]
    public bool Seriously { get; set; }
}

Here is my view:

@using (Html.BeginForm("", "", FormMethod.Post, new { id = "userForm" }))
{
<div>
    <fieldset>
        <legend>Account Information</legend>

        <div class="editor-label">
            @Html.LabelFor(m => m.UserName)
        </div>
        <div class="editor-field">
            @Html.TextBoxFor(m => m.UserName)
            @Html.ValidationMessageFor(m => m.UserName)
        </div>

        <div class="editor-label">
            @Html.LabelFor(m => m.Password)
        </div>
        <div class="editor-field">
            @Html.PasswordFor(m => m.Password)
            @Html.ValidationMessageFor(m => m.Password)
        </div>

        <div class="editor-label">
            @Html.CheckBoxFor(m => m.RememberMe)
            @Html.LabelFor(m => m.RememberMe)
        </div>

        <div class="editor-label">
            @Html.CheckBoxFor(m => m.Seriously)
            @Html.LabelFor(m => m.Seriously)
        </div>

        <p>
            <input type="button" value="Log On" onclick = "SubmitForm();"/>
        </p>
    </fieldset>
</div>
}

Here are the stripped down contents of my js file included in the view:

function SubmitForm() {
    $.ajax({
        type: "POST",
        url: "/Account/LogOnAjax",
        cache: false,
        data: $("#userForm").serialize(),
        success: function (results) {
            showMessage(results);
        },
        error: 
            showMessage("error!");
        }
    });
}

function SeriouslyCheckEnable(value) {
    var SeriouslyCheckBox = $("input[name = 'Seriously']");
    if (value == "true") {
        SeriouslyCheckBox.attr('checked', 'checked');
        SeriouslyCheckBox.attr("disabled", "true");
    }
    else {
        SeriouslyCheckBox.removeAttr('checked');
        SeriouslyCheckBox.removeAttr('disabled');
    }
}

$(document).ready(function () {
    $("input[name='RememberMe']").click(function (e) { SeriouslyCheckEnable(($("input[name='RememberMe']:checked").val())); });
});

Here is the controller that I am debugging:

    public ActionResult LogOnAjax(LogOnModel model)
    {
        bool seriously = model.Seriously;
        bool remMe = model.RememberMe;

        return Json("some message here", JsonRequestBehavior.AllowGet);
    }

Now, regardless of the checked state of the seriously checkbox, I always get a false for the Boolean variable seriously. Any help would be appreciated.

Upvotes: 1

Views: 2663

Answers (2)

JPK
JPK

Reputation: 793

Disabled values won't get posted, as you said. If you want to use a "disabled" value for display purposes but post a hidden value, then you'll need to create an additional property specifically for display purposes.

MODEL

public class LogOnModel
{
    [Required]
    [Display(Name = "User name")]
    public string UserName { get; set; }

    [Required]
    [DataType(DataType.Password)]
    [Display(Name = "Password")]
    public string Password { get; set; }

    [Display(Name = "Remember me?")]
    public bool RememberMe { get; set; }

    public bool Seriously { get; set; }

    [Display(Name = "Seriously?")]
    public bool SeriouslyDisplay { get; set; }
}

HTML

<div class="editor-label">
    @Html.CheckBoxFor(m => m.SeriouslyDisplay)
    @Html.LabelFor(m => m.SeriouslyDisplay)
</div>

@Html.HiddenFor(m => m.Seriously)

JAVASCRIPT

function SeriouslyCheckEnable(value) {
  $('#Seriously').val(value);
  $('#SeriouslyDisplay').prop('checked', value);
  $('#SeriouslyDisplay').prop('disabled', value);
}

The display only property doesn't actually have to be in the display model, you only actually have to put it in the HTML. I just left it there for readability.

Also, I would suggest using the 'checked' property to toggle check boxes with javascript, as in example. It makes it much simpler to use and read!

Upvotes: 2

TK1
TK1

Reputation: 396

I was tempted to mark the answer provided by user2395249 as that answer got me in the right direction. This is how I ended up with the correct values on the AJAX post:

Model:

I basically added another property called SeriouslyHidden.

[Display(Name = "Seriously?")]
public bool Seriously { get; set; }

public bool SeriouslyHidden { get; set; }

View:

<div class="editor-label">
    @Html.HiddenFor(m => m.SeriouslyHidden)
    @Html.CheckBoxFor(m => m.Seriously)
    @Html.LabelFor(m => m.Seriously)
</div>

Modified my JavaScript to the following:

$(document).ready(function () {
    $("input[name='RememberMe']").click(function (e) {
        var RememberMeCheckBoxValue = ($("input[name='RememberMe']:checked").val());
        SeriouslyCheck(RememberMeCheckBoxValue);
        SeriouslyDisable(RememberMeCheckBoxValue);
    });

    $("input[name='Seriously']").click(function (e) {
        SeriouslyCheck(($("input[name='Seriously']:checked").val()));
    });
});

function SeriouslyCheck(value) {
    $('#SeriouslyHidden').val(value);
    if (value == "true")
        $(SeriouslyCheckBox).attr('checked', 'checked');
    else
        $(SeriouslyCheckBox).removeAttr('checked');
}

function SeriouslyDisable(value) {
    if (value == "true")
        $(SeriouslyCheckBox).attr("disabled", "true");
    else
        $(SeriouslyCheckBox).removeAttr('disabled');
}

And then in the controller I retrieved the value from

public ActionResult LogOnAjax(LogOnModel model)
{
    bool seriously = model.SeriouslyHidden;
    bool remMe = model.RememberMe;

    //do some processing here

    return Json("some message here", JsonRequestBehavior.AllowGet);
}

Upvotes: 0

Related Questions