Reputation: 396
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
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
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