JavaScript refactoring not working as expected - javascript

I have this bit of repeated code that toggles 2 radio button from being checked in my $(document).ready():
$(document).ready(function () {
$("#New").click(function () {
var toggleOn = $("#New");
var toggleOff = $("#Used");
var value = true;
toggleOn.prop("checked", value);
toggleOn.val(value);
toggleOff.prop("checked", !value);
toggleOff.val(!value);
});
$("#Used").click(function () {
var toggleOn = $("#Used");
var toggleOff = $("#New");
var value = true;
toggleOn.prop("checked", value);
toggleOn.val(value);
toggleOff.prop("checked", !value);
toggleOff.val(!value);
});
});
I didn't want to have the repeated code so I refactored it into a function:
$(document).ready(function () {
$("#Used").on("click", toggleRadioButtons("Used", "New"));
$("#New").on("click", toggleRadioButtons("New", "Used"));
});
function toggleRadioButtons(radioOne, radioTwo) {
var toggleOn = $("#" + radioOne);
var toggleOff = $("#" + radioTwo);
var value = true;
toggleOn.prop("checked", value);
toggleOn.val(value);
toggleOff.prop("checked", !value);
toggleOff.val(!value);
}
So the problem is that with the refactored code the radio button is no longer properly unchecking the other radio button. I assuming it has to do with JavaScript closure but am not sure how that would apply since I am calling a function in it's outer scope.

