Value Coercion

SmarkForm automatically normalises imported values to match the expected type and shape of each field. This keeps your forms resilient to data-model changes and ensures that what you save is always clean and well-typed.

Scalar-to-Array List Coercion

When a list field receives a non-array value β€” a plain string, a number, or an object β€” it automatically wraps it in a single-item array.

This is particularly useful for model migrations: if a field that used to hold a single email string is upgraded to accept a list of emails, old saved data continues to work without any transformation step.

Exporting Empty Items

By default, empty items are not exported (exportEmpties: false). This keeps saved data clean by omitting blank rows.

Set "exportEmpties": true on the list to preserve empty slots β€” useful in draft-save workflows where you want to retain the user’s position in the list.

πŸ”—
πŸ—’οΈ HTML
🎨 CSS
βš™οΈ JS
πŸ‘οΈ Preview
πŸ“ Notes
❓
<div id="myForm">
    <button data-smark='{"action":"removeItem","context":"email","preserve_non_empty":true}' title="Remove email">βž–</button>
    <button data-smark='{"action":"addItem","context":"email"}' title="Add email">βž•</button>
    <strong data-smark="label">Emails:</strong>
    <ul data-smark='{"type":"list","name":"email","of":"input","min_items":0}'>
        <li data-smark='{"role":"empty_list"}'>(No emails on record)</li>
        <li><input type="email" data-smark placeholder="name@example.com"></li>
    </ul>
</div>
#myForm ul {
    list-style: none;
    padding-left: 0;
}
const myForm = new SmarkForm(document.getElementById("myForm"), {
    "value": {
    "email": "alice@example.com" // Old data saved before upgrading to an array
}
});

πŸ‘‰ Scalar-to-array coercion: If you import a plain string instead of an array, SmarkForm automatically places it in a single-item list.

  • Click ⬇️ Export, change ["alice@example.com"] to just "alice@example.com" in the JSON playground editor below, then click ⬆️ Import β€” the single email is placed in the list automatically.
  • This mirrors the upgrade from a single-value field (e.g. "email") to a list field (e.g. "emails": [...] ).

πŸ‘‰ Empty items are not exported by default (controlled by exportEmpties).

  • Click βž• to add a blank item, then ⬇️ Export β€” the blank row will be absent from the output, keeping saved data clean.
  • Set "exportEmpties": true on the list to keep blank slots in the data (useful in draft-save workflows where you want to preserve the user’s position in the list).

Every example in this section comes with many of the following tabs:

  • HTML: HTML source code of the example.
  • CSS: CSS applied (if any).
  • JS: JavaScript source code of the example.
  • Preview: Live, sandboxed rendering of the example β€” fully isolated from the page styles.
  • Notes: Additional notes and insights for better understanding. Don't miss it‼️

✨ In the Preview tab, a JSON playground editor is available with handy buttons:

  • ⬇️ Export to export the form data to the JSON playground editor.
  • ⬆️ Import to import data from the JSON playground editor into the form.
  • ♻️ Reset in forms prefilled with sample data, resets the form to its default values.
  • ❌ Clear to clear the whole form.

πŸ’‘ The JSON playground editor is part of the SmarkForm form itself β€” it is just omitted from the code snippets to keep the examples focused on what matters.

πŸ› οΈ Between the tab labels and the content there is always an edit toolbar:

  • ✏️ Edit β€” activates edit mode: each source tab turns into a syntax-highlighted code editor (powered by Ace) pre-filled with the full, merged source. Changes are sandboxed β€” the original example is not affected.
  • πŸ“‹ Include playground editor β€” (only visible in edit mode) controls whether the JSON playground editor is included in the preview. When toggled, the HTML and JS editors update instantly so you can see exactly what code is needed to add or remove it.
  • ▢️ Run β€” (only visible in edit mode) re-renders the Preview from the current editor contents and switches to the Preview tab.

Number, Date, Time, and JSON Coercion

Fields with a specific HTML type automatically coerce values on both import and export:

  • <input type="number"> exports a JavaScript number (not a string), and accepts string representations on import (e.g. "28" β†’ 28).
  • <input type="date"> exports an ISO 8601 string (YYYY-MM-DD), and accepts compact strings (YYYYMMDD) and Date objects on import.
  • <input type="time"> exports HH:MM:SS and accepts HH:MM on import.
  • Any field exports null when empty, to explicitly signal β€œunknown or indifferent” rather than an empty string.

