UNPKG

smarkform

Version:

[![SmarkForm Logo](docs/assets/SmarkForm_logo.png)](https://www.npmjs.com/package/smarkform)

192 lines (178 loc) โ€ข 8.81 kB
<!DOCTYPE html> <html style='--background-image-url: url("https://picsum.photos/id/972/800.jpg");'> <head> <title>TODO-List Example</title> <meta name='viewport' content='width=device-width, initial-scale=1.0'> <meta http-equiv='Content-Type' content='text/html; charset=utf-8'> <link rel='stylesheet' href='/resources/dist/examples/smarkform_layout_sample.css?foo=0.7776419866765434'> <link rel='stylesheet' href='/resources/dist/examples/smarkform_styles_sample.css?foo=0.727267112615217'> <script> const bgImg = `https://picsum.photos/id/${1+Math.floor(Math.random()*1084)}/800.jpg`; document.documentElement.style.setProperty('--background-image-url', `url("${bgImg}")`); document.addEventListener("DOMContentLoaded", function() { const backgroundAnchor = document.getElementById("background-anchor"); if (backgroundAnchor) backgroundAnchor.href = bgImg; }); </script> <script defer src='/resources/dist/SmarkForm.umd.js?foo=0.563786617206983'></script> <script> document.addEventListener('DOMContentLoaded', function() { // <!-- BEGIN controller sample--> // Essential: // ========== // SmarkForm instantiation: const myForm = new SmarkForm(document.querySelector("#main-form")); // Import / Export data handling: // ============================== // Do Something on export action: myForm.on("AfterAction_export" , ({data})=>alert (JSON.stringify(data, null, 4)) ); // Fetching data on import action (example): myForm.on("BeforeAction_import", (options) => { let data = prompt('Provide JSON data'); try { options.data = JSON.parse(data); } catch (err) { if (data.length) { alert ('โš ๏ธ Invalid JSON!!'); data = null; // Emulate prompt cancel. } else { data = {}; // Drop form contents }; }; if (data === null) options.preventDefault(); }); // Aesthetic enhancements: // ======================= // Ask for confirm on clear action myForm.on("BeforeAction_clear", async ({context, preventDefault}) => { // Ask for confirmation: if ( context.getPath() == "/" // Only for the whole form && ! await context.isEmpty() // Don't even ask if already empty && ! confirm("Are you sure?") ) preventDefault(); // Abort if user cancelled }); // Allow for list items addition/removal CSS animation: // (Propperly and/remove "animated_item" and "ongoing" CSS classes) const delay = ms=>new Promise(resolve=>setTimeout(resolve, ms)); myForm.on("afterRender", async function(ev) { if (ev.context.parent?.options.type !== "list") return; /* Only for list items */ const item = ev.context.targetNode; item.classList.add("animated_item"); await delay(1); /* Important: Allow DOM to update */ item.classList.add("ongoing"); }); myForm.on("beforeUnrender", async function(ev) { if (ev.context.parent?.options.type !== "list") return; /* Only for list items */ const item = ev.context.targetNode; item.classList.remove("ongoing"); /* Await for transition to be finished before item removal: */ await delay(150); }); // <!-- END controller sample--> }); </script> </head> <body> <div class='main-container'> <div class='smarkForm' id='main-form'> <header> <h1>TODO-List Example</h1> <style> .credits { background: rgba(255, 255, 255, .7); padding: 1em 1.5em; margin: .3em; font-size: small; } .credits, .credits a { color: darkblue; } .credits .subtitle, .credits .subtitle a { color: darkgrey; font-weight: bold; } .credits .description { color: black; } .credits ul { margin-left: .2em; list-style-type: none; } .credits li::before { content: "๐Ÿ‘‰"; margin-right: 5px; } </style> <div class='credits'> <p class='subtitle'>This is an <a href='https://smarkform.bitifet.net'>SmarkForm</a> demonstration page.</p> <p class='description'> This example shows how to create a complete TO-DO list interface with just a few HTML lines. </p> <ul> <li> Complete documentation at <a href='https://smarkform.bitifet.net'>https://smarkform.bitifet.net</a>. </li> <li> Latest version and more examples at <a href='https://smarkform.bitifet.net/resources/examples'>https://smarkform.bitifet.net/resources/examples</a> </li> <li> GitHub: <a href='https://github.com/bitifet/SmarkForm'>https://github.com/bitifet/SmarkForm</a>. </li> <li> NPM: <a href='https://www.npmjs.com/package/smarkform'>https://www.npmjs.com/package/smarkform</a>. </li> <li> <a id='background-anchor' href='#'>Background image</a> courtesy of <a href='https://picsum.photos/'>Lorem Picsum</a> </li> </ul> </div> </header> <!-- BEGIN SmarkForm sample--> <section> <div class='form-group h1 nowrap'> <div class='spacer'></div> <button data-smark='{"action":"import","context":"tasklist"}'><span role='img' aria-label=''>๐Ÿ“‚</span> Import (JSON)</button> <button data-smark='{"action":"export","context":"tasklist"}'><span role='img' aria-label=''>๐Ÿ’พ</span> Export (JSON)</button> </div> <div data-smark='{"type":"list","name":"tasklist","sortable":true,"exportEmpties":true,"min_items":0}'> <fieldset class='form-group aside reverse' data-smark='{"exportEmpties":false}'> <button class='inline' data-smark='{"action":"removeItem"}' title='Remove task'><span role='img' aria-label='Remove task'>โŒ</span></button> <div class='form-group spacer'> <div class='form-group'><span data-smark='{"action":"position"}'>/</span><span>&nbsp;</span> <input data-smark name='title' type='text' placeholder='Task title'> </div> <div class='form-group'> <div class='input-group'><strong data-smark='label'>Goals</strong> <div data-smark='{"name":"goals","type":"list","of":"input","sortable":true,"max_items":100}'> <div class='singleton'> <button data-smark='{"action":"removeItem","failback":"clear","hotkey":"-"}' title='Remove this item'><span role='img' aria-label='Remove this item'>โž–</span></button> <input data-smark='data-smark' type='text' placeholder='New goal...'/> <button data-smark='{"action":"addItem","hotkey":"+"}' title='Add new item below'><span role='img' aria-label='Add new item'>โž•</span></button> </div> </div> </div> </div> </div> </fieldset> </div> <div class='form-group f1 nowrap' style='text-align: right'> <div class='spacer'></div> <button data-smark='{"action":"clear","context":"tasklist","autoscroll":"elegant"}' title='Clear form data'><span role='img' aria-label=''>โŒ</span> Clear all</button> <button data-smark='{"action":"removeItem","context":"tasklist","target":"*","autoscroll":"elegant","preserve_non_empty":true}' title='Clear all empty tasks'><span role='img' aria-label=''>๐Ÿงน</span> Clear empty</button> <button data-smark='{"action":"addItem","context":"tasklist"}'><span role='img' aria-label=''>โž•</span> Add new task</button> </div> </section> <!-- END SmarkForm sample--> </div> </div> </body> </html>