Unpoly adds CSS classes to interactive elements that are loading content, and to the fragments they are targeting.
Styling these "feedback classes" is one way to instantly signal that a user interaction has been registered and that the app is working.
We have a link targeting a fragment #target
:
<a href="/path" up-target="#target">Link</a>
<div id="target">
Inital content
</div>
When the user clicks on the /foo
link, the link is instantly assigned the .up-active
class.
The targeted fragment (the <main>
element) gets the .up-loading
class:
<a href="/bar" up-target="#target" class="up-active">Bar</a> <!-- mark-phrase "up-active" -->
<div id="target" class="up-loading"> <!-- mark-phrase "up-loading" -->
Initial content
</div>
Consider styling .up-active
and .up-loading
to signal that the app is working.
Feedback classes remain set while the request is loading.
Once the response is received the .up-active
and .up-loading
classes are removed:
<a href="/path" up-target="#target">Link</a>
<div id="target">
New content from server
</div>
Feedback classes will also be removed if the request ends for any other reason, such as the server rendering an error code or when the request is aborted. See How previews end for more examples for what terminates a request.
To instantly signal that a user interaction has been registered, consider highlighting active links and submit buttons in your CSS:
.up-active:is(a, [up-follow], input[type=submit], button[type=submit], button:not([type])) {
outline: 2px solid blue;
}
To convey which parts of the page have a pending update, consider styling targeted fragments:
.up-loading {
opacity: 0.6;
}
If these CSS rules are not enough, see Loading state for a variety of other strategies. In particular previews give you access to both the origin and targeted elements, and allow to make arbitrary changes to the page while a request loading.
We have a form targeting a fragment #target
:
<form action="/action" up-target="#target">
<input type="text" name="email">
<button type="submit">Submit</button>
</form>
<div id="target">
Initial content
</div>
When the user clicks the submit button, both the button and the form are marked as .up-active
while the form is submitting. The targeted fragment is marked as .up-loading
:
<form action="/action" up-target="#target" class="up-active"> <!-- mark-phrase "up-active" -->
<input type="text" name="email">
<button type="submit" class="up-active">Submit</button> <!-- mark-phrase "up-active" -->
</form>
<div id="target" class="up-loading"> <!-- mark-phrase "up-loading" -->
Initial content
</div>
Consider styling .up-active
and .up-loading
to signal that the app is working.
Sometimes a form is not submitted by pressing a submit button, but by interacting with an input field:
Return
inside a focused field.[up-autosubmit]
is changed[up-validate]
is changedIn these cases that field is considered the origin element that
caused the submission. It is also marked as .up-active
, in addition to the form and its default submit button:
<form action="/action" up-submit class="up-active"> <!-- mark-phrase "up-active" -->
<input type="text" name="email" class="up-active"> <!-- mark-phrase "up-active" -->
<button type="submit">Submit</button> <!-- mark-phrase "up-active" -->
</form>
When rendering from JavaScript, Unpoly will set .up-active
on the origin element
that caused the interaction. For example, when following a link with up.follow()
, that link
will be .up-active
while loading:
up.follow(link)
In situations where Unpoly cannot guess the origin, you can pass it as an { origin }
option.
For example, when button click causes a render pass, that button should be the origin:
up.on('click', '.my-button', function(event) {
up.render({ url: '/path', origin: event.target }) // mark-phrase "origin"
})
To set additional classes on activated origins, push a class name to up.status.config.activeClasses
:
up.status.config.activeClasses.push('activated')
To set additional classes on targeted fragments that are loading new content, push
a class name to up.status.config.loadingClasses
:
up.status.config.loadingClasses.push('fetching')
To disable feedback classes, set an
[up-feedback=false]
attribute:
<a href="/path" up-follow up-feedback="false">Link</a> <!-- mark-phrase "false" -->
From JavaScript you may pass an { feedback: false }
option:
up.follow(link, { feedback: false }) // mark-phrase "false"