Skip to main content

How to validate Form Elements

Vitali Pinchuk
Community Engineer
Alex Simonok
Director of Engineering

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.
Configuration for three Form Elements.

Expected behavior

Below, I describe the potential Form Elements requirements.

  1. The initial state of some elements (Room, Bench, Submit button) is disabled. Only Facility should be enabled for users' actions.
  2. The Submit button must stay disabled until all drop-down elements have values selected.
  3. The Room element must stay disabled until the Facility element value is selected.
  4. The Bench element must stay disabled until the value in the Room element is selected.
  5. 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.
The Room element is enabled only when the Facility element has a value selected.
The Bench element is enabled only when the Room element has a value selected.
The Bench element is enabled only when the Room element has a value selected.

Configuration

For elements validation, I will use JaveScript in the corresponding panel options.

Submit button

The Submit button validation occurs in the "Form Events" section. The Business Forms executes the code located in this section with every Form Element value change.

Place the code for the Submit button validation into the Form Events.
Place the code for the Submit button validation into the Form Events.

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.)

Parameters

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 in this section must return true or false.

Place the code for the Room drop-down validation into the Disable if returned value is true.
Place the code for the Room drop-down validation into the Disable if returned value is true.

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 in this section must return true or false.

Place the code for the Bench drop-down validation into the Disable if returned value is true.
Place the code for the Bench drop-down validation into the Disable if returned value is true.

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" section. 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 section

Below you can find the full code that I placed in the Form Events section.

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.

Feedback

We're looking forward to hearing from you. You can use different ways to get in touch with us.

  • Ask a question, request a new feature, or report an issue at GitHub issues.
  • Subscribe to our YouTube Channel and leave your comments.
  • Sponsor our open source plugins for Grafana through GitHub.