This example demonstrates the basics of a Custom Form Tab with VanJS:
Renders a single required field, a Sampling period selector.
Validates the selection on every change and shows an inline error message while the value is not valid.
Reports the step validity and its data to the wizard with setModelData(isValid, data), so the wizard only lets the user continue once the field is filled in.
Code
// 1. Import only the VanJS tags used below
const { div, span, strong, label, select, option, p } =van.tags;
// 2. Form state
constsamplingPeriod=van.state(0);
consterrorMessage=van.state("The sampling period cannot be 0.");
// 3. Validate the current value and report validity and data to the wizard
functionupdateValidity() {
constvalue= Number(samplingPeriod.val);
if (value===0) {
errorMessage.val="The sampling period cannot be 0.";
setModelData(false);
return;
}
errorMessage.val="";
setModelData(true, { samplingPeriod:value });
}
// 4. Invalidate the step until a valid value is selected
updateValidity();
// 5. Render the component
returndiv({ class:"pa-4 subtitle-2" },
div({ style:"margin-bottom: 2em" },
"Select how often the device must report its measurements. ",
div({ style:"margin-top: 0.5em" },
"Fields marked with ", span({ style:"color: red" }, "*"), " are mandatory." )
),
van.tags.form({ },
div({ style:"margin-bottom: 1em;" },
label({ for:"samplingPeriod", style:"display: block; font-weight: bold; margin-bottom: 0.5em;" },
"Sampling period (minutes) ", span({ style:"color: red" }, "*")
),
select({
id:"samplingPeriod",
value:samplingPeriod,
onchange: (e) => {
samplingPeriod.val=e.target.value;
updateValidity();
},
style:"padding: 0.5em; width: 100%; max-width: 200px; display: block;" },
option({ value:0 }, "0 (not set)"),
option({ value:5 }, "5"),
option({ value:15 }, "15"),
option({ value:60 }, "60")
),
p({ style:"font-size: 0.9em; margin-top: 0.5em; color: #555;" },
strong("NOTE"), ": the shorter the period, the faster the device drains its battery." )
),
() => errorMessage.val?p({ style:"color: red; font-weight: bold;" }, errorMessage.val) :null )
);