<div id="myForm">
<p class="row">
<label data-smark>Nombre:</label>
<input data-smark='{"name":"name", "type":"input"}' type="text" />
<button data-smark='{"action":"clear","context":"name"}'>❌</button>
</p>
<p class="row">
<label data-smark>Teléfono:</label>
<input data-smark name="phone" type="tel" />
<button data-smark='{"action":"clear","context":"phone"}'>❌</button>
</p>
<p class="row">
<label data-smark>eMail:</label>
<input data-smark name="email" type="email" />
<button data-smark='{"action":"clear","context":"email"}'>❌</button>
</p>
<p class="row">
<button data-smark='{"action":"clear"}'>❌ Borrar</button>
<button data-smark='{"action":"export"}'>💾 Guardar</button>
</p>
</div>
.row {
padding: .5em;
}
const myForm = new SmarkForm(
document.getElementById("myForm")
);
<div id="myForm">
<p class="row">
<label data-smark>Nombre:</label><input data-smark='{"name":"name"}' type="text">
<label data-smark>Edad:</label><input data-smark='{"name":"age"}' type="number">
</p>
<fieldset class="row" data-smark='{"name":"conatact_data"}'>
<button data-smark='{"action":"removeItem", "context":"phones", "target":"*", "keep_non_empty":true}' title='Limpiar vacíos'>🧹</button>
<button data-smark='{"action":"removeItem", "context":"phones", "keep_non_empty":true}' title='Eliminar teléfono'>➖</button>
<button data-smark='{"action":"addItem","context":"phones"}' title='Añadir teléfono'>➕ </button>
<label data-smark>Teléfonos:</label>
<ul data-smark='{"name": "phones", "of": "input", "sortable":true, "min_items":0, "max_items":5, "exportEmpties": true}'>
<li data-smark='{"role": "empty_list"}' class="row">(No dispone)</li>
<li class="row">
<label data-smark>📞 </label><input type="tel" data-smark>
<button data-smark='{"action":"removeItem"}' title='Eliminar éste teléfono'>❌</button>
</li>
</ul>
<p class="row"><label data-smark>eMail:</label>
<input type="email" name="email" data-smark /></p>
</fieldset>
<p class="row">
<button data-smark='{"action":"clear"}'>❌ Borrar</button>
<button data-smark='{"action":"import"}'>📂 Abrir</button>
<button data-smark='{"action":"export"}'>💾 Guardar</button>
</p>
</div>
.row {
padding: .5em;
}
fieldset.row {
border: solid 1px;
margin: 3px;
}
button:disabled {
opacity: .5;
}
const myForm = new SmarkForm(
document.getElementById("myForm")
);
/* Do something on data export */
myForm.on("AfterAction_export", ({data})=>{
window.alert(JSON.stringify(data, null, 4));
});
/* Get data from somewhere on import */
myForm.on("BeforeAction_import", async (ev)=>{
let data = window.prompt('Fill JSON data');
if (data === null) return void ev.preventDefault(); /* Cancelled */
try {
ev.data = JSON.parse(data);
} catch(err) {
alert(err.message);
ev.preventDefault();
};
});
/* Ask for confirmation unless form is already empty: */
myForm.on("BeforeAction_clear", async ({context, preventDefault}) => {
if (
! await context.isEmpty() /* Form (or field) is not empty */
&& ! confirm("Descartar datos?") /* User clicked the "Cancel" button. */
) {
/* Prevent default (clear form) behaviour: */
preventDefault();
};
});
<div id="myForm">
<button data-smark='{"action":"addItem","context":"employee","hotkey":"+"}' title='Nuevo empleado'>👥</button>
<label data-smark>Empleados:</label>
<div data-smark='{"type":"list","name":"employee", "min_items":0,"sortable":true}'>
<fieldset class="row">
<p class="row">
<label>Empleado</label>
<span data-smark='{"action":"position"}'></span>/<span data-smark='{"action":"count"}'></span>:
<input data-smark='{"name":"name"}' type="text" placeholder='Nombre...'>
<button data-smark='{"action":"removeItem","hotkey":"-"}' style='float: right;' title='Baja empleado'>🔥</button>
</p>
<label data-smark>📞 Teléfonos:</label>
<ul data-smark='{"name": "phones", "of": "input", "sortable":true, "max_items":3}'>
<li class="row">
<button data-smark='{"action":"removeItem","hotkey":"-"}' title='Eliminar Teléfono'>➖</button>
<input type="tel" data-smark />
<button data-smark='{"action":"addItem","hotkey":"+"}' title='Añadir Teléfono'>➕ </button>
</li>
</ul>
</fieldset>
</div>
<p class="row">
<button data-smark='{"action":"clear","hotkey":"x"}'>❌ Borrar</button>
<button data-smark='{"action":"export","hotkey":"s"}'>💾 Guardar</button>
</p>
</div>
button[data-hotkey] {
position: relative;
overflow-x: display;
}
button[data-hotkey]::before {
content: attr(data-hotkey);
display: inline-block;
position: absolute;
top: 2px;
left: 2px;
z-index: 10;
background-color: #ffd;
padding: 2px 8px;
border-radius: 4px;
font-weight: bold;
font-family: sans-serif;
font-size: .8em;
white-space: nowrap;
transform: scale(1.8) translate(.1em, .1em);
}
.row {
padding: .5em;
}
fieldset.row {
border: solid 1px;
margin: 3px;
}
button:disabled {
opacity: .5;
}
const myForm = new SmarkForm(
document.getElementById("myForm")
);
/* Do something on data export */
myForm.on("AfterAction_export", ({data})=>{
window.alert(JSON.stringify(data, null, 4));
});
/* Get data from somewhere on import */
myForm.on("BeforeAction_import", async (ev)=>{
let data = window.prompt('Fill JSON data');
if (data === null) return void ev.preventDefault(); /* Cancelled */
try {
ev.data = JSON.parse(data);
} catch(err) {
alert(err.message);
ev.preventDefault();
};
});
/* Ask for confirmation unless form is already empty: */
myForm.on("BeforeAction_clear", async ({context, preventDefault}) => {
if (
! await context.isEmpty() /* Form (or field) is not empty */
&& ! confirm("Descartar datos?") /* User clicked the "Cancel" button. */
) {
/* Prevent default (clear form) behaviour: */
preventDefault();
};
});
⚠️ El software utilizado para ésta presentación interfiere en los eventos de teclado y ratón. Para una mejor apreciación, ver los ejemplos del Manual de SmarkForm:
class myType extends Smarkform.types.input { ... }
SmarkForm.createType(name, myType);
SmarkFrom.createMixin(name, htmlsource);
Use a spacebar or arrow keys to navigate.
Press 'P' to launch speaker console.