Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

custom component validation #90

Closed
JKHeadley opened this issue Nov 25, 2017 · 3 comments
Closed

custom component validation #90

JKHeadley opened this issue Nov 25, 2017 · 3 comments

Comments

@JKHeadley
Copy link

Hi, first of all, great project! So I tried to implement a custom component following your solution in #41, however validation does not seem to be working. Here's my code:

parent

<vue-form :state="formstate" @submit.prevent="onSubmit">

            <vue-form-input
              v-model="user.firstName"
              :formstate="formstate"
              :type="'text'"
              :label="'First Name'"
              :name="'firstName'">
            </vue-form-input>

</vue-form>

component

<template>
  <validate :state="formstate" auto-label class="form-group required-field" :class="fieldClassName(formstate.firstName)">
    <label>{{ label }}</label>
    <input :type="type" :name="name" class="form-control" v-bind:value="value" v-on:input="$emit('input', $event.target.value)">
    <field-messages :state="formstate" :name="name" show="$touched || $submitted">
      <div>
        <span class="glyphicon glyphicon-ok form-control-feedback"></span>
      </div>
      <div slot="required">
        <span class="glyphicon glyphicon-remove form-control-feedback"></span>
        <span class="has-error">First Name is a required field</span>
      </div>
    </field-messages>
  </validate>
</template>

<script>
  export default {
    props: ['value', 'formstate', 'type', 'name', 'label'],
    methods: {
      fieldClassName: function (field) {
        if (!field) {
          return ''
        }
        if ((field.$touched || field.$submitted) && field.$valid) {
          return ['has-success', 'has-feedback']
        }
        if ((field.$touched || field.$submitted) && field.$invalid) {
          return ['has-error', 'has-feedback']
        }
      },
    }
  }
</script>

Any idea what could be going on?

@fergaldoyle
Copy link
Owner

Ideally your validate component would be on the same level as the parent, e.g.

<vue-form :state="formstate" @submit.prevent="onSubmit">
  <validate>
    <vue-form-input
      required
      v-model="user.firstName"
      :type="'text'"
      :label="'First Name'"
      :name="'firstName'">
    </vue-form-input>
  </validate>    
</vue-form>

@JKHeadley
Copy link
Author

Thanks for the help! I was able to get this to work close to what I was looking for. Here's my updated code:

parent

<vue-form :state="formstate" @submit.prevent="onSubmit">
  <validate auto-label class="form-group" :class="fieldClassName(formstate.email)" :custom="{ email: emailValidator }">
    <vue-form-input
      required
      v-model="user.email"
      :formstate="formstate"
      :type="'email'"
      :label="'Email:'"
      :name="'email'"
      :messages="{ email: 'Please input a valid email', required: 'This field is required' }">
    </vue-form-input>
  </validate>
</vue-form>

VueFormInput.vue

<template>
  <div>
    <label>{{ label }}</label>
    <input :value="value" @input="$emit('input', $event.target.value)" :type="type" :name="name" class="form-control" />

    <field-messages :state="formstate" :name="name" show="$touched || $submitted">
      <template>
        <span class="glyphicon glyphicon-ok form-control-feedback"></span>
      </template>
      <template v-for="(message, key) in messages" :slot="key">
        <span class="glyphicon glyphicon-remove form-control-feedback"></span>
        <span class="has-error">{{ message }}</span>
      </template>
    </field-messages>
  </div>
</template>

<script>
  export default {
    props: ['value', 'formstate', 'type', 'name', 'label', 'messages']
  }
</script>

The biggest downside is that I was hoping to keep all the validator functions and class functions in the VueInputForm.vue file. Also, the default required validator works this way, but type validators don't seem to, hence the custom email validator.

@DrCord
Copy link

DrCord commented Oct 9, 2019

Is there a way to get around the need to be on the same level?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants