Preventing form submission without using the 'disabled' attribute.

I am having trouble understanding the MDN documentation of the removeEventListener function, and figured I should just ask, so here is my probably incorrect code that I can't at the moment test:
submitReady(ready){

const submit = document.getElementById('submit');

if(submit){
if(ready){
submit.setAttribute('aria-disabled', 'false');
submit.removeEventListener('click', preventDefault);
}else{
submit.setAttribute('aria-disabled', 'true');
submit.addEventListener('click', preventDefault(e));
}
}

}
submitReady(ready){

const submit = document.getElementById('submit');

if(submit){
if(ready){
submit.setAttribute('aria-disabled', 'false');
submit.removeEventListener('click', preventDefault);
}else{
submit.setAttribute('aria-disabled', 'true');
submit.addEventListener('click', preventDefault(e));
}
}

}
Submit buttons, when within a form, submit the form by default, so I figure using "preventDefault" on it is at least half right...? How do I remove the listener when the form is ready so it returns to its default behavior? Is this correct? I am not at a stage where I can adequately test this code yet (I am revising many things in this project and my submit buttons don't currently exist anymore), but I figured I would ask anyway since it seems like this is probably a basic enough question--I'm very much a beginner with this. Also, in case it matters, "submit" is an <input type="submit"> element, not a <button>. Thank you.
74 Replies
Rägnar O'ock
Rägnar O'ock3mo ago
There's multiple ways of making a listener not do it's thing anymore: - if you expect the condition to change often it's better to simply check it on even call, so a simple guard clause at the start of the handler function would do - if you want to actually remove the listener (maybe you need to have another instead or something) you can call removeEventListener on the same element you called addEventListener on. You will need to pass the event you want to stop listening to as well as the callback you set as the handler and the capture flag if you used it. This will de-register the listener on the element and the handler will not be called again. Not that you need to pass the same function instance to both functions for it to work, so if you used an inline arrow function you'll need to refactor it to store it in a var or use a named function instead. - another way of removing a listener is via an AbortSignal. When adding the listener you can pass an abort signal in the options (the option is called signal). When the abort signal is triggered the listener will be removed automatically. This is nice if you want a centralized way of removing multiple listeners at once as you can pass the same signal to multiple addEventListener calls. Though, because we are talking in the context of a form, it's better to subscribe to the submited (or is it submit ? ) event on the form itself and prevent it if needed than to have it on the button itself as it will be triggered by on form submission no matter how the submission was triggered. Maybe you have a submit action on enter in a text field or some code can call the form.submit method in another part of your code or whatever might happen down the line. When listening to events it's important to listen to the right this, you don't care about the fact that the user put the cursor on the button and pressed then realized the mouse button, but you care that the form was submitted, so listen for that instead.
Ray
RayOP3mo ago
Is there a place to read about which listener applies to which element and when? Or is there a way to use console.log to see that information? Because I figured the event was tied to the button being clicked, not the form, but on the other hand I guess it must be part of the form element since no submitting happens if the button is outside of it. Event listeners, specifically, really trip me up. I never know when one applies, it's all trial and error until something happens. Anyway, does this make more sense for what I'm trying to do?
submitReady(ready){

const form = document.getElementsByTagName('form')[0];
const submitButton = document.getElementByID('submit');

if(submitButton){
if(ready){
submitButton.setAttribute('aria-disabled', 'false');
form.removeEventListener('submit', preventDefault);
}else{
submitButton.setAttribute('aria-disabled', 'true');
form.addEventListener('submit', preventDefault);
}
}

}
submitReady(ready){

const form = document.getElementsByTagName('form')[0];
const submitButton = document.getElementByID('submit');

if(submitButton){
if(ready){
submitButton.setAttribute('aria-disabled', 'false');
form.removeEventListener('submit', preventDefault);
}else{
submitButton.setAttribute('aria-disabled', 'true');
form.addEventListener('submit', preventDefault);
}
}

}
I have no idea what a guard clause is or how to use the option parameter, or what an AbortSignal is, and I'm guessing based on point two of what you said, writing the removeEventListener the way I did isn't going to work...? If it's not going to work, then I don't think I know what it means to "pass the event", either. Javascript specifically is extremely difficult for me to grasp most of the time and I'm working with covid vaccine brain today on top of it lol, I'm really sorry if it seems like I'm being frustrating, it's not on purpose.
ἔρως
ἔρως3mo ago
I have no idea what a guard clause is
i don't like this name because it doesn't mean anything, unless you already know what it is it's an early return. if you know that there's nothing else to do, in a function, you can just return for example, you have this line:
if(submitButton){
if(submitButton){
this is wrapping the rest of the code in the function, so, nothing will happen if the submitButton is falsy so, you can just do this:
if(!submitButton) {
return;
}
if(!submitButton) {
return;
}
and you won't have to wrap your entire code in that if
Ray
RayOP3mo ago
OH. Okay early returns I know, I use those all the time, but i never thought to use them like that for some reason. That's a good tip, thank you
ἔρως
ἔρως3mo ago
how do you use them?
Ray
RayOP3mo ago
like this usually, i always have it do something before returning, i never thought to just have it do nothing but that makes just as much sense
No description
No description
ἔρως
ἔρως3mo ago
i mean, if there's nothing to do ...
Ray
RayOP3mo ago
true lol
ἔρως
ἔρως3mo ago
lol but you're doing it correctly but that match gives me pain that's like writing a value, like 5, and that's the last line of the function
Ray
RayOP3mo ago
because there's no return value?
ἔρως
ἔρως3mo ago
the match is an operator that returns a value
Ray
RayOP3mo ago
right yeah
ἔρως
ἔρως3mo ago
in this case, either return the match or use the more appropriate switch
Ray
RayOP3mo ago
i like the match because it uses strict compares, that's all neither function it's running returns anything, they're both voids
ἔρως
ἔρως3mo ago
which hurts my heart even more :/ i get what you mean, but it's just ...
Ray
RayOP3mo ago
lol
Ganesh
Ganesh3mo ago
Is there no switch in php?
Ray
RayOP3mo ago
there's switch, it's matches that's new
ἔρως
ἔρως3mo ago
there is match is not the same as switch, by the way but it can work somewhat the same
Ray
RayOP3mo ago
i just like the matches better more often than not, even if there isn't a return value
Ganesh
Ganesh3mo ago
Is it due to strict comparison as you said?
Ray
RayOP3mo ago
it's that, and i don't have to write the word "break" after each case
ἔρως
ἔρως3mo ago
^ this is actually nice
Ganesh
Ganesh3mo ago
Ahh kk
Ray
RayOP3mo ago
if i want it to fall through for some values and for some reason it would work better as a switch/case, i'll use switch/case but otherwise i like match
ἔρως
ἔρως3mo ago
it's just not an appropriate use of the match - that is all
Ganesh
Ganesh3mo ago
I assume there's no switch expression like c# which doesn't require break iirc tho i think that also can't have void return, i don't think javascript has that either
ἔρως
ἔρως3mo ago
it works the same in c#, javascript and php
Ray
RayOP3mo ago
lol better?
No description
ἔρως
ἔρως3mo ago
NO
Ray
RayOP3mo ago
oh i forgot the default
ἔρως
ἔρως3mo ago
BAD BAD BAD that's the worst of both worlds 🤣
Ganesh
Ganesh3mo ago
Why does switch has true
Ray
RayOP3mo ago
lmao
Ray
RayOP3mo ago
did you know that adding curly braces is allowed for some reason, this will run and it won't yell at me
No description
ἔρως
ἔρως3mo ago
that's horrible!
Ganesh
Ganesh3mo ago
No switch expression returns a value. It's not the same as switch statement
int index = 3;
string greeting = index switch {
1 => "hello",
2 => "hi",
3 => "afternoon"
_=> "how are you"
};

Console.WriteLine(greeting) // "afternoon"
int index = 3;
string greeting = index switch {
1 => "hello",
2 => "hi",
3 => "afternoon"
_=> "how are you"
};

Console.WriteLine(greeting) // "afternoon"
Hmm that didn't format correctly
ἔρως
ἔρως3mo ago
yeah, that looks like the match, but the default isn't _ but default
Ganesh
Ganesh3mo ago
So match also intended to return a value instead?
ἔρως
ἔρως3mo ago
yes
Ganesh
Ganesh3mo ago
Ah okay that makes sense C# doesn't let you return void or any non matching value so you can't do that there
ἔρως
ἔρως3mo ago
php is happy with it, but that doesn't make it any better
Ganesh
Ganesh3mo ago
You can technically return a function tho. Then execute that function
Ray
RayOP3mo ago
php seems to be happy with a lot of things that other languages would be upset about i think i've said this before but i kind of wish my first programming language was anything else because of it lol
Ganesh
Ganesh3mo ago
That seems to be the php and js way
ἔρως
ἔρως3mo ago
considering you can do for($x = 'a'; $x =< 'z'; $x++) echo $x; ...
Ray
RayOP3mo ago
lmao what i love and hate that
Ganesh
Ganesh3mo ago
That's disgusting. Is incrementing a char (I assume that's a char not a string) advance the alphabet index?
Ray
RayOP3mo ago
php doesn't have char, so that's a string
ἔρως
ἔρως3mo ago
yes, and guess what happens if you do this:
$x = 'z';
$x++:
echo $x;
$x = 'z';
$x++:
echo $x;
Ganesh
Ganesh3mo ago
Hmm what would happen if you had two letters then? 'aa' Is it a? Or NaN
ἔρως
ἔρως3mo ago
'aa'
Ganesh
Ganesh3mo ago
Lol
ἔρως
ἔρως3mo ago
then 'ab' and then 'ac'... to 'zz', then 'aaa' ...
Ray
RayOP3mo ago
that's great lol
Ganesh
Ganesh3mo ago
So incrementing aa would give ab
ἔρως
ἔρως3mo ago
yup and if you use capitals, it will increment the capitals guess what a9 gives next
Ray
RayOP3mo ago
i'm gonna guess it's aa9 or something, not a10
Ganesh
Ganesh3mo ago
aj ?
ἔρως
ἔρως3mo ago
nope a9 goes to b0 and z9 goes to aa0
Ray
RayOP3mo ago
what is going on under the hood that makes this happen lol
Ganesh
Ganesh3mo ago
Ok so it increments the number and the alphabet at the same time
ἔρως
ἔρως3mo ago
yup
Ganesh
Ganesh3mo ago
This is unholy Tho very funny
ἔρως
ἔρως3mo ago
i mean, it makes sense, because it's wrapping around for example, z9z8 gives z9z9 which then gives aa0a0 it's not wrap around, it's carry it goes from a to z, 0 to 9 when you increment 9, it tries to increment the character before, which is a letter and then you increment the letter, which is z, so, the next one is a
Ganesh
Ganesh3mo ago
Wait why did it only increment 8 at first then next it incremented both 9
ἔρως
ἔρως3mo ago
but you have a carry of 1, so, it converts to a letter and adds before
Ganesh
Ganesh3mo ago
Ah nevermind carry on with explanation
ἔρως
ἔρως3mo ago
like 9 -> 10, or z -> aa the 1 or a is the carry value follows the normal rules that's the explanation
Ray
RayOP3mo ago
i had to see this for myself, this is incredibly funny
No description
No description
Ganesh
Ganesh3mo ago
Right right I get it now
ἔρως
ἔρως3mo ago
it's a bit confusing at first it goes that far because zyz is lower than zz because y is lower than z the length doesn't matter for some reason
Ray
RayOP3mo ago
this is so cursed i love it
ἔρως
ἔρως3mo ago
it is cursed

Did you find this page helpful?