i'm implementing a checkbox question for let user to choose. However, if admin set the question mandatory to true, the checkbox must select at least 1 to submit, else a message will prompt user to select. Tried the jquery but when click button, nothing happen.
Any mistakes that ive done?
My View:
@model List<IFXSurveyTool.Models.AnswerQuestionViewModel>
<script>
var messageContainer = $('.errormessage');
$('#save').click(function () {
// Get all mandatory containers
var mandatory = $('.mandatory');
$.each(mandatory, function () {
var numChecked = $(this).find('input:checked').length;
if (numChecked === 0) {
messageContainer.text('At least one checkbox must be selected.');
return false;
}
});
});
$('.mandatory').on('click', 'input[type="checkbox"]', function () {
messageContainer.text('');
});
</script>
<br />
<h2>Questions</h2>
<br />
@using (Html.BeginForm())
{
<div class="errormessage"></div>
<div class="checkboxcontainer mandatory">
@for (int x = 0; x < Model[i].Choice_SubQuestion.Count(); x++)
{
<input type="checkbox" name="[@i].MultiAnswer[@x]" value="@Model[i].Choice_SubQuestion[x]" />
@Html.HiddenFor(m => m[i].MultiAnswer[x])
@Html.LabelFor(m => m[i].MultiAnswer[x], Model[i].Choice_SubQuestion[x].ToString(), new { @class = "questionlist1" })
}
</div>
<button type="button" id="save">Save</button>
}
After generating the checkbox in HTML:
<div class="checkboxcontainer mandatory">
<input type="checkbox" name="[0].MultiAnswer[0]" value="1">
<input name="[0].MultiAnswer[0]" type="hidden" value="">
<label class="questionlist1" for="">1</label>
<input type="checkbox" name="[0].MultiAnswer[1]" value="2">
<input name="[0].MultiAnswer[1]" type="hidden" value="">
<label class="questionlist1" for="">2</label>
<input type="checkbox" name="[0].MultiAnswer[2]" value="3">
<input name="[0].MultiAnswer[2]" type="hidden" value="">
<label class="questionlist1" for="">3</label>
</div>
Firstly, your giving all the containing <div>
elements class="mandatory"
and only ever generating checkboxes if Model[i].Mandatory
is true
so you html should be
for (int x = 0; x < Model[i].Choice_SubQuestion.Count; x++)
{
@{var attributes = Model[i].Mandatory ? "checkboxgroup mandatory" : "checkboxgroup";}
<div class="@attributes">
<div class="message></div>
<input type="checkbox" name="[@i].MultiAnswer[@x]" value="@Model[i].Choice_SubQuestion[x]" />
@Html.HiddenFor(m => m[i].MultiAnswer[x])
@Html.LabelFor(m => m[i].MultiAnswer[x], Model[i].Choice_SubQuestion[x].ToString(), new { @class = "questionlist1" })
</div>
}
<input value="Submit" type="submit" class="btn" id="save" />
Next, your button is a submit button so the form is actually submitting (before the error message has a chance to become visible). Change the scripts to
$('#save').click(function() {
var canSubmit = true;
// Get all mandatory containers
var mandatory = $('.mandatory');
$.each(mandatory, function() {
var numChecked = $(this).find('input:checked').length;
if (numChecked === 0) {
canSubmit = false; // signal we can't submit
// display error message;
$(this).children('.message').text('At least one checkbox must be selected');
return false; // exit the loop
}
});
if (!canSubmit) {
return false; // cancel the default submit
}
});
$('.mandatory').on('click', 'input[type="checkbox"]', function() {
$(this).closest('.mandatory').children('.message').text(''); // clear any existing error message
});
Note also the scripts must be at the bottom of the page (immediately before the closing </body>
tag) or wrapped in $(document).ready() { ..... }
or $(function() { ..... });
(shorthand version).