How to enable disabled the submit button using JavaScript or jQuery? - javascript

I have a form Data in the HTML like the below,
Blade file:
<form method="post" action="someURL" id="register">
<input type="text" name="name" id="name" />
<div class="error">{{ $errors->first('name') }}</div>
<input type="email" name="email" id="email"/>
<div class="error">{{ $errors->first('email') }}</div>
<textarea name="body" id="message"> Enter your message here</textarea>
<div class="error">{{ $errors->first('message') }}</div>
<input type="submit" id="btnSubmit" disabled />
</form>
<script>
const button = document.querySelector("#btnSubmit");
const buttonExpirationDataKey = 'button-disabled-expiration';
let startButtonStateCheck = () => {
button.dataset.interval = setInterval(updateButtonState, 1000);
}
let updateButtonState = () => {
let expirationDate = new Date(button.dataset.enabledAt);
if (expirationDate < new Date()) {
button.disabled = false;
clearInterval(button.dataset.interval);
} else {
button.disabled = true;
}
}
let buttonDisableExpiration = localStorage.getItem(buttonExpirationDataKey);
if (!buttonDisableExpiration) {
// no button state in localStorage, enable button
button.disabled = false;
} else {
// button state held in localStorage, check every 1s for expiration to enable the button again
button.dataset.enabledAt = buttonDisableExpiration;
updateButtonState();
startButtonStateCheck();
}
button.addEventListener("click", () => {
var form = document.getElementById("register");
var fields = ["name", "email", "body"];
var i, l = fields.length;
var fieldname;
for (i = 0; i < l; i++) {
fieldname = fields[i];
if (form[fieldname].value === "") {
button.disabled = false;
}
else{
button.disabled = true;
let now = new Date();
let expirationTime = 1000 * 10;
let expirationDate = new Date(now.getTime() + expirationTime);
localStorage.setItem(buttonExpirationDataKey, expirationDate);
button.dataset.enabledAt = expirationDate;
startButtonStateCheck();
}
}
});
</script>
In controller::
$data = request()->validate([
'name' => 'required',
'email' => 'required|email',
'body' => 'required',
]);
I have validated the fields in the controller.
The Submit button on click should check whether all the Input Values were given, If either one of the values is missing, the Submit button should be Enabled, even on click. I have given the validation in the controller
In my code, the submit button is disabled every time, when it is clicked even without the input values. But, it shows the error as This field is required near the input fields, when we click the submit button.
I need the submit button to be Disabled on click, when all the input values were given and then storing the button Enabled and Disabled in the Local storage.
When a user submits the form, without entering the form input, the button should be Enabled.
But, the submit button is not working as expected. It gets disabled, even without the form inputs
How could I do this? Could anyone please help?

Here first you will have to prevent the default action of the form so you need to use preventDefault() on event and than after all validations check you can manually submit or enable the button. But the main thing is that you need to disable the default behaviour to add your own custom checks.
Here is a fiddle to show :
https://jsfiddle.net/g6wfkj74/7/
Hope this helped

Related

How to keep the Input field inside the session storage and disabled upon refresh?

I want to disable the input field after the user clicks the "disable" button, and automatically change the "disable" button to "enable", disabling the input fields at the same time. But, if we refresh or press Ctrl+F5, the disabled fields becomes enabled and editable. Below is the code I have, what should I do to keep it disabled even upon refresh and changing the button? Thank you.
html
<input id="firstname"></input>
<input id="lastname"></input>
<input id="email"></input>
<button type="button" class="dropdown-item" id="status">Disable</button>
script
const disableInputs = function() {
sessionStorage.disableInputs = 'true';
document.getElementById('firstname').disabled = true;
document.getElementById('lastname').disabled = true;
document.getElementById('email').disabled = true;
var elem = document.getElementById("status");
if (elem.value=="Disable") elem.value = "Enable";
else elem.value = "Disable";
};
if (sessionStorage.disableInputs === 'true') disableInputs();
document.getElementById('status').onclick = disableInputs;
The button is displaying enable from disable after adding onlick change() but it doesn't save at state upon refresh, is this correct?
<button type="button" onclick="change();" id="status">Disable</button>
function change()
{
var elem = document.getElementById("status");
if (elem.value=="Disable") elem.value = "Enable";
else elem.value = "Disable";
}
Firstly, you need first get state of disabled state from sessionStorage by using getItem and Save data using setItem
disabled = !disabled; used to toggle a variable state, So if it's true change it to false and vice versa.
const status = document.getElementById('status');
const firstname = document.getElementById('firstname');
const lastname = document.getElementById('lastname');
const email = document.getElementById('email');
let disabled = JSON.parse(sessionStorage.getItem("disableInputs") ?? 'false');
firstname.disabled = lastname.disabled = email.disabled = disabled;
status.innerText = disabled ? 'Disable' : 'Enable';
function toggle() {
disabled = !disabled;
firstname.disabled = lastname.disabled = email.disabled = disabled;
status.innerText = disabled ? 'Disable' : 'Enable';
sessionStorage.setItem('disableInputs', disabled);
};
<input id="firstname" />
<input id="lastname" />
<input id="email" />
<button type="button" onclick="toggle();" id="status">Disable</button>
Note: <input> is an empty tag, in that it's not designed to have any content or a closing tag. For compliance, you can signify the end of the tag by using it like this: <input id="firstname" />

