How to dynamically keep track of user inputs in JavaScript? - javascript

Does anyone have any idea to dynamically keep track of user inputs in a form? I learned how to disable a button and if users want to enable it, they would just have to fill in the input fields. While this works, if a user decides to backspace and go back to a clear field, the button is still enabled. I wanted to get some insight or ideas to keep track of user inputs dynamically.
I'm a bit new to JS so I just wanted some ideas. Is it possible to use for loops/forEach methods to iterate through the input fields? Or what approach do you recommend on taking?
HTML:
<form class="container">
<input type="text" class="input" />
<input type="email" class="input" id="input" />
<button type="submit" id="submitButton" href="index.html" disabled>
Submit
</button>
</form>
JavaScript:
document.getElementById("input").addEventListener("keyup", function() {
var inputs = document.querySelectorAll("input");
if (inputs != "") {
document.getElementById("submitButton").removeAttribute("disabled");
} else if ((inputs = "")) {
document.getElementById("submitButton").setAttribute("disabled", null);
}
});

Here is the solution of your problem.
document.addEventListener("keyup", function() {
var inputs = document.querySelectorAll("input");
var emptyFillExists = false;
for (let index = 0; index < inputs.length; index++) {
if (inputs[index].value.length === 0) {
emptyFillExists = true;
break;
}
}
if (!emptyFillExists) {
document.getElementById("submitButton").removeAttribute("disabled");
} else {
document.getElementById("submitButton").setAttribute("disabled", null);
}
});
<form class="container">
<input type="text" class="input" />
<input type="email" class="input" />
<button type="submit" id="submitButton" href="index.html" disabled>
Submit
</button>
</form>

There are a few things wrong with your codes:
You assume inputs as strings. It isn't. It's an array.
You track keyup event for only 1 input. You should track keyup event for all inputs instead.
Here's what I'd suggest you do:
Add event listener keyup for the form.
Interate through each input and check.
function areInputsValid() {
// Iterate through every input and check its value
var inputs = document.querySelectorAll('input');
for (var i = 0; i < inputs.length; i++)
if (inputs[i].value == '')
return false;
return true;
}
// Get the form element
var form = document.getElementsByTagName('form')[0];
// Add event listener
form.addEventListener('keyup', function() {
// Are the inputs valid?
if (areInputsValid())
document.getElementById("submitButton").removeAttribute("disabled");
else
document.getElementById("submitButton").setAttribute("disabled", null);
})
EDIT: as charlietfl pointed out, there are bugs in my previous answer.

Related

Listen for blank inputs and add a "disabled" attribute to a button until an input is noticed

