sercrod

*load

Summary

*load loads JSON data from a user-selected file and merges it into the Sercrod host’s data. If a staged view is active (via *stage), the JSON is merged into the stage; otherwise it is merged into the live data. The directive has an alias n-load.

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>Load profile…</button>
</serc-rod>

If the user selects a JSON file like:

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

then after loading:

Behavior

Alias:

Storage and merge semantics

Attribute value:

Error handling:

File input integration

*load works 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="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 *load or n-load 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 reads the *load attribute:

    • Trims the text.
    • If non-empty, splits it into a list of property names (props).
    • If empty, leaves props as null.
  4. It determines the desired accept type:

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

    • 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.
    • Otherwise (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).
  6. handleFile(file):

    • Uses FileReader to read the file as text.

    • In the onload handler:

      • Parses the JSON.
      • Merges it into _stage or _data according to props.
      • Dispatches a sercrod-loaded event with details.
      • Calls update().
  7. 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

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>Load config…</button>
</serc-rod>

Partial import:

<serc-rod id="app" data='{"user":{},"settings":{}}'>
  <button type="button" *load="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="user">
</serc-rod>

Notes