Built-in HTML5 form validation for individual fieldset?

Is it possible to use browsers' built-in HTML5 form validation on an individual fieldset?
I'm building a multi step form but would like to use the browser's built-in validation tool to detect and display validation messages for inputs on the currently displayed fieldset, rather than on the entire form (Chrome gives an error here because the input in the hidden fieldset is not focusable, besides I don't want it to validate the second input when the first button is clicked)
I know you can do custom JS validation and error display, but I want to know if it's possible to use the browser validation on an individual fieldset.
const form = document.getElementById('form')
const first = document.getElementById('first')
const second = document.getElementById('second')
form.addEventListener('submit', (e) => {
e.preventDefault();
first.style.display = 'none';
second.style.display = 'block';
})
<form id="form">
<fieldset id="first">
<legend>first</legend>
<input name="firstInput" required>
<button>next step</button>
</fieldset>
<fieldset id="second" style="display: none;">
<legend>second</legend>
<input required name="secondInput">
<button>Submit</button>
</fieldset>
</form>
I've managed to get what I need like this.
Remove required from all inputs that are not displayed when the page loads
When the function to show the next fieldset runs, it sets all the inputs on the newly displayed fieldset (except checkboxes) as required
If you want to move back to the previous fieldset, the function removes required from the inputs in the fieldset you've just hidden, otherwise you wouldn't be able to move forward again (because the <input required> in the hidden fieldset cannot be focused, the htmll5 validation breaks)
At the last step, the form submits as expected
I'm including my code in case it can help someone.
form = document.getElementById('Form');
fieldsets = document.querySelectorAll('fieldset');
back = document.getElementById('back');
nextORsubmit = document.getElementById('nextORsubmit');
let i = 0;
form.addEventListener('submit', (e) => {
if (i < fieldsets.length - 1) {
e.preventDefault();
console.log('Validate, but don\'t send form');
fieldsets[i].style.display = 'none';
fieldsets[i+1].style.display = 'block';
back.style.display = 'inline';
i++;
// set required on current fieldset inputs, except if they're checkboxes
fieldsets[i].querySelectorAll('input:not([type="checkbox"])').forEach (el => {
el.required = true;
})
}
});
back.addEventListener('click', () => {
console.log('going back a step');
fieldsets[i].style.display = 'none';
fieldsets[i-1].style.display = 'block';
i--;
// remove required on inputs from the next fieldset that we've just hid
fieldsets[i+1].querySelectorAll('input:not([type="checkbox"])').forEach (el => {
el.required = false;
})
// remove back button when you go back to the first step
if (i == 0) {
back.style.display = 'none';
}
})
#back,
fieldset:not(:first-of-type) {
display: none;
}
<form id="Form">
<fieldset>
<legend>first</legend>
<input name="firstInput" required>
</fieldset>
<fieldset>
<legend>second</legend>
<input name="secondInput">
</fieldset>
<fieldset>
<legend>third</legend>
<input name="thirdInput">
</fieldset>
<button id="back" type="button">Back</button><br>
<button id="nextORsubmit">Next</button>
</form>

How to dynamically keep track of user inputs in 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.

Confirm deletion alert code not quite right

I'm creating a simple todo app in JS and i've added an alert box to confirm deletion when usr clicks the delete button. If user clicks 'OK' it deletes fine, and if clicked 'Cancel' it won't delete but it creates another empty
li tag under it.
Something is not quite right with my deleteItem function but I can't figure out what, tried adding an else statement same thing happens. Any help with an explanation will be greatly appreciate (I'm a noob in JS as you can tell). Thanks!
//grab form id first
let ourForm = document.getElementById("ourForm");
let ourField = document.getElementById("ourField");
let OurList = document.getElementById("ourList");
//on submit event from user, do something
ourForm.addEventListener("submit", (e) =>{
//will prevent alert appearing on any click event around form, ONLY when submit button is clicked.
e.preventDefault();
//access value of user input as a test
//console.log(ourField.value);
//now on submit we're gonna pass the function below which is created further down and takes one argument and its value:
if(ourField.value === ""){
alert("Please add a task")
}else{
createItem(ourField.value);
}
})
function createItem(item) {
let createdHTML = `<li>${item} <button
onclick="deleteItem(this)">Delete</button></li>`;
ourList.insertAdjacentHTML("beforeend", createdHTML);
//clear the inpur field value after user input:
ourField.value = "";
//keep field focused after clearing
ourField.focus();
}
function deleteItem(itemToDelete){
//create alert
let result = confirm("Are you sure you want to delete?");
if (result === true) {
//Logic to delete the item
itemToDelete.parentElement.remove();
ourField.focus();
}
}
<h1> Todo App</h1>
<form id="ourForm">
<input id = "ourField" type="text" autocomplete="off">
<button> Create item</button>
<h3>To do tasks:</h3>
<ul id="ourList">
</ul>
What you need to change is: make the buttons of the list items of type button. They default value of type for a button is submit, which will submit the whole form, which will trigger your issue.
//grab form id first
let ourForm = document.getElementById("ourForm");
let ourField = document.getElementById("ourField");
let OurList = document.getElementById("ourList");
//on submit event from user, do something
ourForm.addEventListener("submit", (e) =>{
//will prevent alert appearing on any click event around form, ONLY when submit button is clicked.
e.preventDefault();
//access value of user input as a test
//console.log(ourField.value);
//now on submit we're gonna pass the function below which is created further down and takes one argument and its value:
if(ourField.value === ""){
alert("Please add a task")
}else{
createItem(ourField.value);
}
})
function createItem(item) {
let createdHTML = `<li>${item} <button
onclick="deleteItem(this)" type="button">Delete</button></li>`;
ourList.insertAdjacentHTML("beforeend", createdHTML);
//clear the inpur field value after user input:
ourField.value = "";
//keep field focused after clearing
ourField.focus();
}
function deleteItem(itemToDelete){
//create alert
let result = confirm("Are you sure you want to delete?");
if (result === true) {
//Logic to delete the item
itemToDelete.parentElement.remove();
ourField.focus();
}
}
<h1> Todo App</h1>
<form id="ourForm">
<input id = "ourField" type="text" autocomplete="off">
<button> Create item</button>
<h3>To do tasks:</h3>
<ul id="ourList">
</ul>
You forgot to close the form tag after the button, as a result your ourForm listener gets called even for confirmation box.
//grab form id first
let ourForm = document.getElementById("ourForm");
let ourField = document.getElementById("ourField");
let OurList = document.getElementById("ourList");
//on submit event from user, do something
ourForm.addEventListener("submit", (e) =>{
//will prevent alert appearing on any click event around form, ONLY when submit button is clicked.
e.preventDefault();
//access value of user input as a test
//console.log(ourField.value);
//now on submit we're gonna pass the function below which is created further down and takes one argument and its value:
if(ourField.value === ""){
alert("Please add a task")
}else{
createItem(ourField.value);
}
})
function createItem(item) {
let createdHTML = `<li>${item} <button
onclick="deleteItem(this)">Delete</button></li>`;
ourList.insertAdjacentHTML("beforeend", createdHTML);
//clear the inpur field value after user input:
ourField.value = "";
//keep field focused after clearing
ourField.focus();
}
function deleteItem(itemToDelete){
//create alert
let result = confirm("Are you sure you want to delete?");
if (result === true) {
//Logic to delete the item
itemToDelete.parentElement.remove();
ourField.focus();
}
}
<h1> Todo App</h1>
<form id="ourForm">
<input id = "ourField" type="text" autocomplete="off">
<button> Create item</button>
</form>
<h3>To do tasks:</h3>
<ul id="ourList">
</ul>