I have a user input field that, if blank, I would like the submit button to be disabled until a key press in the input box is noticed. But, if they blank out the input box, then the button is disabled again.
So, I'd like to add the "disabled" attribute to this input button:
<input type="submit" id="mapOneSubmit" value="Submit" [add attribute "disabled" here]>
The input is from this HTML here:
<input type="text" id="mapOneUserInput" onkeypress="return isNumberKey(event)" oninput="validate(this)">
Note: I have onkeypress and oninput validation to prevent non-number inputs and allow only 2 decimal places.
I assume my JS would look like this to add the disabled attribute:
document.getElementById("mapOneSubmit").setAttribute("disabled");
My problem is, I can't find what event listener listens for "blank" inputs? Can you help me with that?
Thanks kindly!
Check this one as well.
function checkvalid(el)
{
//e.g i am preventing user here to input only upto 5 characters
//you can put your own validation logic here
if(el.value.length===0 || el.value.length>5)
document.getElementById("mapOneSubmit").setAttribute("disabled","disabled");
else
document.getElementById("mapOneSubmit").removeAttribute('disabled');
}
<input type='text' id ='inp' onkeyup='checkvalid(this)'>
<button id='mapOneSubmit' disabled>
Submit
</button>
Yet using the input event:
<input type="text" id="mapOneUserInput" onkeypress="return isNumberKey(event)" oninput="validate(this);updateSubmit(this.value)">
Then in js
function updateSubmit(val) {
if (val.trim() == '') {
document.getElementById('mapOneSubmit').disabled = true;
}
else {
document.getElementById('mapOneSubmit').disabled = false;
}
}
You can find the below code to find the blank inputs
function isNumberKey(event) {
console.log(event.which)
}
var value;
function validate(target) {
console.log(target);
}
<form>
<input type="text" id="mapOneUserInput" onkeypress="return isNumberKey(event)" oninput="validate(this)">
<input type="submit" id="mapOneSubmit" value="Submit" [add attribute "disabled" here]>
</form>
You can you set the enable/disable inside validate function.
function validate(elem) {
//validation here
//code to disable/enable the button
document.getElementById("mapOneSubmit").disabled = elem.value.length === 0;
}
Set the button disable on load by adding disabled property
<input type="submit" id="mapOneSubmit" value="Submit" disabled>
On your validate function just check if value of input field is blank then enable/disable the button
function validate(input){
input.disabled = input.value === "" ;
}
My problem is, I can't find what event listener listens for "blank" inputs?
You can disable the submit button at render, after that you can use the input event to determine whether the input value is empty or not. From there, you can set state of the submit button.
document.addEventListener('DOMContentLoaded', () => {
const textInput = document.getElementById('mapOneUserInput');
textInput.addEventListener('input', handleTextInput, false);
textInput.addEventListener('keydown', validateInput, false);
});
function handleTextInput(event) {
const { value } = event.target;
if (value) {
enableSubmitButton(true);
} else {
enableSubmitButton(false);
}
}
// Refer to https://stackoverflow.com/a/46203928/7583537
function validateInput(event) {
const regex = /^\d*(\.\d{0,2})?$/g;
const prevVal = event.target.value;
const input = this;
setTimeout(function() {
var nextVal = event.target.value;
if (!regex.test(nextVal)) {
input.value = prevVal;
}
}, 0);
}
function enableSubmitButton(isEnable) {
const button = document.getElementById('mapOneSubmit');
if (isEnable) {
button.removeAttribute('disabled');
} else {
button.setAttribute('disabled', '');
}
}
<input type="number" value="" id="mapOneUserInput">
<!-- Note that the input blank at render so we disable submit button -->
<input type="submit" id="mapOneSubmit" value="Submit" disabled>

Prevent multiple alert on "oninvalid" html

I was thinking, can i stop the alerts after the first?
I'll explain it better, every time I confirm the form, start an aler for every input that has oninvalid.
so if i have 10 inputs, i'll have 10 alarms. Is it possible to interrupt them after the first one?
<form>
<input type="text" oninvalid="alert('test1')" required />
<input type="text" oninvalid="alert('test2')" required />
<button>Send</button>
</form>
Fiddle: https://jsfiddle.net/9d1L5pxd/1/
You can consider doing something like I demonstrate below. Basically just add an event handler to the send button, which will call a validation function on your form each time it's clicked.
The validation function checks all the text type field values. If a text field with an invalid value is encountered, the function will return false (stop immediately).
If the function doesn't find any problems with the user input then it will return true. You can use the return value to determine if the form should be submitted or whatever if you need to.
var btnSend = document.getElementById('btnSend');
btnSend.addEventListener('click', function() {
var isValid = validateForm();
if (isValid)
console.log('Form is ready to submit.');
});
function validateForm() {
var formToValidate = document.getElementById('dataForm');
var elements = formToValidate.elements;
var i;
for (i = 0; i < elements.length; i++) {
if (elements[i].type == 'text') {
//replace this with your actual validation
var invalid = elements[i].value.length == 0;
if (invalid) {
alert(elements[i].id + ' is invalid.');
return false;
}
}
}
return true;
}
<form id="dataForm">
<input id="field1" type="text" required />
<input id="field2" type="text" required />
<input id="btnSend" type="button" value="Send">
</form>

When form submit replace it with inputs value. JavaScript

