I have a click event associated with a button that calls the resetForm() function. This function clears the values of the inputs and clears the fields_entity session that stored the values in real time. When checking the log inside the resetForm function, it is observed that the session is null. However, when changing the option in the select element, the previously filled and cleared values are reinserted into the inputs that were cleared. The second session check within the roleOption() function, which is called on the change event associated with #role, shows the fields_entity session with the last inserted values as if the session still exists. It is worth noting that all of this was done without reloading the page. My question is to understand why this behavior occurs. I managed to solve it in some ways, but I would really like to understand why the fields_entity still exists. I'm not sure if there's something I might be missing in the autosave function.
<!DOCTYPE html>
<html lang="en">
<head>
<title>Document</title>
</head>
<body>
<form class="form user">
<h2>Cadastrar <span></span></h2>
<label for="role">Choose your role</label>
<select id="role" name="role">
<option value="teacher" name="teacher">Teacher</option>
<option value="student" name="student">Student</option>
<option value="adm" name="adm">Collaborator</option>
</select>
<label for="name">Full name</label>
<input type="text" id="name" name="name">
<label for="email">Email</label>
<input type="email" id="email" name="email" novalidate>
<label for="password">Password</label>
<input type="password" id="password" name="password">
<div class="strength-pwd"></div>
<button type="submit">Register</button>
<button type="button" onclick="resetForm();"> Clear formulary</button>
</form>
<script>
function autosave(form, id) {
let fields = sessionStorage.getItem(`fields_${id}`);
fields ? (fields = JSON.parse(fields)) : (fields = {});
Array.from(form.elements).forEach(input => {
if (input.tagName === "INPUT" || input.tagName === "SELECT") {
input.addEventListener("input", () => {
fields[input.name] = input.value;
sessionStorage.setItem(`fields_${id}`, JSON.stringify(fields));
});
}
});
Object.keys(fields).forEach(key => {
const input = document.querySelector(`input[name="${key}"], select[name="${key}"]`);
if (input) {
input.value = fields[key];
}
});
}
const form = document.querySelector(".form.user");
const role = document.querySelector("#role");
function roleOptions() {
autosave(form, "entity"); //Second check = {name : ..., email...};
let roleValue = role.value;
switch (roleValue) {
case "student":
studentFormulary();
break;
case "teacher":
teacherFormulary();
break;
case "adm":
admFormulary();
break;
default:
studentFormulary();
break;
}
};
role.addEventListener("change", roleOptions);
function resetForm() {
form.querySelectorAll("input").forEach(e => { e.value = ""; });
sessionStorage.removeItem("fields_entity"); //First check = null
}
function studentFormulary() {
//...
}
function teacherFormulary() {
//...
}
function admFormulary() {
//...
}
roleOptions();
</script>
</body>
</html>
I'm not interested in finding the solution to this problem in this case, but rather in understanding its behavior. Everything I've tried to identify it was using console.log to observe the presence of values, but I didn't come to any conclusion.
The issue is that you added an
inputevent listener for the<input>and<select>elements that updates thesessionStoragewhenever the field changes in theautosavefunction.addEventListenerdoes not remove previous event listeners, so you get more listeners every timeautosaveis called.The
autosavefunction forms a closure over thefieldsvariable, which is just the value taken from thesessionStorageat the time the function is called. Even when the sessionStorage is cleared,fieldsremains the same object.