Disable button after adding task to task list

I would like to add some items to task list and disable button each time. When page loads it works fine.
I'd like to also disable button after adding each task.
If you add a new task and press submit button it works fine. But if the user choose pressing 'Enter' button instead of submit it becomes enabled.
What should it be done to disable submit button if the user prefers 'Enter' button instead of submit button ?
<!DOCTYPE html>
<html>
<head>
<script>
document.addEventListener('DOMContentLoaded', () => {
// By default, submit button is disabled
document.querySelector('#submit').disabled = true;
// Enable button only if there is text in the input field
document.querySelector('#task').onkeyup = () => {
document.querySelector('#submit').disabled = false;
};
document.querySelector('#new-task').onsubmit = () => {
// Create new item for list
const li = document.createElement('li');
li.innerHTML = document.querySelector('#task').value;
// Add new item to task list
document.querySelector('#tasks').append(li);
// Clear input field and disable button again
document.querySelector('#task').value = '';
document.querySelector('#submit').disabled = true;
// Stop form from submitting
return false;
};
});
</script>
<title>Tasks</title>
</head>
Body part of the html.
<body>
<h1>Tasks</h1>
<ul id="tasks">
</ul>
<form id="new-task">
<input id="task" autocomplete="off" autofocus placeholder="New Task" type="text">
<input id="submit" type="submit">
</form>
</body>
</html>
When you click the enter button, your onkeyup event handler changes the submit button disabled state to false, and the enter works.
Instead, listen to the input event of the #task box, and enable/disable the submit button according to the changes in the content. This will also handle the case in which submit is enabled after the text was deleted.
// Enable button only if there is text in the input field
document.querySelector('#task').addEventListener('input', (e) => {
document.querySelector('#submit').disabled = e.target.value === '';
});
Example:
// By default, submit button is disabled
document.querySelector('#submit').disabled = true;
// Enable button only if there is text in the input field
document.querySelector('#task').addEventListener('input', (e) => {
document.querySelector('#submit').disabled = e.target.value === '';
});
document.querySelector('#new-task').onsubmit = () => {
// Create new item for list
const li = document.createElement('li');
li.innerHTML = document.querySelector('#task').value;
// Add new item to task list
document.querySelector('#tasks').append(li);
// Clear input field and disable button again
document.querySelector('#task').value = '';
document.querySelector('#submit').disabled = true;
// Stop form from submitting
return false;
};
#submit:disabled {
opacity: 0.5;
}
<h1>Tasks</h1>
<ul id="tasks">
</ul>
<form id="new-task">
<input id="task" autocomplete="off" autofocus placeholder="New Task" type="text">
<input id="submit" type="submit">
</form>
When you press enter key the event listner keyup is firing. You have to put the enable of button here in conditions
document.querySelector('#task').onkeyup = (e) => {
if(e.which === 13){
return; // When user enter key press
}
document.querySelector('#submit').disabled = false;
};
I was watching Harvard CS50 Web Programming Course and I'd like to share another solution. This is not a part of homework, assignment etc. so I feel free to share solution.
Basically we enable button if there is text in the input field.
// Enable button only if there is text in the input field
document.querySelector('#task').onkeyup = () => {
if (document.querySelector('#task').value.length > 0)
document.querySelector('#submit').disabled = false;
else
document.querySelector('#submit').disabled = true;
};
// By default, submit button is disabled
document.querySelector('#submit').disabled = true;
// Enable button only if there is text in the input field
document.querySelector('#task').onkeyup = () => {
if (document.querySelector('#task').value.length > 0)
document.querySelector('#submit').disabled = false;
else
document.querySelector('#submit').disabled = true;
};
document.querySelector('#new-task').onsubmit = () => {
// Create new item for list
const li = document.createElement('li');
li.innerHTML = document.querySelector('#task').value;
// Add new item to task list
document.querySelector('#tasks').append(li);
// Clear input field and disable button again
document.querySelector('#task').value = '';
document.querySelector('#submit').disabled = true;
// Stop form from submitting
return false;
};
#submit:disabled {
opacity: 0.5;
}
<h1>Tasks</h1>
<ul id="tasks">
</ul>
<form id="new-task">
<input id="task" autocomplete="off" autofocus placeholder="New Task" type="text">
<input id="submit" type="submit">
</form>

Categories

Resources