*prevent
Summary
*prevent is a shorthand for *prevent-default. It attaches low-level listeners that call event.preventDefault() for specific events on the host element:
- Enter key presses (
keydown). - Form
submitevents (when the host is a<form>). - Or both, depending on the mode.
Unlike many other directives, the attribute value is not a Sercrod expression. It is a simple mode string such as enter, submit, or all.
Basic example
Prevent the browser’s default form submission, but still run your handler:
<serc-rod id="form-app" data='{"status": null}'>
<form *prevent="submit" @submit="status = 'saved'">
<input type="text" name="title">
<button type="submit">Save</button>
<p *if="status" *print="status"></p>
</form>
</serc-rod>
In this example:
- The browser’s built-in form submission is blocked.
- The
@submit="status = 'saved'"handler still runs. - The page does not navigate away; you stay in the current Sercrod host.
Behavior
*prevent and *prevent-default are handled by the same runtime branch:
-
If the element has either
*prevent-defaultor*prevent, Sercrod:- Reads the raw attribute value.
- Interprets it as a mode string.
- Installs one or more DOM event listeners on the host element.
-
Supported modes (case-insensitive):
enter(default)submitall
-
Defaulting:
- If the attribute value is empty or omitted, the mode is treated as
enter.
- If the attribute value is empty or omitted, the mode is treated as
Behavior by mode:
-
enter:- Attaches a
keydownlistener to the host. - When
e.key === "Enter", it callse.preventDefault(). - No
submitlistener is installed.
- Attaches a
-
submit:- If the host element is a
<form>, attaches asubmitlistener. - That listener always calls
e.preventDefault()on submit. - No
keydownlistener is installed for Enter.
- If the host element is a
-
all:-
Installs both:
keydownlistener that blocks the Enter key.submitlistener on<form>that blocks form submission.
-
Any other mode string:
- If the mode is not
enter,submit, orall, no listeners are attached. - The directive effectively does nothing in that case.
Relationship to *prevent-default
*prevent is purely syntactic sugar:
-
The runtime branch is shared:
- It checks for
*prevent-defaultor*prevent. - It uses whichever attribute is present to read the mode string.
- It checks for
-
This means:
*prevent-defaultand*preventaccept the same set of modes.- They produce the same effect when given the same mode.
Typical usage patterns:
-
Verbose form:
<form *prevent-default="all" @submit="save()"> ... </form> -
Shorthand:
<form *prevent="all" @submit="save()"> ... </form>
In both cases:
- The browser’s default form submission is blocked.
- Sercrod event handlers attached via
@submitstill run.
Modes in detail
Mode string handling:
- The raw attribute value is not evaluated as an expression.
- It is treated as plain text and converted to lower case internally.
- Whitespace is not trimmed inside; you should write simple tokens such as
enterorsubmit.
Supported modes:
-
enter(default):-
Installs
keydownlistener:- On any element, when Enter is pressed (
e.key === "Enter"),e.preventDefault()is called.
- On any element, when Enter is pressed (
-
Recommended when:
-
You want to prevent Enter from triggering built-in behaviors, for example:
- Implicit form submit.
- Activating a focused control in a way you do not want.
-
-
-
submit:-
Effective only when the host is a
<form>. -
Installs a
submitlistener that always callse.preventDefault(). -
Recommended when:
- You want full manual control over form submission via
@submitor other handlers. - You intend to submit via
fetch,XMLHttpRequest, or some other custom logic.
- You want full manual control over form submission via
-
-
all:-
Combines the two:
- Blocks Enter key default on the host.
- Blocks native form submit if the host is a
<form>.
-
Recommended when:
- You want to make sure that neither Enter nor submit cause any built-in navigation or reload.
-
Evaluation timing
*prevent and *prevent-default are processed when Sercrod renders each element:
- After attribute-based handlers (
@click,@submit, and so on) are attached. - Before Sercrod moves on to other non-structural directives on the same element.
Important points:
- The mode is read once when the element is processed.
- The mode string is not re-evaluated on subsequent updates.
- Changing the attribute value after initial render does not reconfigure the listeners.
- The listeners remain attached for the lifetime of the host element.
Execution model
Conceptually, the runtime flow for *prevent looks like:
-
Detect:
- Check whether the node has
*prevent-defaultor*prevent.
- Check whether the node has
-
Read mode:
raw = value of "*prevent-default" or "*prevent" (whichever exists).mode = (raw || "enter").toLowerCase().
-
Attach listeners:
-
If
modeisenterorall:-
Add a
keydownlistener like:- On
keydown, ife.key === "Enter", calle.preventDefault().
- On
-
-
If
modeissubmitoralland the host is a<form>:- Add a
submitlistener that always callse.preventDefault().
- Add a
-
-
Continue:
- Sercrod continues processing other directives and attributes as usual.
- Event handlers registered via
@...attributes are not replaced; they remain intact.
Interaction with Sercrod event handlers
*prevent is complementary to the @ event system:
*preventcontrols whether the browser’s default action runs.@event="handler(...)"controls which Sercrod expression is executed.
Example: manual form handling
<serc-rod id="login-app" data='{"error": null}'>
<form *prevent="submit" @submit="login()">
<input type="text" name="user">
<input type="password" name="pass">
<button type="submit">Log in</button>
<p *if="error" *print="error"></p>
</form>
</serc-rod>
In this setup:
- The
submitevent is delivered to the Sercrod handlerlogin(). - The browser does not perform a real HTTP form submission.
- You are free to implement
login()withfetch, show errors in the page, etc.
Key points:
*preventdoes not automatically invoke your handlers.- It only changes whether the browser’s built-in behavior (navigation, form submit) happens.
- You should still define
@submit,@keydown, or other@eventhandlers as needed.
Use cases
Typical scenarios where *prevent is useful:
-
Prevent accidental form submissions:
- When you want to treat the Enter key as “do nothing” or “move focus” instead of “submit now”.
-
Single-page flows:
- When forms are handled entirely in JavaScript, and navigating away would destroy state.
-
Controlled forms:
- When you have a Sercrod-based validation or saving flow and do not want an actual page reload.
Best practices
-
Always specify a mode for clarity:
*prevent="submit"for forms.*prevent="enter"for non-form controls where Enter should be ignored.*prevent="all"when you want both behaviors.
-
Prefer
*preventfor readability:- Use
*prevent="submit"instead of the longer*prevent-default="submit"wherever you can. - Both are supported, but
*preventis shorter and easier to scan.
- Use
-
Keep in mind it is not an expression:
- Do not write
*prevent="enablePrevent ? 'submit' : null". - The directive will treat that entire string literally and not evaluate it.
- Do not write
-
Combine with
@handlers:*preventis most useful when combined with explicit handlers that implement your custom logic.- For example,
*prevent="submit" @submit="saveDraft()"gives you full control without navigation.
Additional examples
Block Enter on a text input:
<input type="text"
*prevent="enter"
@keydown="onKeydown($event)">
- Enter key default is blocked.
- Your
onKeydownhandler still receives the event via@keydown.
Block both Enter and submit on a form:
<form *prevent="all" @submit="save()">
<input type="text" name="title">
<button type="submit">Save</button>
</form>
- Enter in the form does not cause a browser-level submit.
- Clicking the submit button does not perform a native submit.
- Your
save()handler still runs.
Notes
-
*preventand*prevent-defaultshare a single implementation branch and support the same modes. -
The attribute value is a plain mode string, not a Sercrod expression; unsupported mode strings result in no special behavior.
-
*preventonly covers Enter keydown and form submit:- It does not automatically block other keys or mouse events.
- For more complex behaviors, combine
*preventwith explicit@eventhandlers and custom logic.
-
There are no Sercrod-level restrictions on combining
*preventwith other directives on the same element, but:- It only affects Enter and
submit. - It does not alter the semantics of other structural or data-binding directives.
- It only affects Enter and