Add asterisk only if label text is available - html

I am trying to add an asterisk to a label text of an input, if the input filed is required. I used this answer and referred this answer and I can get the desired result using the following code
jQuery(function() {
jQuery("[required]").before(jQuery("<span>", {
class: "required"
}).html("*"));
});
However, I do not want the asterisk to be added for input fields where the label texts are not available.
Look at the following where a label text is not available;
<label>
<span class="required">*</span>
<input type="text" class="form-control" id="perm_city" name="perm_city" required="required" />
</label>
as opposed to the following where a label text is available
<label for="clientid">Client ID Number
<span class="required">*</span>
<input type="text" class="form-control" id="clientid" name="clientid" required="required" />
</label>
Both has the asterisk added before the input element by my jQuery script. But the desired output is as follows;
Can anyone help me achieve this? TIA

You can use .each loop to iterate through all required inputs then using .clone & .text() get the label texts ignoring all children it has . Then , if the length of text is greater then 0 append your span.
Demo Code :
jQuery(function() {
//loop through required input
jQuery("[required]").each(function() {
//get label and remove child only get text
var cloned = jQuery(this).closest("label").clone().children().remove().end().text().trim();
console.log("Length--" + cloned.length)
//check if txt length is > 0
if (cloned.length > 0) {
jQuery(this).before(jQuery("<span>", {
class: "required"
}).html("*"));
}
})
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<label>
<input type="text" class="form-control" id="perm_city" name="perm_city" required="required" />
</label><br>
<label for="clientid">Client ID Number
<input type="text" class="form-control" id="clientid" name="clientid" required="required" />
</label><br>
<label for="clientid">Client ID Number1
<input type="text" class="form-control" id="clientid" name="clientid" required="required" />
</label><br>
<label for="clientid">
<input type="text" class="form-control" id="clientid" name="clientid" required="required" />
</label>

If this is how your labels are included, then you can clone each <label> element and remove its children, then check if any text remains. This is what I mean (I am not familiar with jQuery, so I will write in vanilla JS):
var labels = document.querySelectorAll("label");
for (var i = 0; i < labels.length; i++) {
var clonedLabel = labels[i].cloneNode(true);
var chldrn = clonedLabel.children.length;
for (var j = 0; j < chldrn; j++) {
clonedLabel.removeChild(clonedLabel.children[0]);
}
// Remove spaces
var innerHTML = clonedLabel.innerHTML.trim();
if (innerHTML != "") {
// Add the asterisk
var span = document.createElement("span");
span.className = "required";
span.innerHTML = "*";
labels[i].insertBefore(span,labels[i].children[0]);
}
}

Related

Stop chrome auto filling / suggesting form fields by id

Ok so...like many other posts this is driving me nuts. Chrome is continually offering autocomplete suggestions for fields that I would rather it not be on. It, along with the soft keyboard take up the whole page which blocks the view for the user / the form is not intended to fill our the users data but rather a new address that would be previously unknown.
So far I've got these both on
<form autocomplete="off">
and
<input autocomplete="randomstringxxx">
Their effect is noticed and chrome is no longer filling the whole form - but it STILL wants to suggest single field suggestions for each element in my form.
I've finally realised that its now picking up the id/name fields from my form elements.
i.e the below will give me a list of names I have used before.
<input id="contact_name" name="contact_name">
Can anyone suggest a way to stop this without renaming the elements? They are tied to fields in my database and ideally I would not have to manually rename and match up these together.
example -
https://jsfiddle.net/drsx4w1e/
with random strings as autocomplete element attribute - STILL AUTOCOMPLETING
https://jsfiddle.net/drsx4w1e/1/
with "off" as autocomplete attribute. - STILL AUTOCOMPLETING
https://jsfiddle.net/6bgoj23d/1/
example no autocomplete when labels / ids/ name attr are removed - NOT AUTOCOMPLETING
example
I know this isn't ideal because it changes the name of the inputs but it only does it temporarily. Changing the name attribute is the only way I found that completely removes the autocomplete.
This solution is all in JS and HTML but I think it would be better if it was implemented with a server side language such as PHP or Java.
I found autocomplete="none" works best for chrome but it doesn't fully turn off auto complete.
How it works
So, on page load this solution adds a string of random characters to each input name.
eg. 'delivery_contact_name' becomes 'delivery_contact_nameI5NTE'
When the form is submitted it calls a function (submission()) which removes the random character that were added. So the submitted form data will have the original names.
See solution below:
<html>
<body>
<form autocomplete="none" id="account_form" method="post" action="" onsubmit="return submission();">
<div class="my-2">
<label for="delivery_contact_name" class="">*</label>
<input autocomplete="none" class="form-control" id="delivery_contact_name" maxlength="200" minlength="2" name="delivery_contact_name" required="" type="text" value="">
</div>
<div class="my-2">
<label for="delivery_telephone" class="">Telephone*</label>
<input autocomplete="none" class="form-control" id="delivery_telephone" maxlength="200" minlength="8" name="delivery_telephone" required="" type="tel" value="">
</div>
<div class="my-2">
<label for="delivery_address_1" class="">Delivery Address*</label>
<input autocomplete="none" class="form-control" id="delivery_address_1" maxlength="50" minlength="2" name="delivery_address_1" required="" type="text" value="">
</div>
<div class="my-2">
<label for="delivery_address_2" class="">Delivery Address*</label>
<input autocomplete="none" class="form-control" id="delivery_address_2" maxlength="50" minlength="2" name="delivery_address_2" required="" type="text" value="">
</div>
<div class="my-2">
<label for="delivery_address_3" class="">Delivery Address</label>
<input autocomplete="none" class="form-control" id="delivery_address_3" name="delivery_address_3" type="text" value="">
</div>
<div class="my-2">
<label for="delivery_address_4" class="">Delivery Address</label>
<input autocomplete="none" class="form-control" id="delivery_address_4" name="delivery_address_4" type="text" value="">
</div>
<div class="my-2">
<label for="delivery_address_postcode" class="">Delivery Postcode*</label>
<input autocomplete="none" class="form-control" id="delivery_address_postcode" maxlength="10" minlength="6" name="delivery_address_postcode" required="" type="text" value="">
</div>
<input type="submit" name="submit" value="Send">
</form>
</body>
<script>
//generate a random string to append to the names
const autocompleteString = btoa(Math.random().toString()).substr(10, 5);
//get all the inputs in the form
const inputs = document.querySelectorAll("input");
//make sure script calls function after page load
document.addEventListener("DOMContentLoaded", function(){
changeInputNames();
});
//add random characters to input names
function changeInputNames(){
for (var i = 0; i < inputs.length; i++) {
inputs[i].setAttribute("name", inputs[i].getAttribute("name")+autocompleteString);
}
}
//remove the random characters from input names
function changeInputNamesBack(){
for (var i = 0; i < inputs.length; i++) {
inputs[i].setAttribute("name", inputs[i].getAttribute("name").replace(autocompleteString, ''));
}
}
function submission(){
let valid = true;
//do any additional form validation here
if(valid){
changeInputNamesBack();
}
return valid;
}
</script>
</html>
Thanks to #rydog for his help. I've changed it into a function that I've put into a my js file as I didn't want to manually add to each page / fire on every page - I have also added the submit event handler with js rather than adding to the on submit of the form.
GREAT SOLUTION by Rydog
function stop_autofill() {
//generate a random string to append to the names
this.autocompleteString = btoa(Math.random().toString()).substr(10, 5);
this.add_submit_handlers = () => {
document.querySelectorAll("form").forEach(value => {
value.addEventListener("submit", (e) => {
this.form_submit_override(e)
})
})
}
//add random characters to input names
this.changeInputNames = () => {
for (var i = 0; i < this.input_elements_arr.length; i++) {
this.input_elements_arr[i].setAttribute("name", this.input_elements_arr[i].getAttribute("name") + this.autocompleteString);
}
}
//remove the random characters from input names
this.changeInputNamesBack = () => {
for (var i = 0; i < this.input_elements_arr.length; i++) {
this.input_elements_arr[i].setAttribute("name", this.input_elements_arr[i].getAttribute("name").replace(this.autocompleteString, ''));
}
}
this.form_submit_override = (e) => {
e.preventDefault()
this.changeInputNamesBack()
e.currentTarget.submit()
return true
}
this.setup_form = () => {
//get all the inputs in the form
this.input_elements_arr = document.querySelectorAll("input");
this.changeInputNames();
this.add_submit_handlers();
}
//make sure script calls function after page load
this.init = () => {
if (document.readyState === "complete") {
this.setup_form()
} else {
let setup_form = this.setup_form
document.addEventListener("DOMContentLoaded", function (e) {
setup_form()
})
}
}
}
on the page that needs it
<script>
af = new stop_autofill()
af.init()
</script>

Storing checkbox tag values to an Javascript Object and String value via JSON

I'm probably making some rookie mistakes, but my brain is drained trying to figure out where I went wrong. I have an HTML form, and I need to store JUST the values of the checked selections in an script object (if it's deselected, it should be removed from the object), as well as convert the object into a string. Problem is, I haven't ever had to mix checkboxes with Javascript, and I'm completely lost. When I debug, it completely ignores the function. Any help would be greatly appreciated.
HTML for the form:
<form method="post" action="http://webdevbasics.net/scripts/demo.php">
<div id="errorText"></div>
<fieldset id="faq">
<label for="uname">Name:</label>
<input type="text" name="uname" id="uname" required="required">
<label for="email">E-mail:</label>
<input type="text" name="email" id="email" required="required">
<label for="nature" required="required">Nature of your question:</label>
<input type="checkbox" name="nature" id="A" value="A">Option A
<input type="checkbox" name="nature" id="B" value="B">Option B
<input type="checkbox" name="nature" id="C" value="C">Option C</br>
<input type="checkbox" name="nature" id="D" value="D">Option D
<input type="checkbox" name="nature" id="other" value="other">Other
<label for="question">Question(s):</label>
<textarea name="question" id="question" rows="10" cols="50" required="required">
</textarea>
</fieldset><p>
<input id="submit" type="submit" value="Submit">
</form><p>
And here's the Javascript:
"use strict";
var natureObject = new Object();
var natureSubmission = "";
function checkboxObject() {
var checkBoxes = document.getElementsByClassName("box");
natureObject = {};
for (var i = 0; i < checkBoxes.length; i++) {
if (checkBoxes[i].checked) {
natureObject[fields[i].name] = checkBoxes[i].value;
}
}
}
function createString() {
natureSubmission = JSON.stringify(natureObject);
}
/* create event listeners */
function createEventListeners() {
var box = document.getElementsByClassName("box");
if (box.addEventListener) {
box.addEventListener("change", checkboxObject, false);
} else if (box.attachEvent) {
box.attachEvent("onchange", checkboxObject);
}
}
if (window.addEventListener) {
window.addEventListener("load", createEventListeners, false);
} else if (window.attachEvent) {
window.attachEvent("onload", createEventListeners);
}
"nature" is not tagName, tagName is "input".
I suggest to add a class for all checkboxes and use getElementsByClassName(), then iterate over them with a for loop.
As a side note, I am unsure whether you can have multiple checkboxes with the same name in a form submission though.

HTML form: onblur event does not work when id and name changed

I have this HTML form which works fine when written like this:
<fieldset>
<label for="name">Name</label>
<input type="text" name="name" id="name" onblur="validateName(name)" />
<span id="nameError" style="display: none;">You can only use alphabetic characters, hyphens and apostrophes</span>
</fieldset>
But when I change 3rd and 4th line to:
<input type="text" name="firstname" id="firstname" onblur="validateName(firstname)" />
<span id="firstnameError" style="display: none;">You can only use alphabetic characters, hyphens and apostrophes</span>
, onblur doesn't work! How could it be? After all i just changed the name and ID?
This is my validateName(name) function:
function validateName(x) {
// Validation rule
var re = /[A-Za-z -']$/;
// Check input
if (re.test(document.getElementById(x).value)) {
// Style green
document.getElementById(x).style.background = '#ccffcc';
// Hide error prompt
document.getElementById(x + 'Error').style.display = "none";
return true;
} else {
// Style red
document.getElementById(x).style.background = '#e35152';
// Show error prompt
document.getElementById(x + 'Error').style.display = "block";
return false;
}
}
thanks
You need to change ID of error element too (because of x + Error).
<span id="firstnameError"...>
And put function params into quotes:
<input type="text" name="firstname" id="firstname" onblur="validateName('firstname')" />
http://jsfiddle.net/Lgp55uwo/

minimum one required for checkboxes with same name [duplicate]

When using the newer browsers that support HTML5 (FireFox 4 for example);
and a form field has the attribute required='required';
and the form field is empty/blank;
and the submit button is clicked;
the browsers detects that the "required" field is empty and does not submit the form; instead browser shows a hint asking the user to type text into the field.
Now, instead of a single text field, I have a group of checkboxes, out of which at least one should be checked/selected by the user.
How can I use the HTML5 required attribute on this group of checkboxes?
(Since only one of the checkboxes needs to be checked, I can't put the required attribute on each and every checkbox)
ps. I am using simple_form, if that matters.
UPDATE
Could the HTML 5 multiple attribute be helpful here? Has anyone use it before for doing something similar to my question?
UPDATE
It appears that this feature is not supported by the HTML5 spec: ISSUE-111: What does input.#required mean for #type = checkbox?
(Issue status: Issue has been marked closed without prejudice.)
And here is the explanation.
UPDATE 2
It's an old question, but wanted to clarify that the original intent of the question was to be able to do the above without using Javascript - i.e. using a HTML5 way of doing it. In retrospect, I should've made the "without Javascript" more obvious.
Unfortunately HTML5 does not provide an out-of-the-box way to do that.
However, using jQuery, you can easily control if a checkbox group has at least one checked element.
Consider the following DOM snippet:
<div class="checkbox-group required">
<input type="checkbox" name="checkbox_name[]">
<input type="checkbox" name="checkbox_name[]">
<input type="checkbox" name="checkbox_name[]">
<input type="checkbox" name="checkbox_name[]">
</div>
You can use this expression:
$('div.checkbox-group.required :checkbox:checked').length > 0
which returns true if at least one element is checked.
Based on that, you can implement your validation check.
Its a simple trick. This is jQuery code that can exploit the html5 validation by changing the required properties if any one is checked. Following is your html code (make sure that you add required for all the elements in the group.)
<input type="checkbox" name="option[]" id="option-1" value="option1" required/> Option 1
<input type="checkbox" name="option[]" id="option-2" value="option2" required/> Option 2
<input type="checkbox" name="option[]" id="option-3" value="option3" required/> Option 3
<input type="checkbox" name="option[]" id="option-4" value="option4" required/> Option 4
<input type="checkbox" name="option[]" id="option-5" value="option5" required/> Option 5
Following is jQuery script, which disables further validation check if any one is selected. Select using name element.
$cbx_group = $("input:checkbox[name='option[]']");
$cbx_group = $("input:checkbox[id^='option-']"); // name is not always helpful ;)
$cbx_group.prop('required', true);
if($cbx_group.is(":checked")){
$cbx_group.prop('required', false);
}
Small gotcha here: Since you are using html5 validation, make sure you execute this before the it gets validated i.e. before form submit.
// but this might not work as expected
$('form').submit(function(){
// code goes here
});
// So, better USE THIS INSTEAD:
$('button[type="submit"]').on('click', function() {
// skipping validation part mentioned above
});
HTML5 does not directly support requiring only one/at least one checkbox be checked in a checkbox group. Here is my solution using Javascript:
HTML
<input class='acb' type='checkbox' name='acheckbox[]' value='1' onclick='deRequire("acb")' required> One
<input class='acb' type='checkbox' name='acheckbox[]' value='2' onclick='deRequire("acb")' required> Two
JAVASCRIPT
function deRequireCb(elClass) {
el = document.getElementsByClassName(elClass);
var atLeastOneChecked = false; //at least one cb is checked
for (i = 0; i < el.length; i++) {
if (el[i].checked === true) {
atLeastOneChecked = true;
}
}
if (atLeastOneChecked === true) {
for (i = 0; i < el.length; i++) {
el[i].required = false;
}
} else {
for (i = 0; i < el.length; i++) {
el[i].required = true;
}
}
}
The javascript will ensure at least one checkbox is checked, then de-require the entire checkbox group. If the one checkbox that is checked becomes un-checked, then it will require all checkboxes, again!
I guess there's no standard HTML5 way to do this, but if you don't mind using a jQuery library, I've been able to achieve a "checkbox group" validation using webshims' "group-required" validation feature:
The docs for group-required say:
If a checkbox has the class 'group-required' at least one of the
checkboxes with the same name inside the form/document has to be
checked.
And here's an example of how you would use it:
<input name="checkbox-group" type="checkbox" class="group-required" id="checkbox-group-id" />
<input name="checkbox-group" type="checkbox" />
<input name="checkbox-group" type="checkbox" />
<input name="checkbox-group" type="checkbox" />
<input name="checkbox-group" type="checkbox" />
I mostly use webshims to polyfill HTML5 features, but it also has some great optional extensions like this one.
It even allows you to write your own custom validity rules. For example, I needed to create a checkbox group that wasn't based on the input's name, so I wrote my own validity rule for that...
we can do this easily with html5 also, just need to add some jquery code
Demo
HTML
<form>
<div class="form-group options">
<input type="checkbox" name="type[]" value="A" required /> A
<input type="checkbox" name="type[]" value="B" required /> B
<input type="checkbox" name="type[]" value="C" required /> C
<input type="submit">
</div>
</form>
Jquery
$(function(){
var requiredCheckboxes = $('.options :checkbox[required]');
requiredCheckboxes.change(function(){
if(requiredCheckboxes.is(':checked')) {
requiredCheckboxes.removeAttr('required');
} else {
requiredCheckboxes.attr('required', 'required');
}
});
});
Inspired by the answers from #thegauraw and #Brian Woodward, here's a bit I pulled together for JQuery users, including a custom validation error message:
$cbx_group = $("input:checkbox[name^='group']");
$cbx_group.on("click", function () {
if ($cbx_group.is(":checked")) {
// checkboxes become unrequired as long as one is checked
$cbx_group.prop("required", false).each(function () {
this.setCustomValidity("");
});
} else {
// require checkboxes and set custom validation error message
$cbx_group.prop("required", true).each(function () {
this.setCustomValidity("Please select at least one checkbox.");
});
}
});
Note that my form has some checkboxes checked by default.
Maybe some of you JavaScript/JQuery wizards could tighten that up even more?
I added an invisible radio to a group of checkboxes.
When at least one option is checked, the radio is also set to check.
When all options are canceled, the radio is also set to cancel.
Therefore, the form uses the radio prompt "Please check at least one option"
You can't use display: none because radio can't be focused.
I make the radio size equal to the entire checkboxes size, so it's more obvious when prompted.
HTML
<form>
<div class="checkboxs-wrapper">
<input id="radio-for-checkboxes" type="radio" name="radio-for-required-checkboxes" required/>
<input type="checkbox" name="option[]" value="option1"/>
<input type="checkbox" name="option[]" value="option2"/>
<input type="checkbox" name="option[]" value="option3"/>
</div>
<input type="submit" value="submit"/>
</form>
Javascript
var inputs = document.querySelectorAll('[name="option[]"]')
var radioForCheckboxes = document.getElementById('radio-for-checkboxes')
function checkCheckboxes () {
var isAtLeastOneServiceSelected = false;
for(var i = inputs.length-1; i >= 0; --i) {
if (inputs[i].checked) isAtLeastOneCheckboxSelected = true;
}
radioForCheckboxes.checked = isAtLeastOneCheckboxSelected
}
for(var i = inputs.length-1; i >= 0; --i) {
inputs[i].addEventListener('change', checkCheckboxes)
}
CSS
.checkboxs-wrapper {
position: relative;
}
.checkboxs-wrapper input[name="radio-for-required-checkboxes"] {
position: absolute;
margin: 0;
top: 0;
left: 0;
width: 100%;
height: 100%;
-webkit-appearance: none;
pointer-events: none;
border: none;
background: none;
}
https://jsfiddle.net/codus/q6ngpjyc/9/
I had the same problem and I my solution was this:
HTML:
<form id="processForm.php" action="post">
<div class="input check_boxes required wish_payment_type">
<div class="wish_payment_type">
<span class="checkbox payment-radio">
<label for="wish_payment_type_1">
<input class="check_boxes required" id="wish_payment_type_1" name="wish[payment_type][]" type="checkbox" value="1">Foo
</label>
</span>
<span class="checkbox payment-radio">
<label for="wish_payment_type_2">
<input class="check_boxes required" id="wish_payment_type_2" name="wish[payment_type][]" type="checkbox" value="2">Bar
</label>
</span>
<span class="checkbox payment-radio">
<label for="wish_payment_type_3">
<input class="check_boxes required" id="wish_payment_type_3" name="wish[payment_type][]" type="checkbox" value="3">Buzz
</label>
<input id='submit' type="submit" value="Submit">
</div>
</form>
JS:
var verifyPaymentType = function () {
var checkboxes = $('.wish_payment_type .checkbox');
var inputs = checkboxes.find('input');
var first = inputs.first()[0];
inputs.on('change', function () {
this.setCustomValidity('');
});
first.setCustomValidity(checkboxes.find('input:checked').length === 0 ? 'Choose one' : '');
}
$('#submit').click(verifyPaymentType);
https://jsfiddle.net/oywLo5z4/
You don't need jQuery for this. Here's a vanilla JS proof of concept using an event listener on a parent container (checkbox-group-required) of the checkboxes, the checkbox element's .checked property and Array#some.
const validate = el => {
const checkboxes = el.querySelectorAll('input[type="checkbox"]');
return [...checkboxes].some(e => e.checked);
};
const formEl = document.querySelector("form");
const statusEl = formEl.querySelector(".status-message");
const checkboxGroupEl = formEl.querySelector(".checkbox-group-required");
checkboxGroupEl.addEventListener("click", e => {
statusEl.textContent = validate(checkboxGroupEl) ? "valid" : "invalid";
});
formEl.addEventListener("submit", e => {
e.preventDefault();
if (validate(checkboxGroupEl)) {
statusEl.textContent = "Form submitted!";
// Send data from e.target to your backend
}
else {
statusEl.textContent = "Error: select at least one checkbox";
}
});
<form>
<div class="checkbox-group-required">
<input type="checkbox">
<input type="checkbox">
<input type="checkbox">
<input type="checkbox">
</div>
<input type="submit" />
<div class="status-message"></div>
</form>
If you have multiple groups to validate, add a loop over each group, optionally adding error messages or CSS to indicate which group fails validation:
const validate = el => {
const checkboxes = el.querySelectorAll('input[type="checkbox"]');
return [...checkboxes].some(e => e.checked);
};
const allValid = els => [...els].every(validate);
const formEl = document.querySelector("form");
const statusEl = formEl.querySelector(".status-message");
const checkboxGroupEls = formEl.querySelectorAll(".checkbox-group-required");
checkboxGroupEls.forEach(el =>
el.addEventListener("click", e => {
statusEl.textContent = allValid(checkboxGroupEls) ? "valid" : "invalid";
})
);
formEl.addEventListener("submit", e => {
e.preventDefault();
if (allValid(checkboxGroupEls)) {
statusEl.textContent = "Form submitted!";
}
else {
statusEl.textContent = "Error: select at least one checkbox from each group";
}
});
<form>
<div class="checkbox-group-required">
<label>
Group 1:
<input type="checkbox">
<input type="checkbox">
<input type="checkbox">
<input type="checkbox">
</label>
</div>
<div class="checkbox-group-required">
<label>
Group 2:
<input type="checkbox">
<input type="checkbox">
<input type="checkbox">
<input type="checkbox">
</label>
</div>
<input type="submit" />
<div class="status-message"></div>
</form>
I realize there are a ton of solutions here, but I found none of them hit every requirement I had:
No custom coding required
Code works on page load
No custom classes required (checkboxes or their parent)
I needed several checkbox lists to share the same name for submitting Github issues via their API, and was using the name label[] to assign labels across many form fields (two checkbox lists and a few selects and textboxes) - granted I could have achieved this without them sharing the same name, but I decided to try it, and it worked.
The only requirement for this one is jQuery, which could easily be eliminated if you wanted to rewrite it in vanilla JS. You can combine this with #ewall's great solution to add custom validation error messages.
/* required checkboxes */
jQuery(function ($) {
var $requiredCheckboxes = $("input[type='checkbox'][required]");
/* init all checkbox lists */
$requiredCheckboxes.each(function (i, el) {
//this could easily be changed to suit different parent containers
var $checkboxList = $(this).closest("div, span, p, ul, td");
if (!$checkboxList.hasClass("requiredCheckboxList"))
$checkboxList.addClass("requiredCheckboxList");
});
var $requiredCheckboxLists = $(".requiredCheckboxList");
$requiredCheckboxLists.each(function (i, el) {
var $checkboxList = $(this);
$checkboxList.on("change", "input[type='checkbox']", function (e) {
updateCheckboxesRequired($(this).parents(".requiredCheckboxList"));
});
updateCheckboxesRequired($checkboxList);
});
function updateCheckboxesRequired($checkboxList) {
var $chk = $checkboxList.find("input[type='checkbox']").eq(0),
cblName = $chk.attr("name"),
cblNameAttr = "[name='" + cblName + "']",
$checkboxes = $checkboxList.find("input[type='checkbox']" + cblNameAttr);
if ($checkboxList.find(cblNameAttr + ":checked").length > 0) {
$checkboxes.prop("required", false);
} else {
$checkboxes.prop("required", true);
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form method="post" action="post.php">
<div>
Type of report:
</div>
<div>
<input type="checkbox" id="chkTypeOfReportError" name="label[]" value="Error" required>
<label for="chkTypeOfReportError">Error</label>
<input type="checkbox" id="chkTypeOfReportQuestion" name="label[]" value="Question" required>
<label for="chkTypeOfReportQuestion">Question</label>
<input type="checkbox" id="chkTypeOfReportFeatureRequest" name="label[]" value="Feature Request" required>
<label for="chkTypeOfReportFeatureRequest">Feature Request</label>
</div>
<div>
Priority
</div>
<div>
<input type="checkbox" id="chkTypeOfContributionBlog" name="label[]" value="Priority: High" required>
<label for="chkPriorityHigh">High</label>
<input type="checkbox" id="chkTypeOfContributionBlog" name="label[]" value="Priority: Medium" required>
<label for="chkPriorityMedium">Medium</label>
<input type="checkbox" id="chkTypeOfContributionLow" name="label[]" value="Priority: Low" required>
<label for="chkPriorityMedium">Low</label>
</div>
<div>
<input type="submit" />
</div>
</form>
Really simple way to verify if at least one checkbox is checked:
function isAtLeastOneChecked(name) {
let checkboxes = Array.from(document.getElementsByName(name));
return checkboxes.some(e => e.checked);
}
Then you can implement whatever logic you want to display an error.
Here is another simple trick using Jquery!!
HTML
<form id="hobbieform">
<div>
<input type="checkbox" name="hobbies[]">Coding
<input type="checkbox" name="hobbies[]">Gaming
<input type="checkbox" name="hobbies[]">Driving
</div>
</form>
JQuery
$('#hobbieform').on("submit", function (e) {
var arr = $(this).serialize().toString();
if(arr.indexOf("hobbies") < 0){
e.preventDefault();
alert("You must select at least one hobbie");
}
});
That's all.. this works because if none of the checkbox is selected, nothing as regards the checkbox group(including its name) is posted to the server
Pure JS solution:
const group = document.querySelectorAll('[name="myCheckboxGroup"]');
function requireLeastOneChecked() {
var atLeastOneChecked = false;
for (i = 0; i < group.length; i++)
if (group[i].checked)
atLeastOneChecked = true;
if (atLeastOneChecked)
for (i = 0; i < group.length; i++)
group[i].required = false;
else
for (i = 0; i < group.length; i++)
group[i].required = true;
}
requireLeastOneChecked(); // onload
group.forEach(function ($el) {
$el.addEventListener('click', function () { requireLeastOneChecked(); })
});
Hi just use a text box additional to group of check box.When clicking on any check box put values in to that text box.Make that that text box required and readonly.
A general Solution without change the submit event or knowing the name of the checkboxes
Build a Function, which marks the Checkbox as HTML5-Invalid
Extend Change-Event and check validity on the start
jQuery.fn.getSiblingsCheckboxes = function () {
let $this = $(this);
let $parent = $this.closest('form, .your-checkbox-listwrapper');
return $parent.find('input[type="checkbox"][name="' + $this.attr('name')+'"]').filter('*[required], *[data-required]');
}
jQuery.fn.checkRequiredInputs = function() {
return this.each(function() {
let $this = $(this);
let $parent = $this.closest('form, .your-checkbox-list-wrapper');
let $allInputs = $this.getSiblingsCheckboxes();
if ($allInputs.filter(':checked').length > 0) {
$allInputs.each(function() {
// this.setCustomValidity(''); // not needed
$(this).removeAttr('required');
$(this).closest('li').css('color', 'green'); // for debugging only
});
} else {
$allInputs.each(function() {
// this.reportValidity(); // not needed
$(this).attr('required', 'required');
$(this).closest('li').css('color', 'red'); // for debugging only
});
}
return true;
});
};
$(document).ready(function() {
$('input[type="checkbox"][required="required"], input[type="checkbox"][required]').not('*[data-required]').not('*[disabled]').each(function() {
let $input = $(this);
let $allInputs = $input.getSiblingsCheckboxes();
$input.attr('data-required', 'required');
$input.removeAttr('required');
$input.on('change', function(event) {
$input.checkRequiredInputs();
});
});
$('input[type="checkbox"][data-required="required"]').checkRequiredInputs();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
</head>
<form>
<ul>
<li><input type="checkbox" id="checkbox1" name="countries" value="Argentina" required="required">Argentina</li>
<li><input type="checkbox" id="checkbox2" name="countries" value="France" required="required">France</li>
<li><input type="checkbox" id="checkbox3" name="countries" value="Germany" required="required">Germany</li>
<li><input type="checkbox" id="checkbox4" name="countries" value="Japan" required="required">Japan</li>
<li><input type="checkbox" id="checkbox5" name="countries" value="Australia" required="required">Australia</li>
</ul>
<input type="submit" value="Submit">
</form>
Try:
self.request.get('sports_played', allow_multiple=True)
or
self.request.POST.getall('sports_played')
More specifically:
When you are reading data from the checkbox array, make sure array has:
len>0
In this case:
len(self.request.get('array', allow_multiple=True)) > 0

If checkbox is checked add new input box [duplicate]

This question already has answers here:
Show box or input box on checked box
(2 answers)
Closed 8 years ago.
I have a form like this
<form >
<input type="text" placeholder="First Name" required id="fname" name="fname"/>
<input type="text" placeholder="Last Name" required id="lname" name="lname"/>
<input type="checkbox" placeholder="Maiden Name" id="Maiden Name" name="chkname"/>
<input type="hidden" placeholder="Maiden Name" id="mname" name="mname"/>
...
</form>
and if the checkbox is checked then the maiden name input box should be visible, can anyone help me with this.
In this instance, it's possible to do this without JavaScript, just use the :checked pseudo class:
EXAMPLE HERE
#mname {
display:none;
}
#maidenname:checked ~ #mname {
display:block;
}
Use either the general sibling combinator, ~, or the adjacent sibling combinator +, to change the display of the input element when the checkbox element is toggled. This of course assumes that the checkbox precedes the input element in the DOM.
If you would rather use JavaScript, you could use the following:
JS EXAMPLE HERE
var checkbox = document.getElementById('maidenname');
var input = document.getElementById('mname');
checkbox.addEventListener('click', function () {
if (input.style.display != 'block') {
input.style.display = 'block';
} else {
input.style.display = '';
}
});
Alternatively, if you would rather add an input element to the DOM (as your title implies), rather than changing the visibility of it, you could use something like this:
ALTERNATIVE JS EXAMPLE HERE
var checkbox = document.getElementById('maidenname');
checkbox.addEventListener('click', function () {
if (document.getElementById('mn')) {
document.getElementById('mn').remove();
} else {
var input = document.createElement("input");
input.id = 'mn';
input.type = 'text';
input.placeholder = 'Maiden Name';
document.body.appendChild(input);
}
});
you should not use maiden name input box as type="hidden". Use it as below:
<input type="text" style=" display:none" placeholder="Maiden Name" id="mname" name="mname"/>
Call function to toggle display on click of checkbox:
<input onchange="showHideControl();" type="checkbox" placeholder="Maiden Name" id="Maiden Name" name="chkname"/>
Toggle maiden name input box:
function showHideControl()
{
$('#mname').toggle();
}
You can do it using pure javascript, like so:
<form id=frmMain name=frmMain>
<input type="text" placeholder="First Name" required id="fname" name="fname"/>
<input type="text" placeholder="Last Name" required id="lname" name="lname"/>
<input type="checkbox" placeholder="Maiden Name" id="chkname" name="chkname" onclick=javascript:document.frmMain.mname.hidden=!document.frmMain.chkname.checked; />
<input type="input" hidden=true placeholder="Maiden Name" id="mname" name="mname"/>
...
</form>