1

I have a problem with my generic input fields. In other words I've made a generic input field which should cover regular input fields, checkboxes and radiobuttons. But when I try to pass a string value as a value of the radio input field, the prop is empty.

<TextInput
        v-model="name"
        description="Name & LastName"
        name="Name & Surname"
        rules="required"
      />
      <TextInput
        v-model="age"
        type="number"
        description="Age"
        name="Age"
        rules="required|digits:2"
      />
      <div id="gender-fields">
        <legend>Please specify your gender:</legend>
        <TextInput
          v-model="gender"
          type="radio"
          description="Male"
          name="Gender"
          rules="required"
        />
        <TextInput
          v-model="gender"
          type="radio"
          description="Female"
          name="Gender"
          rules="required"
        />
        <TextInput
          v-model="gender"
          type="radio"
          description="Unspecified"
          name="Gender"
          rules="required"
        />
      </div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

This is how I'm declaring my input fields in my form. Here's the definiton of the Input Field.

<template>
  <ValidationProvider
    tag="div"
    :rules="rules"
    :name="name"
    :vid="vid"
    v-slot="{ errors }"
    :mode="mode"
  >
    <label>
      {{ description }}
      <input :type="type" v-model="currentValue" :value="value" />
    </label>
    <span>{{ errors[0] }}</span>
  </ValidationProvider>
</template>

<script>
import { ValidationProvider } from "vee-validate";
export default {
  name: "TextInput",
  components: {
    ValidationProvider
  },
  props: {
    description: {
      type: String,
      default: ""
    },
    value: {
      required: true
    },
    rules: {
      type: [String, Object],
      default: ""
    },
    name: {
      type: String,
      default: ""
    },
    vid: {
      type: String,
      default: undefined
    },
    type: {
      type: String,
      default: "text"
    },
    mode: {
      type: String,
      default: "aggressive"
    }
  },
  data: () => ({
    currentValue: ""
  }),
  watch: {
    currentValue(val) {
      // allows us to use v-model on our input.
      this.$emit("input", val);
    }
  }
};
</script>

<style></style>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
THe only input fields I have a problem with are those radio buttons. Is there something I'm missing?

2
  • I forgot to add the value="male" into a <TextInput> component when posting the example. It doesn't work even when passed in. Commented Apr 1, 2020 at 20:13
  • 1
    You're binding both v-model and value on the native input. This is a problem because v-model is just a special way of binding value. On a normal textbox, you get this error: :value="value" conflicts with v-model on the same element because the latter already expands to a value binding internally. Commented Apr 2, 2020 at 1:58

1 Answer 1

1

The easiest way to fix this is to skip putting :value="value" on the input and change your watch like this:

  watch: {
    //watch for value to change and assign it to our currentValue
    value: {
      handler(val) {
        this.currentValue = val;
      },
      //this makes it run the handler function on mount in addition to whenever the value changes
      immediate:true
    },
    currentValue(val) {
      // allows us to use v-model on our input.
      this.$emit("input", val);
    }
  }
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks Ryley, I was having the same issue and it fixed it. I'm interested to know why this isn't done in the same that it looks like Milan and I both used, do you know if this could be due to some recent change? I can't for the life of me find the original source that I used, although I know I changed my implementation up a bit from what I was using, so wasn't sure if I'd broken it in the process.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.