Skip to content

render

Just like on is the input channel for event actions, so too is the render attribute the input channel for result actions.

This attribute can appear on any number of elements - if they all take the same result action, they will all render the same server result.

Rendering is always a granular operation, applying the smallest possible number of DOM mutations. If the server result already matches the current state of the DOM, no changes are applied at all.


position

This attribute controls how the server result is applied to the element.

It can be set to one of the following values:

  • replaceChildren (default)
  • replaceWith
  • before
  • after
  • prepend
  • append

All of these are logically equivalent to the DOM methods with the same names, even if mechanically not identical.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
<div
  render="positionResult"
  position="replaceWith"
>
  <h4>Click the button to replace it with a cat picture.</h4>

  <button
    type="button"
    class="btn"
    on:click="sendPosition"
    on="sendPosition"
    href="/position"
    result="positionResult"
  >
    hey kitty kitty
  </button>
</div>
1
2
3
<img src="../../assets/cat.jpg" alt="cat">

<p class="mb0">Bazinga 😅</p>

Click the button to replace it with a cat picture.


key

This attribute serves the same function as it does in frameworks such as ReactJS: it is a hint to the DOM patcher that helps it distinguish between otherwise similar-looking elements. In KEML, however, it is less restrictive and is never strictly required.

There is no such thing as a free lunch, though. Everything a computer does has some cost associated with it — some costs are just more desirable than others.

key is also not a silver bullet or a general performance optimization applicable in every situation.

Rules of thumb:

  • Use it only for same-tag siblings that can be reordered, inserted, or removed.
  • Do not use it to represent text or attribute differences.
  • Treat it as stable identity, not as data.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<div
  render="keyResult"
  position="replaceWith"
>
  <button
    type="button"
    class="btn mb3"
    on:click="toggleKey"
    on="toggleKey"
    href="/key"
    name="switch"
    value="{ server.getParam('switch') === 'hide' ? 'show' : 'hide' }"
    result="keyResult"
  >
    { server.getParam("switch") } notification
  </button>

  <div>
    {{ if (server.getParam("switch") === "hide") { }}
      <div key="notification" class="admonition info mt0">
        <p class="admonition-title">Info</p>
        <p>Just passing by...</p>
      </div>
    {{ } }}

    <div>
      <dl class="dl">
        <dt>Roses are</dt>
        <dd>red</dd>
        <dt>Violets are</dt>
        <dd>blue</dd>
        <dt>KEML is</dt>
        <dd>awesome</dd>
        <dt>And so are</dt>
        <dd>you</dd>
      </dl>
    </div>
  </div>
</div>

Both the notification message and the definition list are wrapped in their own div elements.

Because the notification identifies itself using the key attribute, the definition list is never disturbed.

Roses are
red
Violets are
blue
KEML is
awesome
And so are
you