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

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.

Related

How to get score from correct answer through form input

I'm creating a quiz that contains 10 questions: 5 multiple choice through radio input and 5 written answers through text input. See code for both inputs below. But I would also like to add a score system to these questions. I found a nice script here on stack overflow that can keep the score while user enters form input. I will add it below.
The script I use to check answers from radio input:
$(document).ready(function(){
$('input[name=radio1]').change(function(){
$('.alert').remove();
if($('input[name=radio1]:checked').val() === "1") {
$(this).parent().append('<span class="correct">✓ Correct!</span>');
} else {
$(this).parent().append('<span class="incorrect">✗ Correct answer = B</span>');
}
});
});
The correct anser given is based on value="1". The other answers have value="0".
The script I use to check answers from text input:
$('submit').on('click', function() {
markAnswers(1)
});
var answers = {
q1: ["Auto's"]
};
function markAnswers(id) {
$(`#q${id}`).each(function () {
let userAnswer = this.value.replace(/[^\w\'\,\-\?\!\"\:\—\;]/g,'');
if ($.inArray(userAnswer, answers[this.id]) === -1) {
$(this).parent().append(`<br><span class='incorrect'>✗ Correct answer = ${answers[this.id]}</span>`);
} else {
$(this).parent().append("<br><span class='correct'>✓ Correct!</span>");
}
});
}
The correct value from text input is determined by this script above.
Now, the script I found that keeps the score, collects score through data-score=. But I was thinking to just use value instead. See original script below:
$('.track').change(function(e) {
update_progress();
});
// supports any number of inputs and calculates done as %
function update_progress() {
var score = 0
$('input.track').each(function(){
var _score = $(this).data("score")
if ($(this).val().length > 0) {
score += _score
}
})
$('#score').text(score)
var count = $('.track').length;
var length = $('.track').filter(function() {
return this.value;
}).length;
var done = Math.floor(length * (100 / count));
$('.perc').text(done);
$('.meter').width(done + "%");
}
The script can be found here: https://stackoverflow.com/a/58297288/4546157
It is really nice. It keeps the score but it also shows you if you have completed the form or not.
I would like each correct answer to have a value of 1 so at the end of the quiz the user can have a maximum score of 10/10. But, a big but, I don't know how to implement it. Hoping to see suggestions or solutions from you guys. Thank you!
You would do it something like this. Though it's bad practice to use globally available variables, but for the sake of simplicity i put them there. Better to wrap everything in a div and store score/progress as data attributes.
Pen: https://codepen.io/lenadax/pen/QWQqMxP?editors=1111
// global vars, put them somewhere else
var progress = 0;
var score = 0;
$('form.question').each(function(i, el) {
// I'm lazy so form id is the same as input name for each question
let inputs = $(`input[name=${$(this).attr('id')}]`);
inputs.on('change', function() {
// increase progress by 1 if button has been selected.
progress++;
if ($(this).val() === "1") {
// increase score if correct choice selected
score++;
$('<span class="result correct">').text('✓ Correct!').appendTo(el);
} else {
$('<span class="result incorrect">').text('X Incorrect!').appendTo(el);
}
// get number of questions
let question_count = $('form.question').length;
// disable after choosing for less hassle
inputs.prop('disabled', true);
// calculate the progress in percent
let progress_num = progress / question_count * 100;
$('.perc').text(progress_num);
$('#score').text(`${score} / ${question_count}`);
});
})
input {
display: inline-block;
}
label {
display: inline-block;
}
button {
display: block;
}
form {
width: 200px;
border: 1px solid gray;
margin: 10px;
padding:10px 5px;
}
.result {
display: block;
}
.result.incorrect {
color: red;
}
.result.correct {
color: green;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<html>
<body>
<form class="question" id="question1">
<span>Question 1</span>
</p>
<input name="question1" id="answer1" type="radio" value="0"/>
<label for="answer1">Wrong answer</label>
</p>
<input name="question1" id="answer2" type="radio" value="1"/>
<label for="answer2">Right answer</label>
</form>
<form class="question" id="question2">
<span>Question 2</span>
</p>
<input name="question2" id="answer1" type="radio" value="0"/>
<label for="answer1">Wrong answer</label>
</p>
<input name="question2" id="answer2" type="radio" value="0"/>
<label for="answer2">Wrong answer</label>
</p>
<input name="question2" id="answer3" type="radio" value="1"/>
<label for="answer3">Right answer</label>
</form>
<h5>Done <span class='perc'>0</span>%</h5>
<h5>Score <span id="score">0</span></h5>
</body>
</html>

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.

JavaScript refactoring not working as expected

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>

Javascript & HTML unit converter - how to use one input field as constant

I am trying to convert a Python script into an HTML/Javascript web based converter. The script is very simple and I followed the steps at https://www.w3schools.com/howto/howto_js_length_converter.asp, which work great, if all fields are dynamic. In my case, I need one variable to not change. On an example: user provides the "AssayWeight" value and one of the following: PPM or Grav. After that, scripts calculates the other value from PPM/Grav that the user didn't provide. Here's the code I have so far:
<script>
function ppmtoGravConverter(source,valNum) {
valNum = parseFloat(valNum);
var inputPPMtoGrav = document.getElementById("inputPPMtoGrav");
var inputAssayWeight = document.getElementById("inputAssayWeight");
var inputGravtoPPM = document.getElementById("inputGravtoPPM");
if (source=="inputPPMtoGrav") {
inputGravtoPPM.value=(valNum*inputAssayWeight/1000).toFixed(4);
}
if (source=="inputGravtoPPM") {
inputPPMtoGrav.value=(valNum*1000/inputAssayWeight).toFixed(4);
}
}
</script>
and html from w3schools:
<label>Assay Weight</label>
<input id="inputAssayWeight" type="number" placeholder="Assay Weight" oninput="ppmtoGravConverter(this.id,this.value)" onchange="ppmtoGravConverter(this.id,this.value)">
<br><br>
<label>PPM</label>
<input id="inputPPMtoGrav" type="number" placeholder="PPM" oninput="ppmtoGravConverter(this.id,this.value)" onchange="ppmtoGravConverter(this.id,this.value)">
<label>Grav (mg)</label>
<input id="inputGravtoPPM" type="number" placeholder="Grav (mg)" oninput="ppmtoGravConverter(this.id,this.value)" onchange="ppmtoGravConverter(this.id,this.value)">
Please let me know what am I missing. This is my 2nd day looking at Javascript. Thanks!
The issue is that in your formula, you are using inputAssayWeight instead of actually taking its value and using it. Replace those two if conditions with
if (source=="inputPPMtoGrav") {
inputGravtoPPM.value=(valNum*parseFloat(inputAssayWeight.value)/1000).toFixed(4);
}
if (source=="inputGravtoPPM") {
inputPPMtoGrav.value=(valNum*1000/parseFloat(inputAssayWeight.value)).toFixed(4);
}
That should fix your issue.
Wrap everything in a <form> tag and give it an #id.
<form id='main'><!-- EVERYTHING --></form>
Bind "input" event to the <form> and call an event handler (i.e. a function to handle a triggered event). Refer to: JavaScript Event Handling
document.forms.main.oninput = inputHandler;
Define function inputHandler() -- remember to pass the Event Object
function inputHandler(event) {...
Define all variables -- refer to: Obtaining References to Forms and Form Elements in JavaScript
// Collect all form controls into a NodeList
const field = this.elements;
// Find the element user interacted with
const input = event.target;
// Reference any form control by #id or [name] attribute by prefixing it with `field`
const aW = field.assayWeight;
// Assign a variable to form control values and convert them into a real Number
let AWT = parseFloat(aW.value);
Delegate "input" event by using if/else flow control statements. By explicitly allowing specific elements to react to an event and implicitly preventing other elements by simple omission is an important part of a programming paradigm called Event Delegation.
if (input.matches('#assayWeight')) {...
The HTML/CSS layout and styling features a toggling system in which it allows the user to enter "assay weight" and either "PPM" or "Grav". Hover over the titles and then click one and then the other to see the toggling. Refer to: Exposing Form Fields Via Checked Radio Buttons
[name=conv],
.mask {
display: none
}
[name=conv]:checked + fieldset .mask {
display: inline-block;
}
Demo
document.forms.convPpmG.oninput = convert;
function convert(event) {
const field = this.elements;
const input = event.target;
const awt = field.aWt;
const ppm = field.pPM;
const grv = field.grv;
const gtp = field.gToP;
const ptg = field.pToG;
let AWT = parseFloat(awt.value);
let PPMin = parseFloat(ppm.value);
let GRVin = parseFloat(grv.value);
if (input.matches('#aWt')) {
// log(AWT, "Assay Weight");
}
if (input.matches('#pPM')) {
// log(PPMin, "PPM Input");
let GRVout = PPMin * AWT / 1000;
// log(GRVout, "Grav Output");
ptg.value = GRVout.toFixed(4);
}
if (input.matches('#grv')) {
// log(GRVin, "Grav Input");
let PPMout = GRVin * 1000 / AWT;
// log(PPMout, "PPM Output");
gtp.value = PPMout.toFixed(4);
}
}
// A utility logger - not required
const log = (data, key = 'Field') => console.log(JSON.stringify(key + ': ' + data));
root,
body {
font: 400 3vw/1.5 Consolas, monospace;
}
fieldset fieldset {
min-height: 20vh;
}
input,
output {
width: 10ch;
margin-right: 5px;
margin-bottom: 8px;
font: inherit;
text-align: right;
}
#aWt {
display: inline-block;
}
[type=reset] {
text-align: center;
}
.switch {
padding: 3px 5px;
}
[type=reset]:hover,
.switch:hover {
color: tomato;
background: rgba(56, 87, 199, 0.4);
cursor: pointer;
}
[name=conv],
.mask {
display: none
}
[name=conv]:checked+fieldset .mask {
display: inline-block;
}
<form id='convPpmG'>
<fieldset>
<legend>PPM / Grav Convertor</legend>
<label>Assay Weight</label>
<input id="aWt" type="number" min='0' value="0">
<input type='reset'>
<br>
<input id='ppmToGrav' name='conv' type='radio'>
<fieldset>
<legend>
<label for='ppmToGrav' class='switch'>PPM to Grav</label>
</legend>
<label class='mask'>
PPM: <input id="pPM" type="number" min='0' value="0">
to Grav: <output id='pToG'>0</output> mg
</label>
</fieldset>
<hr>
<input id='gravToPPM' name='conv' type='radio'>
<fieldset>
<legend>
<label for='gravToPPM' class='switch'>Grav to PPM</label>
</legend>
<label class='mask'>
Grav: <input id="grv" type="number" min='0' value="0">
mg to PPM: <output id='gToP'>0</output>
</label>
</fieldset>
</fieldset>
</form>

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