I have this small form here:
<form action="prekiu-uzsakymas" method="get">
<input type="text" name="ticket" value="8888">
<input type="submit" value="Panaudoti kuponÄ…">
</form>
What I want to do is, when I click submit, the form should be hidden and only the input should appear:
<input type="text" name="ticket" value="8888">
How can I achieve this with javascript ?
Looks like you just want to remove the button. First, give the form and button an ID, then attach to the submit event, where you can do whatever you want to do before submission happens:
jQuery("#my-form-id").submit(function() {
jQuery("#my-button-id").remove(); // or .css("display", "none")
});
In Pure JavaScript, you can remove elements by using the code on the following answer by Johan Dettmar https://stackoverflow.com/a/18120786/886393
Here is a working plunker for your exact case.https://plnkr.co/edit/1HdgiSE770KKghq8DzbS?p=preview
You can define the prototypes for element and nodelist.
Element.prototype.remove = function() {
this.parentElement.removeChild(this);
};
NodeList.prototype.remove = HTMLCollection.prototype.remove = function() {
for (var i = this.length - 1; i >= 0; i--) {
if (this[i] && this[i].parentElement) {
this[i].parentElement.removeChild(this[i]);
}
}
};

JS - Attach the same function to many html forms

I am trying to make an e-commerce-like webpage (for practice) wherein a click on any of the buttons would update the cart value by the number (quantity) specified on the input element.
So far, I was only able to update the cart from the first form because when I try to assign the function on every form using a loop, the cart updates for a millisecond then returns to zero. I assume its because of the scope.
I know there's an easier way to do this without manually assigning the function for every document.forms[n]
JS
window.onload = function()
{
var getForm = document.forms[0];
var numItems = 0;
getForm.onsubmit = function(event)
{
event.preventDefault();
var getInput = getForm.elements["num-item"].value;
if(parseInt(getInput))
{
numItems = numItems + parseInt(getInput);
var getCart = document.getElementById("item-count");
getCart.innerHTML = numItems;
getForm.reset();
}
else
{
alert("Please enter a valid number");
}
}
HTML
Cart:
<div class="basket">
<p><i class="fa fa-shopping-basket"></i></p>
<p id="item-count">0</p>
</div>
HTML Form: For brevity, I'm only posting 1 form example, but in reality, I have 6 other forms that are exactly the same.
<div class="buy-config">
<form class="buy-form" name="buy-form">
<label>Quantity:</label>
<input type="text" class="num-item" />
<button class="buy-btn">Add to Cart</button>
</form>
</div>
Loop through all of the forms by querying the selector (using whatever method you prefer, depending on performance requirements and markup flexibility -- I've used getElementsByClassName) and executing a for loop.
Inside the loop, bind a function to the "submit" event using addEventListener. You can define the function in-line (as I've done), or define the function elsewhere, assign it to a variable, and reference the variable when binding to the event.
Within the event listener function, you will refer to the form that was submitted as this.
On top of the changes described above, I've made some minor changes to your code:
Your previous version was overwriting the contents of the cart each time. This may have been on purpose, depending on whether you have one "basket" for each item or one overall (this wasn't clear in the question). So, rather than initialize numItems to zero, I've initialized it to the current number of items in the cart.
Consider using input type="number" HTML form elements. They're supported by nearly every browser and only accept digits -- they also have up/down arrows and can be set with the scroll wheel. On browsers that don't support them, they fall back to a basic text input.
var forms = document.getElementsByClassName("buy-form");
for (var i = 0; i < forms.length; i++) {
forms[i].addEventListener("submit", function(event) {
event.preventDefault();
var numItems = parseInt(document.getElementById("item-count").innerHTML);
var getInput = this.getElementsByClassName("num-item")[0].value;
if (parseInt(getInput)) {
numItems = numItems + parseInt(getInput);
var getCart = document.getElementById("item-count");
getCart.innerHTML = numItems;
this.reset();
} else {
alert("Please enter a valid number");
}
});
}
<div class="basket">
<p><i class="fa fa-shopping-basket"></i></p>
<p id="item-count">0</p>
</div>
<div class="buy-config">
<form class="buy-form" name="buy-form">
<label>Quantity:</label>
<input type="number" class="num-item" />
<button class="buy-btn">Add to Cart</button>
</form>
</div>
<div class="buy-config">
<form class="buy-form" name="buy-form">
<label>Quantity:</label>
<input type="number" class="num-item" />
<button class="buy-btn">Add to Cart</button>
</form>
</div>
<div class="buy-config">
<form class="buy-form" name="buy-form">
<label>Quantity:</label>
<input type="number" class="num-item" />
<button class="buy-btn">Add to Cart</button>
</form>
</div>
You can use the jQuery selector.
<script src="http://code.jquery.com/jquery-1.12.0.min.js"></script>
<script>
$(document).ready(function() {
$('.buy-btn').click(function(){
$(this).parent('form').submit();
});
});
</script>
<form class="buy-form">
<label>Quantity:</label>
<input type="text" class="num-item" />
<button class="buy-btn">Add to Cart</button>
</form>
The code above will setup a function for each HTML elements that has the css class buy-btn.
You can select anything using parent, children, prev, next or find function from jQuery.
Of course this is just a basic exemple I'm showing here, and again some simple example could be :
$('.buy-btn').click(function(){
$(this).parent('form').submit();
//var itemCount = $('#item-count').html();
//itemCount++;
//$('#item-count').html(itemCount);
var numItem = $(this).prev('.num-item').val();
$('#item-count').html(numItem);
});
Unfortunately, you're going to have to loop through the elements in your JavaScript and assign the function to each, however you can do it a bit simpler with some querySelector methods thrown in:
window.onload = function() {
var getCart = document.getElementById('item-count');
var forms = document.querySelectorAll('.buy-form');
var numItems = 0;
var isNum = function(n) {
return(!isNaN(parseFloat(n)) && isFinite(n));
};
var handler = function(e) {
(e || event).preventDefault();
var getInput = this.querySelector('.num-item').value;
if(isNum(getInput)) {
numItems += parseInt(getInput);
getCart.innerHTML = numItems;
this.reset();
} else {
alert("Please enter a valid number");
}
};
for(var i = 0, len = forms.length; i < len; i++) {
forms[i].addEventListener('submit', handler);
}
};

Fill data in input boxes automatically

I have four input boxes. If the user fills the first box and clicks a button then it should autofill the remaining input boxes with the value user input in the first box. Can it be done using javascript? Or I should say prefill the textboxes with the last data entered by the user?
On button click, call this function
function fillValuesInTextBoxes()
{
var text = document.getElementById("firsttextbox").value;
document.getElementById("secondtextbox").value = text;
document.getElementById("thirdtextbox").value = text;
document.getElementById("fourthtextbox").value = text;
}
Yes, it's possible. For example:
<form id="sampleForm">
<input type="text" id="fromInput" />
<input type="text" class="autofiller"/>
<input type="text" class="autofiller"/>
<input type="text" class="autofiller"/>
<input type="button"value="Fill" id="filler" >
<input type="button"value="Fill without jQuery" id="filler2" onClick="fillValuesNoJQuery()">
</form>
with the javascript
function fillValues() {
var value = $("#fromInput").val();
var fields= $(".autofiller");
fields.each(function (i) {
$(this).val(value);
});
}
$("#filler").click(fillValues);
assuming you have jQuery aviable.
You can see it working here: http://jsfiddle.net/ramsesoriginal/yYRkM/
Although I would like to note that you shouldn't include jQuery just for this functionality... if you already have it, it's great, but else just go with a:
fillValuesNoJQuery = function () {
var value = document.getElementById("fromInput").value;
var oForm = document.getElementById("sampleForm");
var i = 0;
while (el = oForm.elements[i++]) if (el.className == 'autofiller') el.value= value ;
}
You can see that in action too: http://jsfiddle.net/ramsesoriginal/yYRkM/
or if input:checkbox
document.getElementById("checkbox-identifier").checked=true; //or ="checked"

Categories

Resources