I agree with some of the perceived issues, but not entirely with the solution.
I think this is what state machines are for. The disabled attribute is in a sense part of the button's own state-oriented behaviours, but as mentioned it isn't really sufficient to prevent other interactions or submissions. You can prevent form submissions and/or ignore them by orchestrating form UI and interactions within a state machine, though.
It sounds complex, but it's an abstraction that can be easily reused across forms, and it's not an expensive abstraction. If you're using JS, it's a trivial addition that can provide easily tested, robust, reliable form behaviours that respect your users and your business logic.
I've wondered many times why something like <form id="my-form
disabled> isn't possible.
I think this is what state machines are for. The disabled attribute is in a sense part of the button's own state-oriented behaviours, but as mentioned it isn't really sufficient to prevent other interactions or submissions. You can prevent form submissions and/or ignore them by orchestrating form UI and interactions within a state machine, though.
It sounds complex, but it's an abstraction that can be easily reused across forms, and it's not an expensive abstraction. If you're using JS, it's a trivial addition that can provide easily tested, robust, reliable form behaviours that respect your users and your business logic.
I've wondered many times why something like <form id="my-form disabled> isn't possible.