Skip to content

Vuelidate unable to procedurally generate form validation

So I’m currently working on extracting a highly re-usable form into a subcomponent in VueJS (Vue2). This form is long in my actual application, and so instead of hardcoding it, I decided to procedurally generate it from a JSON file. Now, I was having a devil of a time getting it to work, and couldn’t find where the error was occurring. So I made the following simpler version to help find the issue.

https://jsfiddle.net/c2ba7p3r/ ( See in particular lines 78-94 and 101-110 )

Further explanation:

In this app, there is an Array that holds all the form data (very similar to imported JSON). The is made up of objects, each of which represent a section of the form. Within each of said objects, there is a title attribute, and a subsequent array of objects, that will be used to generate the input fields. Something like this:

let example_array = [
   {
      title: "Section 1",
      inputs: [
         {
            // Input 1A
            id: "name",
            label: "Full Name",
            required: true,
            validate: { constraint: "minimum_text",   param: 2  }
         },
         {...}  // Input 1B
                // etc.
      ]
   },
   {
      title: "Section 2",
      inputs: [
         {...}, // Input 2A
         {...}  // Input 2B
                // etc.
      ]
   },
   // etc.
]

Now, this form template array is passed down to the custom form component as a prop. In the custom form component, I extract all the inputs, from the above JSON and flatten them into a single array. From there, I will take each of these inputs from the array and add a property to the data object (in the data function) for each of them.

After I’ve done this, I create the validations in a similar fashion. In the validations function, I go through the array of flattened inputs, extract the required property and validate sub-object, and create the validations from that.

Finally, I have my template, which has a nest v-for loop. The first v-for iterates over the original form template array (passed in as a prop), and creates each section, including the section title. From there, I have a second v-for loop that generates each form section’s inputs.

And thus far, there have been no errors. But of course, therein lies the rub… In the last bit of template generation, where I assign my conditional error class, I cannot access the validation object using an expression, which is necessary due to the v-for to assign the proper validation to each input. Particularly, $v.inputs[input.id] is undefined, making the access of $v.inputs['input.id'].$invalid (or $error or whatnot) fail. It does not fail for a specific property access, like $v.inputs['name'] or $v.inputs['url'] or whatnot, however that defeats the purpose of using the v-for.


Can anyone spot what I’m doing wrong? It feels like I’ve found a bug in the library, but what I suspect what really is happening is that I’m just misusing the library or JavaScript.

Thanks

Answer

It Seams you expected to highlight an invalid field by form-error class

    :class="{ 'form-error': $v.inputs[input.id].$invalid }"

but you have the description field without validation and your code fail on $v.inputs['description'].$invalid the solution is to build empty validation hash for all fields

            { 
              type: "text",
              id: "description",
              label: "Site Description",
              validate: {},                //!!!!
            },
validations: function () {
    const validator = {
      inputs: {}
    }

        // Parse the validation rules passed in from the object (would likely be JSON)
    this.all_form_inputs.forEach((input) => {
      // * No validation is needed
      if(!input.required) {
        validator.inputs[input.id] = {} //!!!

        return
      }

https://jsfiddle.net/qzfm34sa/

this is just fast debug solution, hope you will build a more robust one.