In JavaScript, events are actions that happen in an app. They’re triggered by various things like inputs being entered, forms being submitted, and changes in an element like resizing, or errors that happen when an app is running, etc. We can assign an event handler to respond to and handle these events. Events that happen to DOM elements can be handled by assigning an event handler to properties of the DOM object for the corresponding events. In this article, we’ll look at how to use the oninput
and oninvalid
properties of an editable input element.
oninput
The oninput
property of a DOM element lets us assign an event handler to handle the input
event which is fired when the value of an input
, select
, or textarea
element has been changed. It is also fired when any content in an element with the contenteditable
attribute enabled, and also to any element when designMode
is turned on. In the case of contentEditable
and designMode
, the event target is the editing host. If these properties are applied to multiple elements, then the editing host is the nearest ancestor element whose parent isn’t editable.
For input
elements with the type
attribute set to checkbox
or radio
, the input
event will fire whenever a user toggles the control. However, this isn’t always the case for every browser.
The input
event is fired whenever the value changes, unlike the change
event where the event is only fired when the input value is committed, such as when the user presses the Enter key or select a value from a list of options, etc.
For example, we can assign an event handler function to log the input value of an input event as we do in the following HTML code:
<input placeholder="Enter some text" name="name"/>
<p id="value-log"></p>
Then in the JavaScript code, we can write:
const input = document.querySelector('input');
const log = document.getElementById('value-log');
const updateValue = (e) => {
log.textContent = e.target.value;
}
input.oninput = updateValue;
Then we should see an input text box with a p
element that displays the value that was inputted as it’s changed.
Similarly, we can use it for a select
element. First, we write the following HTML code:
<select name="name">
<option value='Apple'>Apple</option>
<option value='Orange'>Orange</option>
<option value='Grape'>Grape</option>
</select>
<p id="value-log"></p>
Then the JavaScript is very similar to what we have before:
const select = document.querySelector('select');
const log = document.getElementById('value-log');
const updateValue = (e) => {
log.textContent = e.target.value;
}
select.oninput = updateValue;
Note that the value is displayed only when we make a selection, so it won’t show any value when we first load the page since we have nothing selected.
For checkboxes, the code is going to be quite different from text input. We have to check for if the checkbox is checked and then get the value if it is if we want to log the checked values.
For instance, if we have the following HTML code for some checkboxes:
<input type='checkbox' value='Apple' name="name" id='0' /> Apple
<input type='checkbox' value='Grape' name="name" id='1' /> Grape
<input type='checkbox' value='Banana' name="name" id='2' /> Banana
<p id="value-log"></p>
Then we have to attach an oninput
event handler function for each checkbox like we do in the following code:
const checkboxes = document.querySelectorAll('input');
const log = document.getElementById('value-log');
let choices = [];
const updateValue = (e) => {
choices[e.target.id] = e.target.checked ? e.target.value : undefined;
log.textContent = choices.join(' ');
}
checkboxes.forEach((c, i) => {
c.oninput = updateValue;
})
In the code above, we looped through all the checkbox elements and set the updateValue
event handler function to the oninput
property of each checkbox element, and then in the updateValue
function, we set the entry in the choices
array by checking for the checked
value for the checkbox with the given ID, and then we set the value
in the choices
array only if it’s checked by checking the e.target.checked
property.
For radio buttons, it’s easier than dealing with checkboxes since there’s only one possible choice for a group of radio buttons. The HTML code is similar to the checkboxes like we have in the following code:
<input type='radio' value='Apple' name="name" id='0' /> Apple
<input type='radio' value='Grape' name="name" id='1' /> Grape
<input type='radio' value='Banana' name="name" id='2' /> Banana
<p id="value-log"></p>
Then in the JavaScript code, we attach an event handler function to each radio button element like we do in the code below:
const radioButtons = document.querySelectorAll('input');
const log = document.getElementById('value-log');
const updateValue = (e) => {
log.textContent = e.target.value;
}
radioButtons.forEach((c, i) => {
c.oninput = updateValue;
})
In the code above, we set the value straight in the value-log
element since we only want the currently selected choice.
oninvalid
We can assign an event handler to handle the invalid
event by setting the oninvalid
property of a DOM element. The invalid
property is fired when the submittable element has been checked and input validation fails. For example, it’ll fire when an input
element has an input that doesn’t meet the requirements defined in the HTML code. The validation is done by checking the required
and pattern
attributes of the input
or textarea
elements.
For example, we can use it for validating the inputs of a form
element:
<form id="form">
<label for="city">First Name</label>
<input type="text" id="first-name" required>
<p id="first-name-error" hidden>Please fill out first name.</p>
<br>
<label for="city">Last Name</label>
<input type="text" id="last-name" required>
<p id="last-name-error" hidden>Please fill out last name.</p>
<br>
<label for="city">Email</label>
<input type="text" id="email" required pattern='[^@\]+@\[^\.]+\..+'>
<p id="email-error" hidden>Please fill out email.</p>
<br>
<button type="submit">Submit</button>
</form>
Then in the corresponding JavaScript code, we can set the oninvalid
property of each input
element to handle the invalid
event of each input
element as we do in the following code:
const form = document.querySelector('form');
const inputs = document.querySelectorAll('input');
inputs.forEach(input => {
input.oninvalid = (e) => {
document.getElementById(`${e.target.id}-error`).removeAttribute('hidden');
}
})
form.onsubmit = (e) => {
console.log(e);
e.preventDefault();
}
Also, we have to call preventDefault()
on the onsubmit
event handler because we don’t want to submit the form values anywhere in this example. To attach the invalid
event handler to all the input
elements, we get all the input
elements with the document.querySelectorAll
method, then we loop each DOM element object and then set the oninvalid
property to our event handler function. Inside the event handler function, we just toggle the hidden
attribute off whenever an invalid
event is fired for the input
element.
The oninput
property of a DOM element lets us assign an event handler to handle the input
event which is fired when the value of an input
, select
or textarea
element has been changed. It also fired when any content in an element with the contenteditable
attribute enabled, and also to any element when designMode
is turned on. We can use it to handle the situation where a value is entered or selected. The event handler function is run whenever input is changed before it’s committed.
We can assign an event handler to handle the invalid
event by setting the oninvalid
property of a DOM element. The invalid
property is fired when the submittable element has been checked and input validation fails. For example, it’ll fire when an input
element has an input that doesn’t meet the requirements defined in the HTML code. The validation is done by checking the required
and pattern
attributes of the input
or textarea
elements.