Adding {"encoding":"json"} to any <input> or <textarea> enables JSON round-trips: the field stores the value internally as a JSON string but exports it as a parsed JavaScript value (object, array, number, or null).

πŸ”—
πŸ—’οΈ HTML
🎨 CSS
βš™οΈ JS
πŸ‘οΈ Preview
πŸ“ Notes
❓
<div id="myForm">
    <p>
        <label data-smark>Name:</label>
        <input type="text" name="name" data-smark>
    </p>
    <p>
        <label data-smark>Age:</label>
        <input type="number" name="age" min="0" max="150" data-smark>
    </p>
    <p>
        <label data-smark>Date of Birth:</label>
        <input type="date" name="dob" data-smark>
    </p>
    <p>
        <label data-smark>Metadata (JSON):</label>
        <textarea name="metadata" data-smark='{"encoding":"json"}'></textarea>
    </p>
</div>
const myForm = new SmarkForm(document.getElementById("myForm"), {
    "value": {
    "name": "Alice",
    "age": "28",  // String instead of number, will be coerced to a number
    "dob": "19960315", // Correctly parsed as date.
    "metadata": { // Will be exported/imported as JSON
                  // If invalid exports null (catch that from validation)
        "subscribed": true,
        "tier": "premium"
    }
}
});

πŸ‘‰ Number coercion: The Age field is <input type="number">.

  • SmarkForm always exports its value as a JavaScript number, not a string.
  • It also accepts string representations on import β€” try clicking ⬇️ Export, changing "age": 28 to "age": "28" (quoted) in the JSON playground editor, and clicking ⬆️ Import: the exported result will be "age": 28 (unquoted) again.

πŸ‘‰ Date normalization: The Date of Birth field is <input type="date">.

  • SmarkForm always exports an ISO 8601 string (YYYY-MM-DD).
  • It accepts compact strings (YYYYMMDD) and Date objects on import. Try clicking ⬇️ Export, changing "dob": "1996-03-15" to "dob": "19960315" in the JSON playground editor, and clicking ⬆️ Import β€” it will be normalised to "1996-03-15" on the next export.

πŸ‘‰ JSON encoding: The Metadata textarea has {"encoding":"json"}.

  • On import, an object or array is serialised to JSON text (pretty-printed in textareas for readability).
  • On export, the textarea content is parsed back into a JavaScript value β€” your saved data contains a real object, not a raw JSON string.
  • Works with any valid JSON: objects, arrays, numbers, booleans, and null.

Every example in this section comes with many of the following tabs:

  • HTML: HTML source code of the example.
  • CSS: CSS applied (if any).
  • JS: JavaScript source code of the example.
  • Preview: Live, sandboxed rendering of the example β€” fully isolated from the page styles.
  • Notes: Additional notes and insights for better understanding. Don't miss it‼️

✨ In the Preview tab, a JSON playground editor is available with handy buttons:

  • ⬇️ Export to export the form data to the JSON playground editor.
  • ⬆️ Import to import data from the JSON playground editor into the form.
  • ♻️ Reset in forms prefilled with sample data, resets the form to its default values.
  • ❌ Clear to clear the whole form.

πŸ’‘ The JSON playground editor is part of the SmarkForm form itself β€” it is just omitted from the code snippets to keep the examples focused on what matters.

πŸ› οΈ Between the tab labels and the content there is always an edit toolbar:

  • ✏️ Edit β€” activates edit mode: each source tab turns into a syntax-highlighted code editor (powered by Ace) pre-filled with the full, merged source. Changes are sandboxed β€” the original example is not affected.
  • πŸ“‹ Include playground editor β€” (only visible in edit mode) controls whether the JSON playground editor is included in the preview. When toggled, the HTML and JS editors update instantly so you can see exactly what code is needed to add or remove it.
  • ▢️ Run β€” (only visible in edit mode) re-renders the Preview from the current editor contents and switches to the Preview tab.

See also: Data Import and Export, Form Types, List Types