If you give both radio buttons the same name, then only one will only be able to be selected at a time.
No need for jQuery at all.
form {
display: grid;
grid-auto-flow: column;
justify-content: center;
grid-column-gap: 2em;
}
<form name="car">
<label>New <input type="radio" name="condition" value="new" /></label>
<label>Used <input type="radio" name="condition" value="used" /></label>
</form>
If you want them to be checkboxes, you can link them with a jQuery plugin. I called it syncCheckboxes and the code can be found below.
(function($) {
$.syncCheckboxes = function(...ids) {
const $checkboxes = ids.map(id => $(id));
$checkboxes.forEach(function($checkbox) {
$checkbox.on('click', function(e) {
if ($(this).prop('checked')) {
$checkboxes.forEach(function($curr) {
$curr.prop('checked', $curr === $checkbox);
});
}
})
});
};
})(jQuery);
$.syncCheckboxes('#New', '#Used');
form {
display: grid;
grid-auto-flow: column;
justify-content: center;
grid-column-gap: 2em;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form name="car">
<label>New <input type="checkbox" id="New" value="new" /></label>
<label>Used <input type="checkbox" id="Used" value="used" /></label>
</form>

Related

javascript check all and uncheck all checkbox

I have select all check box with some option when i click select all i select all the option and when i remove the select all i remove it from all option and the code below work for that.
What i try to do is when i unselect one of the option the select all box should be unselected and if i select all the option without selecting the select all option the check all box should be selected.
How can i do that?
let checkboxes = document.querySelectorAll("input[type = 'checkbox']");
function checkAll(myCheckBox) {
if (myCheckBox.checked == true) {
checkboxes.forEach(function(checkbox) {
checkbox.checked = true;
});
} else {
checkboxes.forEach(function(checkbox) {
checkbox.checked = false;
});
}
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
min-height: 100vh;
display: grid;
place-content: center;
}
input[type="checkbox"] {
margin-bottom: 10px;
cursor: pointer;
}
input[type="checkbox"]:not(:first-child) {
margin-left: 20px;
}
<div class="container">
<input type="checkbox" id="check-all" onchange="checkAll(this)">
<label for="check-all">Select All</label>
<br/>
<input type="checkbox" id="option-a">
<label for="option-a">Option A</label>
<br/>
<input type="checkbox" id="option-b">
<label for="option-b">Option B</label>
<br/>
<input type="checkbox" id="option-c">
<label for="option-c">Option C</label>
<br/>
</div>
You can add a change event listener to all of those checkboxes (except for the automatic select all checkbox).
So in this demo I used a disciminant being the class auto that only the "select all" checkbox has.
Then I select all elements being input but not having the class auto.
And for each of those I add an event listener for the change event that will uncheck the "select all" checkbox if any of those was unchecked and that will check the "select all" checkbox if otherwise all of them are checked.
let checkboxes = document.querySelectorAll("input[type='checkbox']");
let cbActual = document.querySelectorAll('input[type=checkbox]:not([class=auto])');
cbActual.forEach(
cb => {
cb.addEventListener('change', (event)=>{
if(!event.target.checked)
document.getElementById('check-all')
.checked = false;
else{
if( [...cbActual].every(cb => cb.checked === true) )
document.getElementById('check-all')
.checked = true;
}
});
}
);
function checkAll(myCheckBox) {
if (myCheckBox.checked == true) {
checkboxes.forEach(function(checkbox) {
checkbox.checked = true;
});
} else {
checkboxes.forEach(function(checkbox) {
checkbox.checked = false;
});
}
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
min-height: 100vh;
display: grid;
place-content: center;
}
input[type="checkbox"] {
margin-bottom: 10px;
cursor: pointer;
}
input[type="checkbox"]:not(:first-child) {
margin-left: 20px;
}
<div class="container">
<input type="checkbox" id="check-all" onchange="checkAll(this)" class="auto">
<label for="check-all">Select All</label>
<br/>
<input type="checkbox" id="option-a">
<label for="option-a">Option A</label>
<br/>
<input type="checkbox" id="option-b">
<label for="option-b">Option B</label>
<br/>
<input type="checkbox" id="option-c">
<label for="option-c">Option C</label>
<br/>
</div>
When checkall is clicked either all or none are selected. When one of the options are checked/unchecked the status of checkall is decided based on the filter function.
I changed the markup of the form a bit. You can "group" check boxes on their name. And try avoiding IDs in a form -- in general it is better to use the name attribute.
document.addEventListener('DOMContentLoaded', e => {
document.forms.form01.addEventListener('change', result_change);
});
function result_change(e) {
let form = e.target.form;
/* e.target.form.option could either be a NodeList or just one Element.
A iterable is needed. */
let options = (form.option.length) ? form.option : [form.option];
switch (e.target.name) {
case 'checkall':
let checked = e.target.checked;
[...options].forEach(option => option.checked = checked);
break;
case 'option':
let allchecked = ([...options].filter(option => !option.checked).length == 0) ? ? true;
form.checkall.checked = allchecked ? true : false;
break;
}
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
min-height: 100vh;
display: grid;
place-content: center;
}
input[type="checkbox"] {
margin-bottom: 10px;
cursor: pointer;
}
input[type="checkbox"]:not(:first-child) {
margin-left: 20px;
}
<form name="form01">
<input type="checkbox" name="checkall">
<label for="check-all">Select All</label>
<br/>
<input type="checkbox" name="option" value="a">
<label for="option-a">Option A</label>
<br/>
<input type="checkbox" name="option" value="b">
<label for="option-b">Option B</label>
<br/>
<input type="checkbox" name="option" value="c">
<label for="option-c">Option C</label>
<br/>
</form>
Prefer to use event propagation to handle the change events of all checkboxes in one listener.
To make use of event propagation, you have to be able to distinguish them from the "Select all" checkbox. To distinuish them, you can:
Use a class (on either the "Select all" or all other checkboxes).
Group the checkboxes (except the "Select all" checkbox) in an element.
Check if the changing checkbox is the first (i.e. the "Select all") checkbox.
...
I chose to use a grouping element so that the "Select all" checkbox is not included:
const cbAll = document.getElementById("cb-all");
const cbGroup = document.getElementById("cb-group");
// NodeList has .forEach() but not .every(). Transform to an array, which has both.
const checkboxes = Array.from(cbGroup.querySelectorAll("input[type=checkbox]"));
cbAll.addEventListener("change", () => {
// If cbAll.checked changes, cbAll.checked should override all other checkboxes' checked.
checkboxes.forEach(cb => cb.checked = cbAll.checked);
});
// This listener will be called if *any* checkbox (in cbGroup) changes.
// Update cbAll.checked to true if all checkboxes are checked; otherwise false.
cbGroup.addEventListener("change", () => {
const areAllChecked = checkboxes.every(cb => cb.checked);
cbAll.checked = areAllChecked;
});
label {display: block}
#cb-group {margin-inline-start: 1.2rem}
<label for="cb-all"><input id="cb-all" type="checkbox"> Select all</label>
<div id="cb-group">
<label for="cb-1"><input id="cb-1" type="checkbox"> First option</label>
<label for="cb-2"><input id="cb-2" type="checkbox"> Second option</label>
<label for="cb-3"><input id="cb-3" type="checkbox"> Third option</label>
</div>
Alternatively you can add listeners to all checkboxes individually.
Checkboxes can also be in a "third" state: Indeterminate. Note: This is not a true state, as checkboxes can only be either checked or unchecked. An indeterminate checkbox hides its checkedness under the pretence of being indeterminate.
This is most commonly used for checkboxes like this "Select all" checkbox; where a checkbox describes the state of a group of checkboxes.
The above example can be modified to make use of it:
const cbAll = document.getElementById("cb-all");
const cbGroup = document.getElementById("cb-group");
const checkboxes = Array.from(cbGroup.querySelectorAll("input[type=checkbox]"));
cbAll.addEventListener("change", () => {
checkboxes.forEach(cb => cb.checked = cbAll.checked);
});
cbGroup.addEventListener("change", () => {
const amountChecked = checkboxes.reduce((amount, cb) => {
// Number(bool) returns 1 if bool === true; otherwise 0.
return amount + Number(cb.checked);
}, 0);
const areAllChecked = amountChecked === checkboxes.length;
const areSomeChecked = amountChecked > 0;
cbAll.checked = areAllChecked;
cbAll.indeterminate = areSomeChecked && !areAllChecked;
});
label {display: block}
#cb-group {margin-inline-start: 1.2rem}
<label for="cb-all"><input id="cb-all" type="checkbox"> Select all</label>
<div id="cb-group">
<label for="cb-1"><input id="cb-1" type="checkbox"> First option</label>
<label for="cb-2"><input id="cb-2" type="checkbox"> Second option</label>
<label for="cb-3"><input id="cb-3" type="checkbox"> Third option</label>
</div>

How do I dynamically get the value of an element from an array of elements?

I have a form with 3 checkboxes. I'm trying to the value of whichever checkbox is clicked on. I'm able to get the value of a hardcoded checkbox index (checkbox[0] for example), but I can't get the value of checkbox[i] with vanilla JS.
document.addEventListener("DOMContentLoaded", function() {
var checkboxes = document.getElementsByClassName('checkbox');
var listType = document.getElementById('ListType');
for (var i = 0; i < checkboxes.length; i++) {
checkboxes[i].addEventListener('click', function() {
var inputByIndex = checkboxes[0].value; //I can get the value of the first element, but I can't get the value of whichever checkbox is checked. checkbox[i] doesn't work.
listType.classList.add(inputByIndex);
var spanType = document.getElementById("type");
spanType.innerText = inputByIndex;
});
}
});
input {
margin: 20px;
}
#ListType.basiclist {
color: red;
}
#ListType.accordionlist {
color: blue;
}
#ListType.internalonly {
color: pink;
}
<form id="ListTypes">
<label for "basicList"><input type="checkbox" id="basicList" class="checkbox" name="basicList" value="basiclist"/>Basic List</label>
<label for "accordionList"><input type="checkbox" id="accordionList" class="checkbox" name="accordionList" value="accordionlist"/>Accordion List</label>
<label for "internalOnly"><input type="checkbox" id="internalOnly" class="checkbox" name="internalOnly" value="internalonly" />Internal Use Only</label>
</form>
<div id="ListType">
List Type: <span id="type"></span>
</div>
Fiddle
You can use event.currentTarget to access the element on which event has occurred.
The currentTarget read-only property of the Event interface identifies the current target for the event, as the event traverses the DOM.
document.addEventListener("DOMContentLoaded", function() {
var checkboxes = document.getElementsByClassName('checkbox');
var listType = document.getElementById('ListType');
for (var i = 0; i < checkboxes.length; i++) {
checkboxes[i].addEventListener('click', function(event) {
var inputByIndex = event.currentTarget.value;
listType.classList.add(inputByIndex);
var spanType = document.getElementById("type");
spanType.innerText = inputByIndex;
});
}
});
input {
margin: 20px;
}
#ListType.basiclist {
color: red;
}
#ListType.accordionlist {
color: blue;
}
#ListType.internalonly {
color: pink;
}
<form id="ListTypes">
<label for "basicList"><input type="checkbox" id="basicList" class="checkbox" name="basicList" value="basiclist"/>Basic List</label>
<label for "accordionList"><input type="checkbox" id="accordionList" class="checkbox" name="accordionList" value="accordionlist"/>Accordion List</label>
<label for "internalOnly"><input type="checkbox" id="internalOnly" class="checkbox" name="internalOnly" value="internalonly" />Internal Use Only</label>
</form>
<div id="ListType">
List Type: <span id="type"></span>
</div>
In the for loop, use let instead of var to make it work:
document.addEventListener("DOMContentLoaded", function() {
var checkboxes = document.getElementsByClassName('checkbox');
var listType = document.getElementById('ListType');
for (let i = 0; i < checkboxes.length; i++) {
checkboxes[i].addEventListener('click', function() {
var inputByIndex = checkboxes[i].value; //I can get the value of the first element, but I can't get the value of whichever checkbox is checked. checkbox[i] doesn't work.
listType.classList.add(inputByIndex);
var spanType = document.getElementById("type");
spanType.innerText = inputByIndex;
});
}
});
input {
margin: 20px;
}
#ListType.basiclist {
color: red;
}
#ListType.accordionlist {
color: blue;
}
#ListType.internalonly {
color: pink;
}
<form id="ListTypes">
<label for "basicList"><input type="checkbox" id="basicList" class="checkbox" name="basicList" value="basiclist"/>Basic List</label>
<label for "accordionList"><input type="checkbox" id="accordionList" class="checkbox" name="accordionList" value="accordionlist"/>Accordion List</label>
<label for "internalOnly"><input type="checkbox" id="internalOnly" class="checkbox" name="internalOnly" value="internalonly" />Internal Use Only</label>
</form>
<div id="ListType">
List Type: <span id="type"></span>
</div>
the checkboxes list doesn't exist within the closure of the onclick funcion. Instead use this.value.
JS fiddle
Delegate
You need to think of the CSS for more than one listType color or use a set of radio buttons
document.addEventListener("DOMContentLoaded", function() {
document.getElementById('ListTypes').addEventListener("click", function(e) {
const tgt = e.target;
if (tgt.type && tgt.type === 'checkbox') {
const values = [...tgt.form.querySelectorAll("[type=checkbox]:checked")].map(chk => chk.value);
document.getElementById("type").textContent = values.join(", ")
document.getElementById("ListType").classList.add(...values);
}
});
});
input {
margin: 20px;
}
#ListType.basiclist {
color: red;
}
#ListType.accordionlist {
color: blue;
}
#ListType.internalonly {
color: pink;
}
<form id="ListTypes">
<label for "basicList"><input type="checkbox" id="basicList" class="checkbox" name="basicList" value="basiclist"/>Basic List</label>
<label for "accordionList"><input type="checkbox" id="accordionList" class="checkbox" name="accordionList" value="accordionlist"/>Accordion List</label>
<label for "internalOnly"><input type="checkbox" id="internalOnly" class="checkbox" name="internalOnly" value="internalonly" />Internal Use Only</label>
</form>
<div id="ListType">
List Type: <span id="type"></span>
</div>
You just need to select them all using the method you would like (I used querySelectorAll & ) and do an iteration over them (I used forEach()).
This is the most simple function you can ever find.
const checkboxes = document.querySelectorAll('input[type="checkbox"]');
checkboxes.forEach(singleCheckbox => {
singleCheckbox.addEventListener('click', () => alert(singleCheckbox.id))
});
<label for="first">First<input type="checkbox" id="first"/></label>
<label for="second">Second<input type="checkbox" id="second"/></label>
<label for="third">Third<input type="checkbox" id="third"/></label>
Just to make clear what was actually the problem with your code...
At the time you click handler will be fired the for loop will end its work and thus, the value of i will become exactly checkboxes.length, and of course, there is no checkbox with such an index, because the last of them has index (checkboxes.length - 1). So the reason is that the code inside of the handler is executed after for loop ends its work.
The solutions were already provided by other users.

