Features


Markup agnostic

Leverage your existing HTML and CSS knowledge to create powerful forms with no effort.

  • Markup-driven and Intuitive API

    • Just add the data-smark attribute to form fields to enhance them:
      <input name="user" type="text" data-smark>
      
    • And initialize the form with a single line of JavaScript:
      const myForm = new SmarkForm(form_container);
      
  • Does not impose any specific HTML structure or CSS design rules.

    • Designers have complete freedom.

    • Developers don’t have to worry about layout changes.

👉 See the Quick Start section for more details.

Easy to use (low-code)

  • Zero-Wiring: Controls (called trigger components) reach their target fields by its context (position in the form) or by relative paths within the form.
    <button data-smark='{"action": "addItem", "context": "contacts"}'>➕ Add contact</button>
    <button data-smark='{"action": "export"}'>💾 Save</button>
    
  • To handle data import and export from your own code, you just have to listen to onBeforeAction_import and onAfterAction_export events.
    myForm.on("afterAction_export", ({data}) => {
        console.log("Exported data:", data);
    });
    
  • Of course, you can also call the .import() and .export() methods of the whole form (or any field) to import or export data programmatically.

👉 Take a look to the Showcase section to realize how easy it is to create complex forms with little or no JavaScript code.

Nestable forms

  • Forms are just fields of the form type that import/export their data as JSON.
    <fieldset data-smark='{"type": "form", "name": "details"}'>
        <!-- ... -->
    </fieldset>
    
  • They can be nested to any depth.

  • The whole SmarkForm enhanced form is a field of this type.

👉 See them in action….

Variable-length lists

  • Variable-lenght lists of scalars or subforms.
    • With configurable minimum and maximum length.
    • Users can add or remove items by clicking on appropriate buttons (trigger components) configured to call the addItem and removeItem actions.
  • Data is imported/exported as JSON arrays.
    • If non array is attempted to be imported, it is converted to an array with a single item.
  • Can be manually (user drag & drop) or automatically (🚧 comming soon…) sorted.

👉 See them in action….

Context driven hotkeys

  • Attach a keyboard shotcut to a trigger by just adding a hotkey property to the trigger component.
    • Ex.: <button data-smark='{action: "addItem", hotkey: "+"}'>Add Item</button>.
    • Then use Ctrl++ to add an item to the list.
  • Allow users to discover available hotkeys by pressing Ctrl key.
    • Every time the user presses/releases Ctrl, all triggers with a reachable hotkey will get the data-hotkey attribute of the their DOM element is filled/unfilled with the hotkey value.
    • This allows for a very simple CSS arrangement for auto-reveal/unreveal feature.
  • Avoid hotkey cluttering by reusing the same hotkey in different contexts.
    • Hotkeys are attached to triggers and triggers are context-aware.
    • If the same hotkey is used more than once, only the one in the nearest context (depending on the current focus) is activated.

👉 See it in action….

Consistent User Experience

  • Smooth navigation across all forms.
    • Use Tab and Shift+Tab as usual to navigate between fields and controls.
    • Use Enter and Shift+Enter to navigate between fields only, bypassing controls.
      • Use Ctrl+Enter instead of Enter in multiline (textarea) fields.
  • Non-breaking unobtrusive keyboard navigation: triggers are smartly added or removed from navigation flow (with tab) when there is a hotkey to reach them.

  • Automatically enabled/disabled controls (depending on context).
    • I.e.: Add Item and Remove Item triggers are automatically disabled when the list is full or empty, respectively.

👉 Learn more….

JSON based

  • Every single field can import/export its data in the appropriate data type:
    • Forms as JSON objects.
    • Lists as JSON arrays.
    • Numbers as numbers.
    • Dates as well-formed date strings.
    • Booleans as booleans.

👉 See it in action…

Lightweight yet highly compatible

  • Just 37KB minified!

  • Bundled both as modern ES Module and UMD for wide compatibility.

  • > 0.25%, browser coverage thanks to Babel

👉 Check it out…

Flexible and extendable

  • Develop your own component types to suit your specific needs.

  • 🚧 (Not yet implemented) Create you own components on top of SmarkForm templates (I.e.: a complex schedule form returning well known JSON structure).

Directory-like addressability

  • Address any field by from another field by its relative or absolute path.

  • Those paths traverse the form structure: not the DOM.
    • 🚀 This give you full freedom to alter the form layout without breaking the code.
  • They are highly useful to alter triggers’ context and/or targetted fields.

  • They support upper (..) and sibling (.-1) addressing to traverse lists hoizontally and even wildcards (*) to address multiple fields at once.

👉 See the Form Traversing section for more details.

Reliability-oriented

  • It handles edge cases gracefully:
    • If non-Array is attempted to be imported into a list, it is converted to an array with a single item.
    • Textarea fields automatically stringify and pretty-print objects.
  • Null awareness:
    • Non text fields (like number, date, checkbox, etc.) can return null to indicate that the value is unknown or not applicable.
    • Radiobuttons can be unckecked.
    • Color pickers can be cleared and return null to distinguish when the color is unknown or not applicable instead of defaulting to black.

👉 Try it yourself…



Hello footer