I have a button that is created on each slide in a quiz game. Radio buttons containing the answer choices are appended from an object onto each slide as you cycle through the questions. I want to require that a radio button be clicked on before you can access the nextQuestion button. You can find the .append() on line 5 of the code below (inside of the loadQuestion function). What method would be the best way to achieve the desired result? If you need more of the code, let me know.
var loadQuestion = function (){
$('.question-name').html(name + (qnum) +"/"+ total);
$('.question').html(questions[count].question);
for(var i=0; i<questions[count].options.length; i++) {
$('.inputs').append('<input type="radio" name="question" value="'+questions[count].options[i]+'">'+questions[count].options[i]+'<br>')
}
};
/*--- First Question ---*/
var name = "Question ";
var qnum = 1;
var count = 0;
var total = questions.length;
loadQuestion();
/*--- When the Next Question Button is Hit ---*/
nextQuestion.click(function() {
$('.inputs').html("");
qnum++;
count++;
if (qnum <= 4) {
loadQuestion();
} else if (qnum == 6) {
$('.question-name').html("Your Score:");
$('.question').html("You got X out of 5 questions correct!");
nextQuestion.html("Home Screen").click(function() {
location.reload();
});
} else if (qnum == 5){
loadQuestion();
$('.next-question').html("Get Score!");
}
});
$(document).ready(function () {
$('#nextButton').attr('disabled', true);//disable the button by default on page load
$("input[type=checkbox]").on("click", function () {
if (this.length > 0) {
$('#nextButton').attr('disabled', false);//enable only when the checkbox is checked
}
});
});
I hope this helps!
Security note: Anybody can remove the disabled attribute from the button tag using developer tools in the browser. Use the backend to validate the checkbox value.
There's more than one way to go about this:
"Prevent button press until radio is selected"
From a ui/ux perspective your request raises the following question: "If the user isn't supposed to click on the button until the radio is selected, why is the button available for them to press before the radio is selected?" So, let's start there.
//pseudo-code - use delegate binding '.on()' for dynamically generated elements
$('.inputs').on('click', 'input[name="question"]', function({
if ($(this).is(':checked')) {
$('#nextButton').attr('disabled', false);
} else {
$('#nextButton').attr('disabled', true);
} /*... snip ...*/
}));
Or, you could generate the nextButton after an answer is selected much in the same way that you are currently generating the radio button - just remember to use delegate event binding. This is probably the "better way" because as has already been pointed out by #zadd, the disabled property can be circumvented.
Without reinventing the wheel, you could also just check to see if there's a radio selected when the button is pressed.
// pseudo-code again
nextQuestion.click(function() {
if($('input[name="question"]:checked').length > 0){
// checked!!! go do stuff!!!
} else {
// not checked! i should probably throw an alert or something...
alert('please answer the question before proceeding...');
}
});
Related
I have a bit complex form (includes inputs, textareas, custom selects, etc). I want to perform validation (just to check whether all fields are empty or not). Nothing more.
But I find it difficult to validate whether a radio button was selected or not. I'm using Twitter Bootstrap and I have styled the radio buttons through their javascript and css (btn-group).
I want whenever a user types or clicks something to run the script which checks whether the field is empty or not.
I will post a jsFiddle link below which reproduces my problem. The javascript I use is a bit different, because I want to perform the check only to inputs in the current tab.
$('body').on('keyup mouseup ', 'li, label, input, textarea, select', function (e) {
var tabId = $(this).closest('.tab-pane').attr('id');
var inputs = $('#' + tabId + ' :input');
var errors = {};
inputs.each(function (i, element) {
if ($(element).attr('name') !== undefined) {
if ($(element).attr('type') !== 'radio') {
if ($.trim($(element).val()) === '') {
errors[i] = $(element).attr('name');
}
} else {
if ($('.active', $("input[name='" + $(element).attr('name') + "']").closest('.btn-group')).length <= 0) {
errors[i] = $(element).attr('name');
}
}
}
});
console.log(errors);
if (!$.isEmptyObject(errors)) {
$('a[href="#' + tabId + '"]')
.html("<i class='red ace-icon fa fa-times bigger-120'></i> " + $('a[href="#' + tabId + '"]').text());
} else {
$('a[href="#' + tabId + '"]')
.html("<i class='green ace-icon fa fa-check bigger-120'></i> " + $('a[href="#' + tabId + '"]').text());
}
});
http://jsfiddle.net/gzwyddrc/
To reproduce the problem:
Click on the text field (An alert will tell you that the form is not valid) - OK
Close the alert and type one letter (otherwise you will be annoyed by the alert). The alert will pop out again telling you that the form is still invalid. - OK
Now click on one of the radio buttons. The alert will still tell you that the form is invalid. - NOT OK
If you click on either the text field or one of the radio buttons the alert has something else to say: THE FORM IS VALID! - NOT OK
I believe I've misused the events that I binded to the elements I want to fire that validation.
Ok, I've looked into this, but there were quite a lot of changes I had to make.
This is the code:
$("form").on("keyup mouseup", function (ev) {
var selected, errors = [];
setTimeout(function () {
$("input,select").each(function (i, v) {
var e;
e = $(v);
if (e.attr("name") === undefined) return;
switch (e.attr("type"))
{
case "radio":
selected = false;
e.closest(".btn-group").find("input[type=radio]").each(function (i, v) {
if ($(v).closest("label").hasClass("active"))
{
selected = true;
}
});
if (!selected) {
errors.push(e.attr("id"));
}
break;
default:
if ($.trim(e.val()) === "")
{
errors.push(e.attr("name")); // should be id?
}
break;
}
});
if (errors.length > 0) {
alert("ERRORS: " + errors);
}
}, 10);
});
The changes I made are:
event handlers are attached to the form, this is more convenient especially for multi-form pages (imagine a separate form on the top for login);
the selector also considers select (dropdowns) a possible input field;
minor name/order changes to make it more readable;
the switch replaces the if, because you will encounter more input types further along (switch scales better than if..else);
replaced the error object with an error array on which to push() errors;
when a radio group is unselected, the whole group is invalid, not any single one of the radio buttons nested, so the check should be based on the group as a whole (see use of selected flag);
for radio buttons the active class is toggled on the label not on the input;
finally, the most important feature you'll already have noticed:
Bootstrap itself uses events and JS to toggle the active class, so if you check it right away the label will never have the active class -- to counter this, I inserted a setTimeout() that will fire validation 10 ms later (which still is instantly for humans) so that Bootstrap has all the time to make an update pass over the form before we go in and validate.
I checked it thoroughly in a fiddle, so I'm quite confident it works well and opens up many possibilities you've probably envisioned.
This one seems really common question in StackOverflow. However, I am having difficulty in validating these textarea (Not to left blank) and checkboxes(At least one should be checked). I tried several validation Javascripts and frameworks but in vain.
I have textarea named "case_title0[]" whose will increase the number "0" to "1","2" and so on when user clicks "Add More" button. I want to validate at the point when user clicks the "Add More" button.
Secondly, I want the checkbox (name="editioncheck'+caseNum+'[]") which is dynamic as well to restrict user to leave it blank. The checkbox looks like "editioncheck0[]", "editioncheck1[]" and so on. It needs to be checked at least once to proceed to next "Add More" button. Until then "Add More" button should remain inactive.
So, I want these two type of validation in my form ie. textarea and checkbox.
Which is the simplest framework or custom code to use here?
I don't want fancy display as just alert() box should work in this regard.
Add common class to all textareas and common class to all checkboxes and perform validation.
<textarea class="t"></textarea>
<textarea class="t"></textarea>
<textarea class="t"></textarea>
<textarea class="t"></textarea>
<input type="checkbox" class="c">
function validate() {
var err = false;
$('.t').each(function(){
if($(this).text().length < 1) {
err = true;
return false;
}
});
if(!err) {
/* code to validate checkboxes like above */
}
return !err;
}
Finally, I have figured out the solution and I am going to post it here. As there is no exactly similar solution to my problem I had to code from scratch. While doing so lot of online resources helped me a lot.
To validate textarea on the fly (dynamic generate of text area when user clicks "Add More" button), here is solution I applied:
var csn='case_title'+caseno; //here "caseno" is incremental number to uniquely identify elements
var csum='case_summary'+caseno;
var caset=document.getElementById(csn).value;
var casesum=document.getElementById(csum).value;
if (caset == null || caset == "") {
alert("Executive Summary must be filled out");
caseNum --;
return false;
}
if (casesum == null || casesum == "") {
alert("Summaries with links must be filled out");
caseNum --;
return false;
Next, to validate the checkboxes I did as follows:
var edval='editioncheck'+caseno;
var checkBoxes=document.getElementsByClassName(edval);
var isChecked = false;
for (var i = 0; i < checkBoxes.length; i++) {
if ( checkBoxes[i].checked ) {
isChecked = true;
};
};
if ( isChecked ) {
//alert( 'At least one checkbox checked!' );
} else {
alert( 'Select at least one edition!' );
caseNum --;
return false;
}
The solution seems similar to the concept of fr34k, so thanks a lot. However, I found this online here http://jsfiddle.net/qyE97/
So, every time user click "Add More" button this script is executed and validates for the textarea and checkboxes.
I need to rewrite this section of a jQuery script so that it is triggered by selection of a radio button and not a dropdown.
var check_engraving = $('#attrib-2');
if (check_engraving.val() == 4) {
enable_engraving = true;
$('#individual_engraving_wrapper').show();
The new radio button that needs to trigger it is:
<span class="EngraveAttribute4"><input type="radio" name="id[2]" value="540" id="attrib-2-540" /><label class="attribsRadioButton zero" for="attrib-2-540">I would like different engraving on each of these items</label><br /></span>
It's obviously no good changing it to
var check_engraving = $('#attrib-2-540');
if (check_engraving.val() == 540) {
as the value is always 540 regardless of whether or not it is selected.
I tried to use
$('input:radio[name="id[2]"]').change(function () {
if ($(this).val() == '540') {
enable_engraving = true;
$('#individual_engraving_wrapper').show();
}
});
which I thought was working ok, but if I update the quantity I have to deselect then reselect the radio button for engraving to be true. The old dropdown system stayed as true when the quantity was updated.
I'm sure this can be done, but I'm stumped on it. Any suggestions appreciated.
try this
$('input[type=radio][name="id[2]"]').change(function () {
if ($(this).val() == '540') {
enable_engraving = true;
$('#individual_engraving_wrapper').show();
}
});
With the help of answers I found here, I try to disable submit button and send an alert message when clicked on it until there's not at least 2 checkboxes checked.
What I am doing wrong ?
var selected = $('#frmCompare :checkbox:checked').length;
function verifCompare() {
if (selected >= 2) {
//good
$('#frmCompare').submit();
} else {
//bad
alert('Veuillez selectionner au moins 2 produits à comparer...');
return false
}
}
$(document).ready(function () {
$('#btnCompare').attr('disabled', 'disabled');
$('#frmCompare :checkbox').change(function () {
//alert(selected);
if (selected >= 2) {
$('#btnCompare').attr('enabled');
}
});
});
At this point, only alert message works.
Fiddle
EDIT : added fiddle
There is no enabled attribute in HTML.
$('#btnCompare').prop('disabled', selected < 2);
You also need to recalculate the value of selected at every change, you can't just go with what it was set to at page load.
You initialize the count of checked checkboxes just once, when your script is first parsed. The count will not be recomputed later. This line:
var selected = $('#frmCompare :checkbox:checked').length;
should be inside the verification function, not outside.
You should change your code as
$('#frmCompare :checkbox').change(function(){
//update selected variable
selected = $('#frmCompare :checkbox:checked').length
if (selected >= 2) {
$('#btnCompare').attr('enabled');
}
});
I need to change the back button functionality of my phonegap project, which I've succeeded in doing without any problem. The only issue now, is that I need to further change the functionality based on if the user has a certain field selected.
Basically, if the user has clicked in a field with the id of "date-selector1", I need to completely disable the back button.
I was attempting to use document.activeElement, but it only returns the type of the element (input in this case), but I still want the functionality to work when they are in a general input, but not when they are in an input of a specific id.
EDIT
I tried all of the suggestions below, and have ended up with the following code, but still no success.
function pluginDeviceReady() {
document.addEventListener("backbutton", onBackKeyDown, false);
}
function onBackKeyDown() {
var sElement = document.activeElement;
var isBadElement = false;
var eList = ['procedure-date', 'immunization-date', 'lab-test-done', 'condition-onset', 'condition-resolution', 'medication-start-date', 'medication-stop-date', 'reaction-date'];
console.log("[[ACTIVE ELEMENT: --> " + document.activeElement + "]]");
for (var i = 0;i < eList.length - 1;i++) {
if (sElement == $(eList[i])[0]) {
isBadElement = true;
}
}
if (isBadElement) {
console.log('Back button not allowed here');
} else if ($.mobile.activePage.is('#main') || $.mobile.activePage.is('#family') || $.mobile.activePage.is('#login')) {
navigator.app.exitApp();
} else {
navigator.app.backHistory();
}
}
if you're listening for the back button you can add this if statement:
if (document.activeElement == $("#date-selector1")[0]) {
/*disable button here, return false etc...*/
}
or even better (Thanks to Jonathan Sampson)
if (document.activeElement.id === "date-selector1") {
/*disable button here, return false etc...*/
}
You can have a flag set when a user clicks on a field or you can have a click event (or any other type of event) when a user clicks on the field that should disable the back button.
From the documentation it looks like for the specific page that the backbuton is conditional on you can drop back-btn=true removing that back button.
http://jquerymobile.com/test/docs/toolbars/docs-headers.html
If you need complex conditional functionality you can just create your own button in the header or footer, style it using jquery-mobile widgets and implement your own click functionality.