How to validate Form Elements
This article shares how to use JavaScript in the Business Forms plugin to enhance user experience by validating Form Elements.
The Business Forms plugin, formerly known as the Data Manipulation plugin, is designed around one innovative idea: the ability to send data back into the data source from any Grafana dashboard.
When a user enters data on the form, you might wonder what data validation mechanisms are available to ensure only allowable values are sent back to the data source.
Instead of providing an abstract answer, I put together a particular example where I assume:
- the required Form Elements,
- their expected behavior.
Based on the above-assumed requirements, I explain:
- how to configure the Business Forms plugin to make it all possible.
Form Elements
The Form Elements are components the Business Forms plugin provides as building bricks for your data entry forms.
In this article, a data entry form consists of the following elements:
- Three drop-downs with the Select with custom Options type. Names: Facility, Room, and Bench. Each element provides a selection list. The exact selective options are irrelevant to the topic I cover here. For simplicity, every element has two options, 1 and 2.
- The Submit button. Any Business Form has this button by default. I keep all initial settings.
![Configuration for three Form Elements.](/img/blog/2024-05-30-form-elements-validation/example-panel.png)
Expected behavior
Below, I describe the potential Form Elements requirements.
- The initial state of some elements (Room, Bench, Submit button) is
disabled
. Only Facility should be enabled for users' actions. - The Submit button must stay
disabled
until all drop-down elements have values selected. - The Room element must stay
disabled
until the Facility element value is selected. - The Bench element must stay
disabled
until the value in the Room element is selected. - Update the previously selected values (set Form Elements values to Unselected state):
- When the Facility value is changed, the Room element updates its value to unselected.
- When the Room or Facility values are changed, the Bench element updates its value to unselected.
![The Room element is enabled only when the Facility element has a value selected.](/img/blog/2024-05-30-form-elements-validation/room-value.gif)
![The Bench element is enabled only when the Room element has a value selected.](/img/blog/2024-05-30-form-elements-validation/bench-value.gif)
Configuration
For elements validation, I will use JaveScript in the corresponding panel options.
Submit button
The Submit button validation occurs in the "Form Events" category. The Business Forms executes the code located in this category with every Form Element value change.
![Place the code for the Submit button validation into the Form Events.](/img/blog/2024-05-30-form-elements-validation/form-events.png)
To enable or disable the Submit button I use the context.panel.enableSubmit()
or context.panel.disableSubmit()
method respectively. These methods are provided by the Business Forms and could be used in any of the JavaScript code parameters (Custom code, Form Events, etc.)
Access the full list of available parameters in the Business Forms->Custom Code section in the documentation.
You can copy the code from here:
let elements = context.panel.elements;
/**
* Caclulate form validation state
*/
const isFormValid = elements.every((element) => !!element.value);
/**
* Enable/Disable submit button
*/
if (isFormValid) {
context.panel.enableSubmit();
} else {
context.panel.disableSubmit();
}
Room drop-down
The Room element disabled/enabled switch occurs in the "Disable if returned value is true" parameter. The code must return true or false.
![Place the code for the Room drop-down validation into the Disable if returned value is true.](/img/blog/2024-05-30-form-elements-validation/room-element-validation.png)
You can copy the code from here:
const facility = context.panel.elements.find(
(element) => element.id === "facility"
);
return !facility?.value;
Bench drop-down
The Bench element disabled/enabled switch occurs in the "Disable if returned value is true" parameter. The code must return true or false.
![Place the code for the Bench drop-down validation into the Disable if returned value is true.](/img/blog/2024-05-30-form-elements-validation/bench-element-validation.png)
You can copy the code from here:
const facility = context.panel.elements.find(
(element) => element.id === "facility"
);
const room = context.panel.elements.find((element) => element.id === "room");
return !facility?.value || !room?.value;
Update values
For the Room and Bench elements the value update occurs in the "Form Events" category. I will use the context.panel.onChangeElements(updatedElements)
method.
You can copy the code from here:
/**
* Update room and bench values on facility change
*/
if (context.element.id === "facility") {
elements = elements.map((element) => {
if (element.id === "room" || element.id === "bench") {
return {
...element,
value: null,
};
}
return element;
});
}
/**
* Update bench value on room change
*/
if (context.element.id === "room") {
elements = elements.map((element) => {
if (element.id === "bench") {
return {
...element,
value: null,
};
}
return element;
});
}
/**
* Update form elements
*/
context.panel.onChangeElements(elements);
Full code for the Form Events category
Below you can find the full code that I placed in the Form Events category.
You can copy the code from here:
let elements = context.panel.elements;
/**
* Update room and bench values on facility change
*/
if (context.element.id === "facility") {
elements = elements.map((element) => {
if (element.id === "room" || element.id === "bench") {
return {
...element,
value: null,
};
}
return element;
});
}
/**
* Update bench value on room change
*/
if (context.element.id === "room") {
elements = elements.map((element) => {
if (element.id === "bench") {
return {
...element,
value: null,
};
}
return element;
});
}
/**
* Update form elements
*/
context.panel.onChangeElements(elements);
/**
* Calculate form validation state
*/
const isFormValid = elements.every((element) => !!element.value);
/**
* Enable/Disable submit button
*/
if (isFormValid) {
context.panel.enableSubmit();
} else {
context.panel.disableSubmit();
}
I hope the solution is illustrative enough to keep you moving forward with your validation tasks. There could be many possible scenarios, and this article should be a good start for any complicated requirements.
Always happy to hear from you
- Ask a question, request a new feature, or report an issue at GitHub issues.
- Subscribe to our YouTube Channel and leave your comments.