sercrod

*load

Summary

*load.file loads JSON data from a user-selected file and merges it into the Sercrod host’s data. *load.session loads JSON from browser sessionStorage and applies the same merge rules. *load.store loads JSON from persistent browser storage backed by IndexedDB and applies the same merge rules. If a staged view is active (via *stage), the JSON is merged into the stage; otherwise it is merged into the live data. *load remains as the legacy-compatible file form, equivalent to *load.file when no storage suffix is used.

Typical use:

Basic example

A simple load button that merges the entire JSON into host data:

<serc-rod id="profile" data='{"user":{"name":"","email":""}}'>
  <p>Name: <span *print="user.name"></span></p>
  <p>Email: <span *print="user.email"></span></p>

  <button type="button" *load.file>Load profile…</button>
</serc-rod>

If the user selects a JSON file like:

{
  "user": {
    "name": "Alice",
    "email": "alice@example.com"
  }
}

then after loading:

Load selected keys into one destination:

<button type="button" *load.file *keys="profile settings" *response="'draft'">
  Load draft
</button>

In this form:

Load selected keys from the current browser session:

<button type="button" *load.session="'profile-draft'" *keys="profile" *response="'draft'">
  Load session draft
</button>

In this form:

Load selected keys from persistent browser storage:

<button type="button" *load.store="'profile-draft'" *keys="profile" *response="'draft'">
  Load persistent draft
</button>

In this form:

Behavior

Aliases and compatibility:

Storage and merge semantics

Key and destination values:

Old spelling:

<button *load="user settings">Load user+settings</button>

This remains supported for compatibility. Treat the value as old *keys syntax.

Error handling:

File input integration

*load.file and legacy *load work both with native file inputs and with regular clickable elements.

Accept attribute:

Stage interaction

*load is designed to cooperate with staged editing:

Typical pattern:

<serc-rod id="editor" data='{"doc":{"title":"","body":""}}'>
  <section *stage>
    <label>
      Title:
      <input *input="doc.title">
    </label>

    <label>
      Body:
      <textarea *input="doc.body"></textarea>
    </label>

    <button type="button" *load.file *keys="doc">Load draft…</button>
    <button type="button" *apply>Apply</button>
    <button type="button" *restore>Restore</button>
  </section>
</serc-rod>

In this pattern:

Evaluation timing

Execution model

Conceptually, the runtime behaves like this for *load:

  1. Sercrod detects a load directive on an element.

  2. It clones the element.

    • All attributes and children are copied as-is.
    • The *load / n-load attribute is preserved on the clone for visibility, but Sercrod does not re-interpret it later.
  3. It resolves the action attribute:

    • *load.file means browser file input.
    • *load.session gives a sessionStorage key.
    • *load.store gives a persistent browser storage key.
    • legacy *load values are treated as old *keys syntax.
  4. It parses *keys and *response (*into is accepted as an alias).

  5. For file loads, it determines the desired accept type:

    • Uses the element’s own accept attribute if present.
    • Otherwise, defaults to "application/json".
  6. It wires source handling:

    • For *load.store, it attaches a click listener that reads the JSON string from IndexedDB.

    • For *load.session, it attaches a click listener that reads the JSON string from sessionStorage.

    • For file loads, if the cloned element is an <input type="file">:

      • Ensures accept is set.
      • Adds a change listener that calls handleFile(file) for the selected file.
    • For file loads on any other element (button, link, etc.):

      • Adds a click listener.
      • That listener creates a temporary <input type="file">, sets accept, and listens for change.
      • When a file is chosen, it calls handleFile(file).
  7. The common JSON path:

    • Reads JSON text from the selected source.
    • Parses the JSON.
    • Merges or places it into _stage or _data according to *keys and *response.
    • Dispatches sercrod-loaded with source details.
    • Calls update().
  8. The cloned element is appended to the parent in the rendered DOM; the original template node is not appended.

Variable creation

*load does not create new template variables:

Scope layering

*load respects the existing scope model:

Because *load is an action on the host data, it does not affect how inner scopes are layered; it only changes the values they eventually read.

Parent access

*load does not introduce a new parent object:

Use with conditionals and loops

You can place *load inside conditional blocks or loops just like any other action element:

Restrictions:

Best practices

Storage backends and adapters

The default *load.file path is intentionally simple: open a file picker, read JSON text, parse it, merge it into _stage or _data, dispatch sercrod-loaded, and update the host. *load.session and *load.store use the same merge step after reading JSON text from browser storage.

That does not mean *load is only a file-picker feature. The important boundary is the merge step. Built-in session/store forms or a file adapter can read JSON from another local source, then pass the parsed value into the same load path.

Useful browser storage patterns:

Recommended data shape:

Do not create more backend-named directives just to name a storage backend. Prefer the action family (*save.file, *save.session, *save.store, and matching load forms), and put backend-specific behavior behind adapters or explicit helpers.

Examples

Full data import:

<serc-rod id="app" data='{"config":{"theme":"light","lang":"en"}}'>
  <pre *literal="JSON.stringify(config, null, 2)"></pre>
  <button type="button" *load.file>Load config…</button>
</serc-rod>

Partial import:

<serc-rod id="app" data='{"user":{},"settings":{}}'>
  <button type="button" *load.file *keys="user settings">
    Load user and settings
  </button>
</serc-rod>

Custom accept type on a native file input:

<serc-rod id="app" data='{"user":{}}'>
  <input type="file" accept="application/json,.json" *load.file *keys="user">
</serc-rod>

Notes