I'm currently using twitter bootstrap wizard as this template, so my wizard structure is something like this:
form
step1
checkbox
button next
step2
inputs
button next
step3
submit
The checkboxes are defined as:
#{
foreach (var test in #Html.GetEnumSelectList<length>())
{
<div class="form-check form-check-inline mb-3">
<input id="#test.Text" type="checkbox" value="#test.Value" name="selectedTest" class="form-check-input">
<label for="#test.Text" class="form-check-label">#test.Text</label>
</div>
}
}
So I want to get change step 3, style: none to style: block if one of these checkboxes is checked as:
<script>
let id;
$("input[type=checkbox]").on("change", function () {
id = $(this).attr("id");
const text = document.getElementById(id);
if ($(this).is(":checked")) {
text.style.display = "block";
}
else
{
text.style.display = "none";
const IsChecked = $("input[type=checkbox]");
let show = "none";
for (let i = 0; i < IsChecked.length; i++) {
if (IsChecked[i].checked) {
show = "block";
}
break;
}
}
})
</script>
But oh surprise, the HTML of step 3 is not available yet until I go to step 3, how can tell step 1 to do the change into step 3 when the checkbox of step 1 is checked?
Related
i am trying to make a multi-step questionnaire where there are 3 steps. This questionnaire allows users to input their desired answers and will return company names that are in the selected category, features and integration needed. This data is stored in the MySQL database, i will attach a diagram of the schema.
Diagram
Step 1 is category, uses radio button as only one can be selected.
Step 2 is Features, uses checkbox as multiple items can be selected
Step 3 is integration, uses radio button as only one can be selected.
The way i have tried to implement this is to include the user input value into the SQL select query and then use the results as the next step values. The issue i have is, as it is multi-step the second query does not run until the full questionnaire is submitted. Also i get the feeling this not the right way to do it as questions will not load if the database does not respond quickly.
Can i implement Javascript to do the multi-step logic and then run one query at the end? i am kind of lost on how to go about this.
Any help with be greatly appreciated.
App.py
#app.route('/home', methods = ['GET', 'POST'])
def home():
firstInput = ''
myresult2 = ''
sqlFirst = 'SELECT DISTINCT * FROM categories;'
if request.method == 'POST':
firstInput = request.form.get('cat_in')
my_data = (firstInput,)
fetchFetch = 'SELECT distinct features.features, categories.categories, mytable.cat_FK_KEY, categories.categoryID, mytable.Categories FROM mytable, features, nameFeatures, categories WHERE mytable.id = `nameFeatures`.`name_FK_ID` and features.featureID = nameFeatures.feature_FK_ID and mytable.cat_FK_KEY = categories.categoryID and categories.categoryID = %s;'
cursor.execute(fetchFetch, my_data)
myresult2 = cursor.fetchall()
cursor.execute(sqlFirst)
myresult = cursor.fetchall()
return render_template('index.html', firstInput=firstInput, myresult=myresult, myresult2=myresult2)
index.html
<form id="regForm" action="" method="post">
<div class="tab">Please pick a Category:
{% for row in myresult %}
<input type="radio" id="{{row[0]}}" oninput="this.className = ''" name="cat_in" value="{{row[0]}}">
<label for="{{row[0]}}">{{row[1]}}</label><br>
{% endfor %}
</div>
<div class="tab">Select the features:
<p>{{firstInput}}</p>
{% for row in myresult2 %}
<input type="checkbox" id="{{row[0]}}" oninput="this.className = ''" name="feature_in" value="{{row[0]}}">
<label for="{{row[0]}}">{{row[0]}}</label><br>
{% endfor %}
</div>
<div class="tab">Which intergration:
</div>
<div style="overflow:auto;">
<div style="float:right;">
<button type="button" id="prevBtn" onclick="nextPrev(-1)">Previous</button>
<button type="button" id="nextBtn" onclick="nextPrev(1)">Next</button>
</div>
</div>
<!-- Circles which indicates the steps of the form: -->
<div style="text-align:center;margin-top:40px;">
<span class="step"></span>
<span class="step"></span>
<span class="step"></span>
<span class="step"></span>
</div>
</form>
<script>
var currentTab = 0; // Current tab is set to be the first tab (0)
showTab(currentTab); // Display the current tab
function showTab(n) {
// This function will display the specified tab of the form...
var x = document.getElementsByClassName("tab");
x[n].style.display = "block";
//... and fix the Previous/Next buttons:
if (n == 0) {
document.getElementById("prevBtn").style.display = "none";
} else {
document.getElementById("prevBtn").style.display = "inline";
}
if (n == (x.length - 1)) {
//document.getElementById("nextBtn").innerHTML = "Submit";
document.getElementById("nextBtn").submit();
} else {
document.getElementById("nextBtn").innerHTML = "Next";
}
//... and run a function that will display the correct step indicator:
fixStepIndicator(n)
}
function nextPrev(n) {
// This function will figure out which tab to display
var x = document.getElementsByClassName("tab");
// Exit the function if any field in the current tab is invalid:
if (n == 1 && !validateForm()) return false;
// Hide the current tab:
x[currentTab].style.display = "none";
// Increase or decrease the current tab by 1:
currentTab = currentTab + n;
// if you have reached the end of the form...
if (currentTab >= x.length) {
// ... the form gets submitted:
document.getElementById("regForm").submit();
return false;
}
// Otherwise, display the correct tab:
showTab(currentTab);
console.log(currentTab);
}
function validateForm() {
// This function deals with validation of the form fields
var x, y, i, valid = true;
x = document.getElementsByClassName("tab");
y = x[currentTab].getElementsByTagName("input");
// A loop that checks every input field in the current tab:
for (i = 0; i < y.length; i++) {
// If a field is empty...
if (y[i].value == "") {
// add an "invalid" class to the field:
y[i].className += " invalid";
// and set the current valid status to false
valid = false;
}
}
// If the valid status is true, mark the step as finished and valid:
if (valid) {
document.getElementsByClassName("step")[currentTab].className += " finish";
}
console.log(valid);
return valid; // return the valid status
}
function fixStepIndicator(n) {
// This function removes the "active" class of all steps...
var i, x = document.getElementsByClassName("step");
for (i = 0; i < x.length; i++) {
x[i].className = x[i].className.replace(" active", "");
}
//... and adds the "active" class on the current step:
x[n].className += " active";
}
</script>
I'm brand new to coding. I've created a form with three fields- two with "number" types and one with radio button selection. I'm trying to utilize "try catch throw" to validate these fields and have error messages echoed onto the screen (not as an alert). I know that there is a lot of code in here, but I am really lost with this. Here is my HTML and js:
HTML:
<form>
<fieldset>
<label for="hshld" class="formhdr">Total number of people in your household:</label>
<input type="number" id="hshld" name="hshld" min="1">
</fieldset>
<fieldset>
<label for="hrrisk" class="formhdr">Number of high-risk people in your household:</label>
<input type="number" id="hrrisk" name="hrrisk" min="0">
</fieldset>
<fieldset>
<legend class="formhdr">Number of weeks in isolation:</legend>
<input type="radio" id="countone" name="headcount">
<label for="countone" class="numweeks">1</label>
<input type="radio" id="counttwo" name="headcount">
<label for="counttwo" class="numweeks">2</label>
<input type="radio" id="countthree" name="headcount">
<label for="countthree" class="numweeks">3</label>
<input type="radio" id="countfour" name="headcount">
<label for="countfour" class="numweeks">4+</label>
</fieldset>
<input type="submit" value="Submit" id="submit">
</form>
and my .js:
//Global variables
var hshld = document.getElementById("hshld");
var mysubmit = document.getElementById("submit");
var radioError = document.getElementById("radioError");
var weekCount;
//this function checks to see if the user entered a number into the field
function validatehshld() {
try {
if (hshld.value == "") {
throw "Enter a number!";
}
hshld.style.outline = "none";
// clear input box
}
catch (hshldError) {
hshld.style.outline = "2.5px dashed red";
hshld.placeholder = hshldError;
return false;
}
}
// makes sure that the radio button is selected. If not, throws an error message into the "radioError" paragraph at under the form.
function validatewkCount() {
try {
if (weekCount == 0) {
throw document.getElementById('radioError').innerHTML = "Select a number!";
}
// clear input box
hshld.style.outline = "none";
}
catch (weekCountError) {
radioError.style.outline = "2.5px dashed red";
radioError.placeholder = radioError;
return false;
}
}
// stop the form from submitting if a field needs attention
function endEvent() {
return event.preventDefault();
}
function validateSubmit() {
if(validatehshld() === false && validatewkCount() === false) {
endEvent();
}
}
// EventListeners, includes IE8 compatibility
if (hshld.addEventListener) {
hshld.addEventListener("focusout", validatehshld, false);
} else if (hshld.attachEvent) {
hshld.attachEvent("onclick", validatehshld);
}
// runs validateSubmit() function when the user clicks the submit button
if (mysubmit.addEventListener) {
mysubmit.addEventListener("click", validateSubmit, false);
} else if (mysubmit.attachEvent) {
mysubmit.attachEvent("onclick", validateSubmit);
}
if (mysubmit.addEventListener) {
mysubmit.addEventListener("click", numBottles, false);
} else if (mysubmit.attachEvent) {
mysubmit.attachEvent("onclick", numBottles);
}
// this function gets called via the onclick attribute (line 44)
function numBottles() {
// takes the current value of the input field from id "hshld"
var people = document.getElementById("hshld").value;
var hrrisk = document.getElementById("hrrisk").value;
// this variable represents the number of gallons a single person should have for one week of isolation- 1 gallon per day
var weekWater = 7;
// this variable will hold the number of weeks selected from the radio buttons
var weekCount;
// this code determines which radio button is selected and assigns a value to the variable depending on which radio button is selected
if (document.getElementById('countone').checked) {
var weekCount = 1;
} else if (document.getElementById('counttwo').checked) {
var weekCount = 2;
} else if (document.getElementById('countthree').checked) {
var weekCount = 3;
} else if (document.getElementById('countfour').checked) {
var weekCount = 4;
} else if (isNaN(weekCount) === true) {
var weekCount = 0;
}
// echo out the calculation (people X weekWater) to the span object with id=bottles
document.getElementById("bottles").innerHTML = (people * weekWater * weekCount) + (hrrisk * weekCount);
}
Try not to use try, catch, or throw here, instead create your error message in a new element and place it in the html somewhere you think it looks nice.
I would just use:
if (typeof hshld.value !== 'number') { // if a wrong data type was entered
document.getElementById("error-zone").innerHTML += "<div>Enter a number!</div"
} else {
// continue calculating answer
}
for the quick and dirty method.
Again i'm having trouble with checkboxes. I'm getting info from an API and showing like checkbox. The problem comes when i'm triying to add a validation. This is a part of my code:
(function() {
'use strict';
var fact = {
templateUrl: './app/components/fact.components.html',
controller: factCtrl
};
angular.module('fApp').component('odcFacturas', fact);
factCtrl.$inject = ["$scope", "couponApi"];
function factCtrl($scope, couponApi) {
var vm = this;
vm.clientOrder = null;
vm.all = false;
vm.sendData = function() {
vm.apiData = couponApi.get({
idOrder: vm.idOrder
}).$promise.then(function(data) {
for (var i = 0; i < data.Response.length; i++) {
data.Response[i].Select = vm.all;
}
vm.coupons = data.Response;
vm.combo = data.Response.length > 0;
});
}
Here i call the info, and the next part of my code check all the checkboxes:
vm.selectAll = function() {
for (var i = 0; i < vm.coupons.length; i++) {
vm.coupons[i].Select = vm.all;
}
if (vm.all == 0) {
alert("Select at least one coupon");
}
}
How can I trigger three validations with a submit button? I mean: what I want to do is validate three cases:
if the checkbox "select all checkboxes" is checked, submit
if there's no selected checkboxes, show the alert message
if there's at least one checkbox (or 'n' checkboxes) selected,
submit
On the HTML view i have this:
<div class ="container-fluid">
<div class="row">
<div class="col-md-6">
<div class="cbx input-group">
<div class="checkbox" name="imtesting" ng-show="$ctrl.coupons.length > 0">
<label><input type="checkbox"
ng-show="$ctrl.coupons.length > 0"
name="allCoupons"
ng-model="$ctrl.all"
ng-click="$ctrl.selectAll()"/>Select all coupons</label>
<ul>
<li ng-repeat="c in $ctrl.coupons">
<input type="checkbox"
name="couponBox"
ng-model="c.Select"
ng-click="$ctrl.result()"
required/>{{c.CodeCoupon}}
<br>
</li>
</ul>
<label class="label label-danger" ng-show="submitted == true && !ctrl.newTest()">Select at least one coupon</label>
</div>
</div>
</div>
</div>
Hope you can help me.
Thanx in advance.
You can use the Select property from each coupon object like
vm.canSubmit = function() {
for(var i = 0; i< vm.coupons.length; i++)
{
if (vm.coupons[i].Select) {
return true;
}
}
return false;
}
Redo the way you are handling your selectsAll function. When you are using angular there is a thing called scope.$apply that is actually running which tells the dom to update if the object or properties have changed. Sometimes if you use for loops the way you are using them it wont register a change.
Try this and it should work:
vm.selectAll = function()
{
vm.all = !vm.all;
vm.coupons.forEach(function(o){
o.Select = vm.all;
})
}
vm.submit = function(){
var checked = 0;
vm.coupons.forEach(function(o){
if(o.Select === true)
checked +=1;
})
if(vm.all || checked > 0){
//submit here
}
else if(checked === 0){
//error
}
}
This will work both ways. If checked it will check all and if unchecked it will uncheck all. That validation will work for all three scenarios.
I'm new at Javascript and I'm trying to reveal additional info only if any 2 out of 3 checkboxes are checked.
Here is my code so far (I'm trying to enter my code in the question but It's not working, sorry. I also may have made it more complicated then necessary, sorry again). I did place my code in the Demo.
<script>
var checkboxes;
window.addEvent('domready', function() {
var i, checkbox, textarea, div, textbox;
checkboxes = {};
// link the checkboxes and textarea ids here
checkboxes['checkbox_1'] = 'textarea_1';
checkboxes['checkbox_2'] = 'textarea_2';
checkboxes['checkbox_3'] = 'textarea_3';
for ( i in checkboxes ) {
checkbox = $(i);
textbox = $(checkboxes[i]);
div = $(textbox.id + '_container_div');
div.dissolve();
showHide(i);
addEventToCheckbox(checkbox);
}
function addEventToCheckbox(checkbox) {
checkbox.addEvent('click', function(event) {
showHide(event.target.id);
});
}
});
function showHide(id) {
var checkbox, textarea, div;
if(typeof id == 'undefined') {
return;
}
checkbox = $(id);
textarea = checkboxes[id];
div = $(textarea + '_container_div');
textarea = $(textarea);
if(checkbox.checked) {
div.setStyle('display', 'block');
//div.reveal();
div.setStyle('display', 'block');
textarea.disabled = false;
} else {
div.setStyle('display', 'none');
//div.dissolve();
textarea.value = '';
textarea.disabled = true;
}
}
<label for="choice-positive">
<script type="text/javascript">
function validate(f){
f = f.elements;
for (var c = 0, i = f.length - 1; i > -1; --i)
if (f[i].name && /^colors\[\d+\]$/.test(f[i].name) && f[i].checked) ++c;
return c <= 1;
};
</script>
<label>
<h4><div style="text-align: left"><font color="black">
<input type="checkbox" name="colors[2]" value="address" id="address">Full Address
<br>
<label>
<input type="checkbox" name="colors[3]" value="phone" id="phone">Phone Number <br>
<label>
<input type="checkbox" name="colors[4]" value="account" id="account">Account Number <br>
</form>
<div class="reveal-if-active">
<h2><p style = "text-decoration:underline;"><font color="green">Receive the 2 following
pieces of info:</h2></p>
</style>
Sorry i wasn't able to exactly use the code you provided but tried to change just enough to get it working.
I've uploaded a possible solution to JSFiddle - you essentially can add event listeners to the checkboxes that recheck when clicked how many are selected and show/hide via removing/adding a class e.g. additionalContactBox.classList.remove('reveal-if-active');
I have a form with multiple checkboxes and I want to use JavaScript to make sure at least one is checked. This is what I have right now but no matter what is chosen an alert pops up.
JS (wrong)
function valthis(){
if (document.FC.c1.checked) {
alert ("thank you for checking a checkbox")
} else {
alert ("please check a checkbox")
}
}
HTML
<p>Please select at least one Checkbox</p>
<br>
<br>
<form name = "FC">
<input type = "checkbox" name = "c1" value = "c1"/> C1
<br>
<input type = "checkbox" name = "c1" value = "c2"/> C2
<br>
<input type = "checkbox" name = "c1" value = "c3"/> C3
<br>
<input type = "checkbox" name = "c1" value = "c4"/> C4
<br>
</form>
<br>
<br>
<input type = "button" value = "Edit and Report" onClick = "valthisform();">
So what I ended up doing in JS was this:
function valthisform(){
var chkd = document.FC.c1.checked || document.FC.c2.checked||document.FC.c3.checked|| document.FC.c4.checked
if (chkd == true){
} else {
alert ("please check a checkbox")
}
}
I decided to drop the "Thank you" part to fit in with the rest of the assignment. Thank you so much, every ones advice really helped out.
You should avoid having two checkboxes with the same name if you plan to reference them like document.FC.c1. If you have multiple checkboxes named c1 how will the browser know which you are referring to?
Here's a non-jQuery solution to check if any checkboxes on the page are checked.
var checkboxes = document.querySelectorAll('input[type="checkbox"]');
var checkedOne = Array.prototype.slice.call(checkboxes).some(x => x.checked);
You need the Array.prototype.slice.call part to convert the NodeList returned by document.querySelectorAll into an array that you can call some on.
This should work:
function valthisform()
{
var checkboxs=document.getElementsByName("c1");
var okay=false;
for(var i=0,l=checkboxs.length;i<l;i++)
{
if(checkboxs[i].checked)
{
okay=true;
break;
}
}
if(okay)alert("Thank you for checking a checkbox");
else alert("Please check a checkbox");
}
If you have a question about the code, just comment.
I use l=checkboxs.length to improve the performance. See http://www.erichynds.com/javascript/javascript-loop-performance-caching-the-length-property-of-an-array/
I would opt for a more functional approach. Since ES6 we have been given such nice tools to solve our problems, so why not use them.
Let's begin with giving the checkboxes a class so we can round them up very nicely.
I prefer to use a class instead of input[type="checkbox"] because now the solution is more generic and can be used also when you have more groups of checkboxes in your document.
HTML
<input type="checkbox" class="checkbox" value=ck1 /> ck1<br />
<input type="checkbox" class="checkbox" value=ck2 /> ck2<br />
JavaScript
function atLeastOneCheckboxIsChecked(){
const checkboxes = Array.from(document.querySelectorAll(".checkbox"));
return checkboxes.reduce((acc, curr) => acc || curr.checked, false);
}
When called, the function will return false if no checkbox has been checked and true if one or both is.
It works as follows, the reducer function has two arguments, the accumulator (acc) and the current value (curr). For every iteration over the array, the reducer will return true if either the accumulator or the current value is true.
the return value of the previous iteration is the accumulator of the current iteration, therefore, if it ever is true, it will stay true until the end.
Check this.
You can't access form inputs via their name. Use document.getElements methods instead.
Vanilla JS:
var checkboxes = document.getElementsByClassName('activityCheckbox'); // puts all your checkboxes in a variable
function activitiesReset() {
var checkboxesChecked = function () { // if a checkbox is checked, function ends and returns true. If all checkboxes have been iterated through (which means they are all unchecked), returns false.
for (var i = 0; i < checkboxes.length; i++) {
if (checkboxes[i].checked) {
return true;
}
}
return false;
}
error[2].style.display = 'none'; // an array item specific to my project - it's a red label which says 'Please check a checkbox!'. Here its display is set to none, so the initial non-error label is visible instead.
if (submitCounter > 0 && checkboxesChecked() === false) { // if a form submit has been attempted, and if all checkboxes are unchecked
error[2].style.display = 'block'; // red error label is now visible.
}
}
for (var i=0; i<checkboxes.length; i++) { // whenever a checkbox is checked or unchecked, activitiesReset runs.
checkboxes[i].addEventListener('change', activitiesReset);
}
Explanation:
Once a form submit has been attempted, this will update your checkbox section's label to notify the user to check a checkbox if he/she hasn't yet. If no checkboxes are checked, a hidden 'error' label is revealed prompting the user to 'Please check a checkbox!'. If the user checks at least one checkbox, the red label is instantaneously hidden again, revealing the original label. If the user again un-checks all checkboxes, the red label returns in real-time. This is made possible by JavaScript's onchange event (written as .addEventListener('change', function(){});
You can check that atleast one checkbox is checked or not using this simple code. You can also drop your message.
Reference Link
<label class="control-label col-sm-4">Check Box 2</label>
<input type="checkbox" name="checkbox2" id="checkbox2" value=ck1 /> ck1<br />
<input type="checkbox" name="checkbox2" id="checkbox2" value=ck2 /> ck2<br />
<script>
function checkFormData() {
if (!$('input[name=checkbox2]:checked').length > 0) {
document.getElementById("errMessage").innerHTML = "Check Box 2 can not be null";
return false;
}
alert("Success");
return true;
}
</script>
< script type = "text/javascript" src = "js/jquery-1.6.4.min.js" > < / script >
< script type = "text/javascript" >
function checkSelectedAtleastOne(clsName) {
if (selectedValue == "select")
return false;
var i = 0;
$("." + clsName).each(function () {
if ($(this).is(':checked')) {
i = 1;
}
});
if (i == 0) {
alert("Please select atleast one users");
return false;
} else if (i == 1) {
return true;
}
return true;
}
$(document).ready(function () {
$('#chkSearchAll').click(function () {
var checked = $(this).is(':checked');
$('.clsChkSearch').each(function () {
var checkBox = $(this);
if (checked) {
checkBox.prop('checked', true);
} else {
checkBox.prop('checked', false);
}
});
});
//for select and deselect 'select all' check box when clicking individual check boxes
$(".clsChkSearch").click(function () {
var i = 0;
$(".clsChkSearch").each(function () {
if ($(this).is(':checked')) {}
else {
i = 1; //unchecked
}
});
if (i == 0) {
$("#chkSearchAll").attr("checked", true)
} else if (i == 1) {
$("#chkSearchAll").attr("checked", false)
}
});
});
< / script >
Prevent user from deselecting last checked checkbox.
jQuery (original answer).
$('input[type="checkbox"][name="chkBx"]').on('change',function(){
var getArrVal = $('input[type="checkbox"][name="chkBx"]:checked').map(function(){
return this.value;
}).toArray();
if(getArrVal.length){
//execute the code
$('#msg').html(getArrVal.toString());
} else {
$(this).prop("checked",true);
$('#msg').html("At least one value must be checked!");
return false;
}
});
UPDATED ANSWER 2019-05-31
Plain JS
let i,
el = document.querySelectorAll('input[type="checkbox"][name="chkBx"]'),
msg = document.getElementById('msg'),
onChange = function(ev){
ev.preventDefault();
let _this = this,
arrVal = Array.prototype.slice.call(
document.querySelectorAll('input[type="checkbox"][name="chkBx"]:checked'))
.map(function(cur){return cur.value});
if(arrVal.length){
msg.innerHTML = JSON.stringify(arrVal);
} else {
_this.checked=true;
msg.innerHTML = "At least one value must be checked!";
}
};
for(i=el.length;i--;){el[i].addEventListener('change',onChange,false);}
<label><input type="checkbox" name="chkBx" value="value1" checked> Value1</label>
<label><input type="checkbox" name="chkBx" value="value2"> Value2</label>
<label><input type="checkbox" name="chkBx" value="value3"> Value3</label>
<div id="msg"></div>
$('input:checkbox[type=checkbox]').on('change',function(){
if($('input:checkbox[type=checkbox]').is(":checked") == true){
$('.removedisable').removeClass('disabled');
}else{
$('.removedisable').addClass('disabled');
});
if(($("#checkboxid1").is(":checked")) || ($("#checkboxid2").is(":checked"))
|| ($("#checkboxid3").is(":checked"))) {
//Your Code here
}
You can use this code to verify that checkbox is checked at least one.
Thanks!!