1
votes

I wanted to give some form visual validation cues, so I tried using class binding to do just that. If I use the ternary inline, it doesn't really meet my requirements of what should happen, but when I tried using computed prop, it made all the other components disappear.

If i tried doing it like this: v-bind:class="[(!validation.hasError('form.fullName'))?'has-success':'has-danger noValid']"

It just triggers the animation and the classes once and they stays there. I want to trigger the noValid animation everytime the user clicks my submit button if there's errors in validation.

I'm using simple-vue-validator btw.

Here's the godforsaken component, I use vue now-ui-kit template from Creative Tim as a base and customize my way from there. This is their Form Group Input component, docs here

<fg-input
  class="input-lg"
  :label="validation.firstError('form.fullName')"
  placeholder="Full Name..."
  v-model="form.fullName"
  addon-left-icon="now-ui-icons users_circle-08"
  v-bind:class="{ visualValidation }"
></fg-input>

Button Component: bootstrap-vue, cause their customized button doesn't really serve my purpose

<b-button type="submit" block pill variant="info" @click="submit">Submit Form</b-button>

My computation: noValid is the shaking animation class, has-success and has-danger just changes their appearances.

computed: {
    visualValidation: function() {
      const successClass = "has-success";
      const errorBoi = "has-danger";
      const shakeBoi = "noValid";
      if (validation.firstError("form.fullName")) {
        return errorBoi + " " + shakeBoi;
      } else if (!validation.hasError("form.fullName")) {
        return successClass;
      }
    }
  }

I thought the variables that i returned would be binded as classes to the form.fullName Model but it's not doing anything, better yet, it made all my other components not rendering.

What should i do here? i'm just starting to learn Vue.js so i don't really understand what's going on here.

Edit from here:

I rewrote the logic to my class binding, and just use method to remove the class on click the components.

here is the updated component:

<fg-input
              class="input-lg"
              :label="validation.firstError('form.email')"
              placeholder="Email Here..."
              v-model="form.email"
              addon-left-icon="now-ui-icons ui-1_email-85"
              v-bind:class=" {'has-success' : isSuccEmail, 'has-danger' : isFailEmail, 'noValid': validNoEmail} "
              @click="removeShake()"
            ></fg-input>

data:

isSuccEmail: false,
isFailEmail: false,
validNoEmail: false

method:

removeShake: function() {
      let vm = this;
      vm.validNoName = false;
      vm.validNoEmail = false;
      console.log(vm.validNoEmail);
      console.log(vm.validNoName);
    },

However, there's currently a bug, where the validator don't validate separately. It gave the class has-success to email even though it was full-name that was successful.

    valEmail: function() {
      let vm = this;

      vm.$validate("form.email").then(function(success) {
        if (success) {
          vm.isFailEmail = false;
          vm.isSuccEmail = true;
        } else if (!success) {
          vm.isSuccEmail = false;
          vm.isFailEmail = true;
          vm.validNoEmail = true;
        } else {
          alert("Fatal Error");
        }
      });
    },
    valName: function() {
      let vm = this;

      vm.$validate("form.fullName").then(function(success) {
        if (success) {
          vm.isFailName = false;
          vm.isSuccName = true;
        } else if (!success) {
          vm.isSuccName = false;
          vm.isFailName = true;
          vm.validNoName = true;
          console.log(vm);
        } else {
          alert("Fatal Error");
        }
      });
    }

The $validate is a function of simple-vue-validator, the docs.

Submit function is just calling those two functions above.

I think this because of the promise call, is there a way to call the $validate() without promise?

1

1 Answers

0
votes

There are a few problems here.

Firstly, while templates don't require you to use this. you still need to use it within your JS code. You should be seeing an error in the console, or maybe even at compile time depending on how you have linting configured.

if (validation.firstError("form.fullName")) {

What is validation? I assume that should be this.validation. Likewise a couple of lines further down.

Your next problem is here:

v-bind:class="{ visualValidation }"

The braces here are creating an object literal, so it's equivalent to this:

v-bind:class="{ visualValidation: visualValidation }"

This will be conditionally adding the string 'visualValidation' as a class , which isn't what you want. Get rid of the braces:

v-bind:class="visualValidation"