SmarkForm
🚀 Powerful while effortless Markup-driven and Extendable form controller.
SmarkForm is a lightweight library designed for front-end developers and designers to enhance HTML forms with powerful features like subforms and dynamic, variable-length lists, context driveh hotkeys and more…
🔧 It seamlessly integrates with the DOM to provide a markup-agnostic solution, freeing your form layout from rigid structure and styling constraints while enabling JSON form data import and export and ensuring compatibility with modern workflows.
♿ With a focus on accessibility (a11y), SmarkForm offers configurable hotkeys, smooth navigation, and a low-code experience, making it an extendable and versatile tool for building HTML form applications.
[More…]
Main Features
<>Markup agnostic: Maximum decoupling between design and development teams.🧩Low code: No manual wiring between controls and fields.🗂Subforms: Nested forms to any depth.📑Lists: Sortable and variable-length lists (arrays) either of scalars or subforms.🫳Configurable hot keys: Context-driven and discoverable keyboard shortcuts.🫶Consistent UX: Smooth navigation and consistent behaviour across all forms.{}JSON format: Data is imported / exported as JSON.🪶Lightweight: Only 43KB minified.♿Accessibility: Focus on UX and accessibility (a11y).🆓Dependency-free: No external dependencies required.💪Flexible, extendable and more…
Sample Code
The following code snippet shows SmarkForm simplicity.
✅ Click everywhere in the form to focus it.
✅ Hit the Ctrl key to see the available hotkeys revealed. Notice they may change depending on the focused context.
✅ Check the JS tab to see that there is no JS code other than the library instantiation.
✅ Check the HTML tab to see that how straightforward and simple it is.
<div id="myForm">
<p>
<label data-smark='{"type": "label"}'>Name:</label>
<input name='name' data-smark='{"type": "input"}' />
</p>
<p>
<label data-smark='{"type": "label"}'>Surname:</label>
<input name='surname' data-smark='{"type": "input"}' />
</p>
<button data-smark='{"action":"removeItem", "context":"phones", "target":"*", "hotkey":"Delete", "preserve_non_empty":true}' title='Remove unused fields'>🧹</button>
<button data-smark='{"action":"removeItem", "context":"phones", "hotkey":"-", "preserve_non_empty":true}' title='Remove phone number'>➖</button>
<button data-smark='{"action":"addItem","context":"phones", "hotkey":"+"}' title='Add phone number'>➕ </button>
<strong data-smark='label'>Phones:</strong>
<ul data-smark='{"name": "phones", "of": "input", "sortable":true, "max_items":5, "exportEmpties": true}'>
<li class="row">
<label data-smark>📞 Telephone
<span data-smark='{"action":"position"}'>N</span>
</label>
<button data-smark='{"action":"removeItem", "hotkey":"-"}' title='Remove this phone number'>➖</button>
<input type="tel" data-smark>
<button data-smark='{"action":"addItem", "hotkey":"+"}' title='Insert phone number'>➕ </button>
</li>
</ul>
</div>
/* *******************************************************************
✔ The only `CSS` code is almost just to materialize the hotkeys hints
when pressing the `Ctrl` key (Remember SmarkForm is HTML agnostic).
******************************************************************* */
/* Materialize hotkey hints from data-hotkey attribute */
#myForm [data-hotkey] {
position: relative;
overflow-x: display;
}
#myForm [data-hotkey]::before {
content: attr(data-hotkey);
display: inline-block;
position: absolute;
top: 2px;
left: 2px;
z-index: 10;
pointer-events: none;
background-color: #ffd;
outline: 1px solid lightyellow;
padding: 2px 8px;
border-radius: 4px;
font-weight: bold;
font-family: sans-serif;
font-size: 0.8em;
white-space: nowrap;
transform: scale(1.8) translate(0.1em, 0.1em);
}
/* Hide list bullets */
#myForm ul li {
list-style-type: none;
}
/* Make disabled buttons more evident: */
#myForm :disabled {
opacity: 0.4;
}
const myForm = new SmarkForm(document.getElementById("myForm"));
Phones:
👉 This is a simple form to show the power of SmarkForm.
- Tinker with it in the Preview tab, modifying data, etc…
- Add or remove items from the Phones list.
- Sort the list by dragging them with the mouse.
- Use the
⬇️to export the data as JSON. - Use the
❌to clear the form. - Use the
⬆️to import the JSON back to the form. You can modify the JSON before importing it back.
- Notice you can navigate forward and backward using the keyboard:
- Using the
EnterandShift+Enterfrom field to field bypassing control buttons. - Using the
TabandShift+Tabas usual, to reach both fields and control buttons. - Don’t miss the hotkeys! Move the focus to a telephone field and hit the
Ctrlkey to see the avaliable ones (depending on focused context) revealed.
- Using the
👉 Its behavior is driven by the data-smark attributes, which are declarative and intuitive with straightforward defaults to match most common use cases.
-
…for instance, min_items is set to 1 by default, so you cannot remove the last item from the Phones list. But you can change it by setting min_items to 0, allowing an empty list.
-
Another interesting case is the exportEmpties property, which is set to
falseby default, so empty items are not usually exported. In this example, it is set totruesince, for a first contact, it might seem counterintuitive.
👉 Check the JS tab to see the little JS just to initialize it as a SmarkForm and show you the data when exported.
👉 In the CSS tab you will find some non-essential CSS primarily to materialize hotkeys’ revealing feature when pressing the Ctrl key.
👉 You will find similar examples working preview along this documentation. Don’t miss the 📝 Notes tab to be aware of the nitty-gritty details.
To minimize clutter, the
⬇️ Export,⬆️ Importand❌ Clearbuttons implementation have been omitted from the source code, as they are common to all examples and will be explained in detail in a 🔗 later section.
Current Status
SmarkForm implementation is stable and fully functional, but not all initially planned requirements are yet implemented. Hence, it’s not yet in the 1.0.0 version. [🔗 More…]
Last Updated: Thu Oct 23 2025.
Where to Go Next?
To get started with SmarkForm you can:
| 👉 Take a look to our 🔗 Showcase section to see its full potential at a glance. |
| 👉 Follow our 🔗 Quick Start Guide to rapidly dive in. |
| 👉 Check out our 🔗 Downloadable Examples to see them in action and/or start tinkering. |
Community and Support
If you don’t find a solution there, feel free to open a discussion on our GitHub repository.
For further support, you can contact me through our Contact Page or reach out via email at smarkform@bitifet.net.
If you want to stay updated with the latest news, releases, and announcements, or join the community chat, you can follow us on Telegram:
🚀 Stay tuned
Contributing
We welcome any feedback, suggestions, or improvements as we continue to enhance and expand the functionality of SmarkForm.
👉 See the 🔗 Contributing Section for more details.