question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

[HOW-TO] Programmatically set custom error message to a field

See original GitHub issue

Hi! I’ve just discovered this awesome framework and I’m trying to integrate it in a test environment in localhost. Everything looks fine to me but I don’t undestand how to handle server-side errors. Let’s suppose user submit the form but the server found a duplicate email address. My server will respond with a response body like this:

{
  status: false,
  message: 'Invalid data, please check and try again',
  errors: [
    {
      key: 'email',
      message: 'This email is already associated to another user',
    }
  ]
}

So my question is: How can I programmatically set custom error messages to each field of the form starting from fields’ key?

EXAMPLE FIDDLE

Here’s my code: HTML:

  <!-- OTHER HTML... --->
  <div id="form-container"></div>
  <!-- OTHER HTML, JS FILES AND JS DEPENDENCIES... --->
  <script src="formio-test.js"></script>

Javascript:

window.onload = function() {
  initForm('form-container');
}

  /**
   * Init form in provided container
   *
   * @param {string} containerId The ID of the form-container used in the HTML
   *
   * @returns {undefined}
   */
  async initForm(containerId) {
    const formData = {
      display: "form",
      components: [
        {
          label: "Columns",
          columns: [
            {
              components: [
                {
                  label: "Nome",
                  placeholder: "Inserisci il nome",
                  showCharCount: true,
                  spellcheck: true,
                  tableView: true,
                  validate: {
                    required: true,
                    minLength: 2,
                    maxLength: 30,
                    unique: false,
                    multiple: false
                  },
                  key: "firstName",
                  type: "textfield",
                  input: true,
                  hideOnChildrenHidden: false
                },
                {
                  label: "Email",
                  placeholder: "Inserisci l'email",
                  spellcheck: true,
                  tableView: true,
                  validate: {
                    required: true,
                    minLength: 5,
                    maxLength: 320,
                    unique: false,
                    multiple: false
                  },
                  key: "email",
                  type: "email",
                  input: true,
                  hideOnChildrenHidden: false
                }
              ],
              width: 6,
              offset: 0,
              push: 0,
              pull: 0
            },
            {
              components: [
                {
                  label: "Cognome",
                  placeholder: "Inserisci il cognome",
                  showCharCount: true,
                  spellcheck: true,
                  tableView: true,
                  validate: {
                    required: true,
                    minLength: 2,
                    maxLength: 30,
                    unique: false,
                    multiple: false
                  },
                  key: "lastName",
                  attributes: {
                    boooohAtr: "bohhhval"
                  },
                  type: "textfield",
                  input: true,
                  hideOnChildrenHidden: false
                },
                {
                  label: "Role",
                  widget: "choicesjs",
                  placeholder: "Seleziona un ruolo",
                  tableView: true,
                  data: {
                    values: [
                      {
                        value: "admin",
                        label: "Admin"
                      },
                      {
                        label: "Utente",
                        value: "user"
                      }
                    ]
                  },
                  selectThreshold: 0.3,
                  validate: {
                    required: true,
                    unique: false,
                    multiple: false
                  },
                  key: "role",
                  type: "select",
                  indexeddb: {
                    filter: {}
                  },
                  input: true,
                  defaultValue: "user",
                  hideOnChildrenHidden: false
                }
              ],
              width: 6,
              offset: 0,
              push: 0,
              pull: 0
            }
          ],
          tableView: false,
          key: "columns",
          type: "columns",
          input: false
        },
        {
          label: "Invia",
          showValidations: false,
          rightIcon: "fa fa-chevron-right",
          tableView: false,
          key: "submit",
          type: "button",
          input: true,
          validate: {
            unique: false,
            multiple: false
          }
        }
      ]
    };

    const formSettings = {
      readOnly: false,
      noAlerts: false,
      language: "it",
      i18n: {
        it: formioTranslationIt
      }
    };

    // Init form
    this.form = await Formio.createForm(
      document.getElementById(containerId),
      formData,
      formSettings
    );

    // Prevent the submission from going to the form.io server.
    this.form.nosubmit = true;

    // Set default data
    this.form.submission = {
      data: {
        firstName: "Joe",
        lastName: "Smith",
        email: "info@loremipsum.com"
      }
    };

    // Handle submit
    this.form.on("submit", submission => {
      this.onFormSubmit(submission);
    });
  }


  /**
   * Handle form submit
   *
   * @param {any} submission Submission data emitted from the form
   *
   * @returns {undefined}
   */
  async onFormSubmit(submission) {
    try {
      // Reset previous custom errors
      this.form.customErrors = [];

      // Call back-end API
      const response = await fetch("http://localhost:8080/api/v1/users", {
        method: "POST",
        body: JSON.stringify(submission.data),
        mode: "cors",
        headers: {
          "Content-Type": "application/json"
        }
      });

      // Stop button loading and parse result
      this.form.emit("submitDone", submission);

      // Handle failiture
      if (!res.status) {
        // I NEED TO ADD ERROR MESSAGES:
        // 1) A general error message to the form
        // 2) A specific error message to each field that has encountered an error in the back-end validation

        return;
      }

      // Handle success
      this.form.setAlert("success", res.message);
      this.form.showAlert();
    } catch (error) {
      console.error("ERROR: ", error);
      // todo 
    }
  }

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:7 (3 by maintainers)

github_iconTop GitHub Comments

2reactions
matt-whiteleycommented, Mar 29, 2022

I am adding this here as this issue appears on Google when searching for how to do this.

It appears to be an undocumented ‘feature’, but if you return a response in the following format then the formio.js framework displays the errors natively without writing a custom callback:

{
  "name": "ValidationError",
  "details": [
     {
       "message": "My custom message about this field",
       "type": "custom",
       "path": ["input1"],
       "level": "error"
     },
     {
       "message": "My custom message about another field",
       "type": "custom",
       "path": ["input2"],
       "level": "error"
     }
  ]
}

details is an array with an object per input that is invalid. path must be an array for some reason, but it takes the key of the input, and this is what puts the error in the right place in the form. Using this you can display a custom message for as many inputs as needed.

Screenshot 2022-03-29 at 13 38 55
1reaction
travistcommented, Dec 11, 2020

this hook has been around for a while and should also be available for any version released within the past year in 4.x branch. And yes it also applies to wizards.

Read more comments on GitHub >

github_iconTop Results From Across the Web

How to set a custom error message to a form in angular
Reactive Form in Angular allows you to have custom errors and custom validations. Below is an example: HTML : Validate if the input...
Read more >
Can I programmatically change an error message?
Run the VI. An error dialog appears and displays the customized error code and description. Click the Continue button in this error dialog....
Read more >
How to add custom validations to fields programmatically?
If you want custom validation for a different field then, 1. Replace the word “text” in the above code with the field name...
Read more >
8 - What is correct way to override the field required error ...
But is there any way to just override error message without removing required true & writing obvious logic once again like if (...
Read more >
useForm - setError - React Hook Form
Should focus the input during setting an error. This only works when the input's reference is registered, it will not work for custom...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found