# Example 1

### Description

This example demonstrates the basics of a Custom Form Tab with **VanJS**:
1. Renders a single required field, a **Sampling period** selector.
2. Validates the selection on every change and shows an inline error message while the value is not valid.
3. 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

```javascript
// 1. Import only the VanJS tags used below
const { div, span, strong, label, select, option, p } = van.tags;

// 2. Form state
const samplingPeriod = van.state(0);
const errorMessage = van.state("The sampling period cannot be 0.");

// 3. Validate the current value and report validity and data to the wizard
function updateValidity() {
    const value = 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
return div({ 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
                        )
          );
```
