I am using a document.addEventListener("DOMContentLoaded", function ()
to force the input pattern (first must be a letter, then prevent consecutive spaces, etc.)
Now I want to make a 2nd document.addEventListener("DOMContentLoaded", function () for an email.
(I want to prevent multiple .’s and prevent more than 1 @)
Here is my code for both of the above but it isn’t working, it only capitalizes the email (i kept that option on to see if that part works, which it does but nothing else does work.)
Here is the first part (I also tried something else, removing the first }); at the document.addEventListener("DOMContentLoaded", function () at the start of the 2nd as I heard that should work but that didn’t work either.
document.addEventListener("DOMContentLoaded", function() {
// Function to handle all keypress events
function handleKeyPress(event) {
const input = event.target;
const char = String.fromCharCode(event.which);
// Prevent first character from being a space
if (input.selectionStart === 0 && event.code === "Space") {
event.preventDefault();
return;
}
// Prevent first character from being a non-letter
if (input.selectionStart === 0 && !/^[a-zA-Z]$/.test(char)) {
event.preventDefault();
return;
}
// Prevent consecutive spaces
const lastChar = input.value.charAt(input.selectionStart - 1);
if (char === " " && lastChar === " ") {
event.preventDefault();
return;
}
}
// Attach event listeners to input fields
const inputs = document.querySelectorAll("input[name='real_name'], input[name='display_name']");
inputs.forEach(input => {
input.addEventListener("keypress", handleKeyPress);
// Set text-transform to capitalize to force capitalization of each word
input.style.textTransform = "capitalize";
});
});
document.addEventListener("DOMContentLoaded", function() {
// Function to handle all keypress events
function handleKeyPress2(event) {
const input = event.target;
const char = String.fromCharCode(event.which);
// Prevent first character from being a space
if (input.selectionStart === 0 && event.code === "Space") {
event.preventDefault();
return;
}
// Prevent consecutive spaces
const lastChar = input.value.charAt(input.selectionStart - 1);
if (char === "@" && lastChar === "@") {
event.preventDefault();
return;
}
var key = event.keyCode || event.charCode || event.which;
if (key == 32) {
return false;
} else {
return key;
}
}
// Attach event listeners to input fields
const inputs = document.querySelectorAll("input[name='email']");
inputs.forEach(input => {
input.addEventListener("keydown", handleKeyPress2);
// Set text-transform to capitalize to force capitalization of each word
input.style.textTransform = "capitalize";
});
});
2
Answers
You do not need to attach multiple
DOMContentLoaded
event handlers. You can bind a single one and put all the event handlers for your HTML elements within that.The cause of your issue, however, is because you’re using the
keydown
event on aninput
oftype="email"
. This has some inconsistent behaviour withtype="text"
inputs, as you’ve discovered.Given your goal, the simplest approach would be to use the built-in HTML validators as this will ensure all fields are given a value on submission, and also ensure the email field is of the correct format. This has the additional benefit of working whether or not the user has Javascript enabled in their browser.
Here’s a working example:
Also note that using
text-transform
on aninput
element is extremely bad practice. This is because the field will then not exactly match what the user has typed in. For example, they may think that they typed inFoo
, but they actually enteredfoo
, and your server-side logic will receivefoo
when the form is submit, which is not what the user believed they provided to you.First, one does not even necessarily need a
'DOMContentLoaded'
handler for dealing with input-element related'keypress'
events, as long as the element-query for the latter’s registration starts after the targeted element/s have been made accessible within the DOM.Second, and regardless of whether one registers the event-handling at
'DOMContentLoaded'
, one always should make use of event-delegation in order to handle input-element related'keypress'
events.One would register the event-listener at the closest available parent of all involved input-elements. The main-handler then just needs to validate and distinguish the relevant input-elements in order to forward the element-type/element-name specific handling to the targeted element’s related, more specialized, handler function.