1

I'm trying to append new input fields based on a condition, I will describe the workflow to help you understand

First stage is to press this button to implement 2 functions(1 is to move to other fieldset in the staged form, second function is to append the inputs:

<input type="button" name="secondBtn" class="next action-button" value="Next" id="secondBtn" @click="nextPlusappend"/>

nextPlusappend:

nextPlusappend() {
    this.isNextClicked();
    this.appendFields();
}

appendFields:

    //this.platform initllized as 'one' so the condition is true.


 if(this.platform === 'one'){
        this.inputFields.push({
            Username: '',
            Password: '',
            AffiliateID: '',
            CI: '',
            GI: '',
        })
    }

And I want to append all the fields from the function to this fieldset:

<div v-if="currentPage === 2">
  <fieldset id="fieldset3"  v-for="(param, index) in inputFields" :key="index">
    <h2 class="fs-title">API Credentials</h2>
    <h3 class="fs-subtitle">Step 3- Add any parameter for the integration</h3>

    <input v-model="param.Username" type="text" name="`inputFields[${index}[Username]]`" placeholder="userName">
    <input type="button" name="previous" class="previous action-button" value="Previous" @click="isPreviousClicked"/>
    <input type="submit" name="submit" class="submit action-button" value="Create a Ticket" id="excel"/>
  </fieldset>
  </div>

How can I append this without hard code all the input fields as I did here:?

<input v-model="param.Username" type="text" name="`inputFields[${index}[Username]]`" placeholder="userName">

This is designated to be dynamic, what do i mean? I mean that if the this.platform is equal to "one" there will be a unique fields, and if this.platform equal to "two" for example there will be other unique fields.

1 Answer 1

2

Don't think like "pushing a form field", rather think like "adding a new item to the dataset" (and of course, its displayed UI is a form field).

Let me give an example:

Vue.component("FormField", {
  props: ["label", "value"],
  computed: {
    val: {
      get() {
        return this.value
      },
      set(val) {
        this.$emit("update:value", val)
      }
    },
  },
  methods: {
    handleClickAdd() {
      this.$emit("click-add-field")
    }
  },
  template: `
    <div>
      <label>
        {{ label }}: <input type="text" v-model="val" />
      </label>
      <button
        @click="handleClickAdd"
      >
        + ADD
      </button>
    </div>
  `,
})

new Vue({
  el: "#app",
  data() {
    return {
      formFields: [{
        label: "Field 1",
        value: null,
      }],
    }
  },
  methods: {
    handleClickAddField() {
      const item = {
        label: `Field ${ this.formFields.length + 1 }`,
        value: null,
      }
      this.formFields = [...this.formFields, item]
    },
  },
  template: `
    <div
      class="container"
    >
      <div
        class="col"
      >
        <h4>FIELDS:</h4>
        <hr>
        <form-field
          v-for="(field, i) in formFields"
          :key="i"
          :label="field.label"
          :value.sync="field.value"
          @click-add-field="handleClickAddField"
        />
      </div>
      <div
        class="col"
      >
        <h4>FIELD VALUES:</h4>
        <hr>
        <div
          v-for="(field, i) in formFields"
          :key="i"
        >{{ field.label }}: {{ field.value }}</div>
      </div>
    </div>
  `,
})
.container {
  display: flex;
}

.col {
  padding: 0 8px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app"></div>

You can see, that on ADD I just added a new item in the formFields - the values are bound in the template to a child-component, that handles the actual representation of the fields.

On the right side of the snippet, you can see another benefit of decoupling data from UI: I created another representation of the same data source - that immediately reacts to any changes!

Sign up to request clarification or add additional context in comments.

1 Comment

This showed me the right way to do it. Thank you!

Your Answer

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