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>
Related
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
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>
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>
I was trying to prevent multiple submit. To prevent to submit the same value, I called window.alert to stop the process and tell the user the input value is already registered. The problem is the submit seems to be clickable after the alert window opened. Because after clicking the button several times after the alert window opens, and I closed the alert window. the alert window immediately re-opened without any clicks. the submit button seems to clickable after the windo open. how to disable all input right after the alert window open?
I was trying to disable a button by setting the state. However, it didn't work.
HTML
<form onSubmit={(e) => submitHandler(e)}>
<input
name="words"
value={words}
placeholder="Enter Tag for search"
onChange={(e) => onChangeHandler(e)}
/>
{disable ? (
<h1>updating</h1>
) : (
<button type="submit" disable={disable}>
submit
</button>
)}
</form>
const submitHandler = (e) => {
e.preventDefault();
if (!words) {
return null;
}
setNewSearchWordsState({ ...newSearchWordsState, disable: true });
const newList = list.map((item, idx) => {
if (idx === id) {
item.searchWords.map((searchWord) => {
if (searchWord === words) {
setNewSearchWordsState({ ...newSearchWordsState, words: '' });
window.alert(`${words} already registered`);
}
item.searchWords.push(words.toLowerCase());
});
}
return {
...item,
};
});
updateSearchWords(newList);
setNewSearchWordsState({ words: '', disable: false });
};
You may want try this working sample https://codepen.io/cunlay/pen/BaaROPG
// HTML
<form onsubmit="submitHandler()">
<input id="words" onkeyup="changeHandler()" placeholder="Enter Tag for search" />
<button type="submit" id="btn" disabled=true>Submit</button>
</form>
//JAVASCRIPT
<script>
function changeHandler(){
var words = document.getElementById('words');
var btn = document.getElementById('btn');
var text = words.value;
if(!text){
btn.disabled = true;
}else{
btn.disabled = false;
}
}
function submitHandler(){
//Your code here
alert("submitted");
return false;
}
</script>
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>