Override @formio/js Templates
by brendanbond
HTML
<link
href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css"
rel="stylesheet"
integrity="sha384-sRIl4kxILFvY47J16cr9ZwB07vP4J8+LH7qKQnuqkuIAvNWLzeN8tE5YBujZqJLB"
crossorigin="anonymous"
/>
<link rel="stylesheet" href="https://cdn.form.io/js/formio.full.min.css" />
<div class="container">
<div id="formio"></div>
</div>
<script src="https://cdn.form.io/js/formio.full.js"></script>
CSS
.radio-block label {
background: #228b22;
border: 3px solid transparent;
cursor: pointer;
}
.radio-block.radio-selected label {
border-color: black;
}
@keyframes slideInFromRight {
from {
transform: translateX(100%);
opacity: 0;
}
to {
transform: translateX(0);
opacity: 1;
}
}
@keyframes slideInFromLeft {
from {
transform: translateX(-100%);
opacity: 0;
}
to {
transform: translateX(0);
opacity: 1;
}
}
.wizard-page.slide-left {
animation: slideInFromRight 0.4s ease-out;
}
.wizard-page.slide-right {
animation: slideInFromLeft 0.4s ease-out;
}
JavaScript
// Here we override our radio button and wizard templates. Again, for a full design system it's better to keep these version controlled, but hopefully this demonstrates the concepts. See https://help.form.io/developers/form-development/form-templates#what-is-a-template
// I also used our open source bootstrap templates for guidance, found here: https://github.com/formio/bootstrap/tree/main/src/templates/bootstrap5
Formio.Templates.current = {
wizard: {
form: (() => {
let lastPage = -1;
let direction = "";
return (ctx) => {
if (lastPage !== -1 && ctx.currentPage !== lastPage) {
direction = ctx.currentPage > lastPage ? "slide-left" : "slide-right";
setTimeout(() => { direction = ''; }, 400);
}
lastPage = ctx.currentPage;
return `
<div class="${ctx.className}">
<div style="position: relative; overflow: hidden;">
${ctx.wizardHeader || ""}
<div class="wizard-page ${direction}" ref="${ctx.wizardKey}">
${ctx.components}
</div>
${ctx.wizardNav || ""}
</div>
</div>`;
};
})(),
},
radio: {
form: (ctx) => `
<div class="d-flex flex-column gap-2" ref="radioGroup" role="radiogroup">
${ctx.values
.map((item, index) => {
const id = `${ctx.instance.root?.id}-${ctx.id}-${ctx.row}-${typeof item.value === "object" ? item.value + "-" + index : item.value}`;
return `
<div class="radio-block" ref="wrapper">
<input ref="input" type="radio" class="position-absolute opacity-0"
name="${ctx.input.attr.name}" value="${item.value}"
${item.disabled ? "disabled" : ""}
id="${id}" role="radio">
<label class="d-block w-100 p-3 text-white text-center rounded fw-medium"
for="${id}">
...