How to get counter when inputs, select etc. change in form?

var inpts = $('.map-form .val-input');
var radio = $('.map-form .radio-input');
var counter = $('.filtr-map-count');
$('.detect-change').change(function() {
countInputs();
});
function countInputs() {
var click = 0;
$(inpts).each(function(){
if($(this).val() != ""){
click++;
}
counter.text(click);
});
$(radio).each(function() {
if($(this).val() != ""){
click++;
}
counter.text(click);
});
};
$(window).on('load', function() {
countInputs();
});
.filtr-map {
background-color: red;
width: 100px;
height: 40px;
color: #fff;
z-index: 99;
font-weight: bolder;
cursor: pointer;
display: flex;
justify-content: center;
align-items: center;
margin-top: 50px;
}
.filtr-map-count {
font-size: 10px;
position: relative;
top: -5px;
left: 5px;
background-color: #000;
border-radius: 50%;
width: 20px;
height: 20px;
display: flex;
align-items: center;
justify-content: center;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form class='map-form'>
<div>
<h2>Search</h2>
<fieldset>
<label>Price</label>
<span>min</span>
<input type="text" class='val-input detect-change ' value="" />
<span>max</span>
<input type="text" class='val-input detect-change ' value="" />
</fieldset>
<fieldset>
<label>Category</label>
<div class="styled_select">
<select class='val-input detect-change '>
<option value="">Default</option>
<option value="1">Option 1</option>
<option value="2">Option 2</option>
</select>
</div>
</fieldset>
<fieldset>
<div class="styled_radio"><input class='radio-input detect-change' checked="checked" type="radio" id="Radio1" name="Radio" /><label
class="input" for="Radio1"><span class="circle"><span></span></span><span>Test One Test</span></label></div>
<div class="styled_radio"><input class='detect-change' type="radio" id="Radio2" name="Radio" /><label class="input"
for="Radio2"><span class="circle"><span></span></span><span>Test test</span></label></div>
</fieldset>
<input type="submit" value='Send'>
</div>
</form>
<div class="filtr-map">
Filter<span class='filtr-map-count'>0</span>
</div>
Hey, How to get counter when inputs, select etc. change in form? How to make a counter. If input/select/radio change in fieldset counter should increase, if back to default value decrease. The counter number should also works after page reload. I added a js code with im working on but something goes wrong.
---UPDATE---
I added working jquery code for this example, maybe will be helpful for someone else. Also I added classes that help with select the changed elements.
Ok so this becomes a little more complicated if you're considering all input types.
I have written the code below as a starting point. Yes, it does do what you need it to. BUT it hasn't been fully tested and it can be improved.
See a working example here: https://jsfiddle.net/hber3q0z/
The jQuery that's doing the heavy lifting...
var $form = $('.map-form');
var $counter = $('.filtr-map-count');
var changed = {};
// Listen for an `update` event on counter element
$counter.on('update', function() {
// Update the text value
$(this).text(function() {
var count = 0;
// Loop through the `changed` object and count if value has changed
$.each(changed, function(key, hasChanged) {
if (hasChanged) {
count++;
}
});
// Return count
return count;
});
});
// Find all form inputs
$form.find(':input').each(function(key) {
var $this = $(this);
// Get the input name, else create a temporary name
var name = $this.attr('name') || new Date().getTime().toString() + key;
// Store the original value
var original = $this.val();
// If the input is a checkbox
if ($this.is(':checkbox')) {
// Create a function to get checkbox group values
var checkboxValue = function() {
var values = [];
// Find all `checked` inputs with the same type and name
$form.find('[type="' + $this.attr('type') + '"][name="' + $this.attr('name') + '"]:checked').each(function() {
// Push values to array
values.push($(this).val());
});
// Join them for easier comparisom
return values.join(',');
};
// Store original group value
original = checkboxValue();
// Listen to checkbox events
$this.on('change keyup keydown mouseup', function() {
// Perform value changed check
changed[name] = checkboxValue() !== original;
// Tell the counter element to update contents
$counter.trigger('update');
});
}
// If the input is a radio
else if ($this.is(':radio')) {
// Create a function to get radio group value
var radioValue = function() {
// Find the first `checked` input with the same type and name
return $form.find('[type="' + $this.attr('type') + '"][name="' + $this.attr('name') + '"]:checked').val();
};
// Store original group value
original = radioValue();
// Listen to radio input events
$this.on('change keyup keydown mouseup', function() {
// Perform value changed check
changed[name] = radioValue() !== original;
// Tell the counter element to update contents
$counter.trigger('update');
});
}
// Catch-all other input types
else {
// Listen to input events
$this.on('change keyup keydown cut paste', function() {
// Perform value changed check
changed[name] = $this.val() !== original;
// Tell the counter element to update contents
$counter.trigger('update');
});
}
});
The code is checking all inputs in the form for an actual changed value, not just a change event. I have also included support for checkbox and radio groups.

I want to check if the checkbox is checked, but everytime i try it always goes with the else option for everything

Im trying to make a bookshop website where the customer checks the books and writes the number of copies. But the code cannot tell if the checkbox is checked and goes with the "else" option always. What needs to change?
checkb1-5 are the checkboxes element
numbcop1-5 is the number of copies entered by the user
function Checker() {
var checkb1 = document.getElementById("adult");
if (checkb1.checked){
var numbcop1 = document.getElementById(numb1);
} else{
var numbcop1 = 0;
}
var checkb2 = document.getElementById("ado");
if (checkb2.checked){
var numbcop2 = document.getElementById(numb2);
} else{
var numbcop2 = 0;
}
var checkb3 = document.getElementById("child");
if (checkb3.checked){
var numbcop3 = document.getElementById(numb3);
} else {
var numbcop3 = 0;
}
var checkb4 = document.getElementById("school");
if (checkb4.checked){
var numbcop4 = document.getElementById(numb4);
} else {
var numbcop4 = 0;
}
var checkb5 = document.getElementById("transl");
if (checkb5.checked){
var numbcop5 = document.getElementById(numb5);
} else{
var numbcop5 = 0;
}
}
Looks like there are a few things to fix before to make your function works:
When you are doing var numbcop1 = document.getElementById(numb1); you need to make sure the parameter you are adding to getElementById is correct. E.g document.getElementById('numb1') or make sure that numb1 contains an string indicating the id for the function to look at e.g var numb1 = 'adult_amount'; and then use that variable as your code does document.getElementById(numb1)
Once you get the element that is expected to have the value, if it is an input you can do var numbcop1 = document.getElementById('numb1').value; to get the number typed by the user.
Let's refactor the Adult field to have a clear example on how it works:
<input type="checkbox" data-copies="adult_copies" id="adult">
<label>adult</label>
<input type="number" id="adult_copies">
And add this to your JS and check how the values comes using a single function that can be reused for the other books:
function getChecked(event) {
let numbcop;
let copies_id = event.target.getAttribute('data-copies');
if (event.target.checked){
numbcop = document.getElementById(copies_id).value;
} else{
numbcop = 0;
}
console.log(numbcop);
}
let adult = document.getElementById("adult");
adult.addEventListener('click', getChecked);
LMK if this works for your implementation.
actually it is going with the if option not else but it is returning zero.
You must point to the value of the numb1 not just the element.
for example:
var numbcop1 = document.getElementById(numb1).value;
at least this must be coded like this (?):
var
t_elem = ['adult', 'ado', 'child','school', 'transl'],
numbcop1 = 0,
numbcop2 = 0,
numbcop3 = 0,
numbcop4 = 0,
numbcop5 = 0
;
function Checker() {
t_elem.forEach((elm,idx)=>{
window['numbcop'+(idx+1)] = (document.getElementById(elm).checked) ? document.getElementById('numb'+(idx+1)).value : 0;
})
}
Get_Books.onclick = function() {
Checker();
console.log(numbcop1, numbcop2, numbcop3, numbcop4, numbcop5);
}
label { float:left; clear: both; display:block; width:80px; margin:10px 5px; text-align: right }
input, button { float:left; display:block; margin:10px 5px }
button { clear: both }
<label for="adult">adult: </label>
<input id="adult" type="checkbox" />
<input id="numb1" type="number" value="1" />
<label for="ado">ado: </label>
<input id="ado" type="checkbox" />
<input id="numb2" type="number" value="2" />
<label for="adult">child: </label>
<input id="child" type="checkbox" />
<input id="numb3" type="number" value="3" />
<label for="school">school: </label>
<input id="school" type="checkbox" />
<input id="numb4" type="number" value="4" />
<label for="transl">transl: </label>
<input id="transl" type="checkbox" />
<input id="numb5" type="number" value="5" />
<button id="Get_Books">Books</button>

Input validation number with display another block

I've got the input field, need to check the number only, if value of input is number - another div .hidden should display: block; Also I've got multiple eventlistener on four block- onclick this .hidden block is visible, if it possible combine this event with the form input event.
;
(function() {
var amount_list = document.querySelectorAll('.form-row .donate');
var amount_array = [].slice.call(document.querySelectorAll(".form-row .donate"));
var donerForm = document.getElementById('hidden');
var inputDonateField = document.getElementById('donate-price').value;
var inputNumber = /^[0-9]+$/;
var onClickFormVisible = function() {
donerForm.style.display = "block";
};
var amoutn_array = amount_array.map(function(e) {
return e.addEventListener('click', onClickFormVisible);
});
// var onclickInputNumberDonate = function() {
// // If x is Not a Number or
// if (isNaN(inputDonateField) && inputDonateField.length > 0) {
// console.log(inputDonateField);
// return onClickFormVisible();
//
// } else {
// return false;
// }
// };
function validateForm() {
if (inputDonateField === null || inputDonateField === "") {
alert("Name must be filled out");
return false;
}
}
})();
#hidden {
display: none;
}
<div class="form-row">
<label>Label</label>
<div class="donate">50kr</div>
<div class="donate">100kr</div>
<div class="donate">200kr</div>
<div class="donate">500kr</div>
</div>
<div class="form-row">
<div class="form-col doner-price">
<label for="donate-price">
only number
<input type="text" id="donate-price" name="name" value="">
</label>
</div>
</div>
<div id="hidden">TExt here</div>
Most browsers support type="number", can also have specified ranges with the min and max attributes, and can use the step attribute to accept only certain numbers (for example whole numbers).
<input type="number" min="0" max="50" step="1" />
On submit of the form, you'll still want to verify of course.
IsNan() is useful for filtering out some inputs. Comparing against a regex like new RegExp('^[0-9]+$'); is a safe bet.
As for:
if it possible combine this event with the form input event.
I don't quite know what you're asking.
If you are asking how to validate on both onclick and onsubmit events, just create a function for the validation, like validateInput() and call it for onclick and onsubmit.
element.onclick = function() {
if (isValidInput(inputValue)) {
// More code here
}
}
form.onsubmit = function() {
if (isValidInput(inputValue)) {
// More code here
}
}
function isValidInput(inputValue) {
// Check that input is valid
// Return true / false
}
It's working for me now with keyup input event.
(function() {
var amount_list = document.querySelectorAll('.form-row .donate'); //node-list
var amount_array = [].slice.call(document.querySelectorAll(".form-row .donate")); //node-list to array
var donerForm = document.getElementById('hidden');
var inputDonateField = document.getElementById('donate-price');
var inputNumber = /^[0-9]+$/;
var onClickFormVisible = function() {
donerForm.style.display = "block";
};
var onInputTypeNumber = function() {
if (inputNumber.test(inputDonateField.value)) {
donerForm.style.display = "block";
} else {
return false;
}
};
//onclick event for each amount images
var amoutn_array = amount_array.map(function(e) {
return e.addEventListener('click', onClickFormVisible);
});
//input event only if value === number
inputDonateField.addEventListener("keyup", onInputTypeNumber);
})();
.form-row{display:flex; margin:2rem;}
.donate{
background: #007DBD;
width: 75px;
height:50px;
padding: 1rem;
border: 1px solid black;
}
#hidden{
display:none;
width: 100px;
height:150px;
background: gray;
color: black;
text-align:center;
padding: 2rem;
}
<div class="form-row">
<label>Label</label>
<div class="donate">50kr</div>
<div class="donate">100kr</div>
<div class="donate">200kr</div>
<div class="donate">500kr</div>
</div>
<div class="form-row">
<div class="form-col doner-price">
<label for="donate-price">
only number
<input type="text" id="donate-price" name="name" value="">
</label>
</div>
</div>
<div id="hidden">Only if Input value === to number.You are see this block;</div>

Categories

Resources