2
votes

In VueJS I want to associate input text fields with check-boxes i.e If someone select a checkbox he should enter some value in input field associated with that checkbox.

Now the problem is that the check-boxes are created based on database values so the number of check-boxes are dynamic. The check-boxes are bind with array assessments:[],

 <input type="checkbox" :value="assessment" :id="assessment+index" class="md-check" v-model="form.assessments">

So when a checkbox is selected its value is stored in array assessments:[], each selected checkbox will have an associated value which will be entered in text field.

Note: I have already checked the below link but it's not for vueJS. Associate input type checkbox to input type text

1

1 Answers

1
votes

This is one of the situations where Vue shines. In the question you linked, jQuery was used. You will notice that they have to manually select a related input box and enable or disable it. None of that is needed in Vue.

In Vue we have for-loops in templates and the ability to compute element properties. This is the time to use them. You weren't clear on what you actually get from the server, but lets say you get the following data structure from the server.

{
  assessments: [
    {
      label: "assessment 1",
      value: 0
    },
    {
      label: "assessment 2",
      value: 1
    },
    {
      label: "assessment 3",
      value: 0
    },
    {
      label: "assessment 4",
      value: 0
    }
  ]
}

To render this, we can put this data structure in a local data variable assessments and loop through this.

<template>
  <div>
    <div v-for="(assessment, index) in assessments" :key="index" class="row">
      {{ assessment.label }}
    </div>
  </div>
</template>

We still don't have a way to manage the data from checkboxes or your input fields, so lets populate that. In the function you use to assign this.assessments = whateveryougetfromtheserver;, also populate the form:

for (const assessment of this.assessments) {
  this.form.assessments.enabled.push(assessment.value > 0);
  this.form.assessments.value.push(assessment.value);
}

You would end up with a data structure that looks something like this:

{
  assessments: [
    { label: 'label 1', value: 0 },
    { label: 'label 2', value: 1 },
    // etc
  ],
  form: {
    assessments: {
      enabled: [
        false,
        true,
        // etc
      ],
      value: [
        0,
        1,
        // etc
      ]
    }
  }
}

Now we only have to map the checkboxes and input fields and we are good to go. To do this we modify the template:

<div v-for="(assessment, index) in assessments" :key="index" class="row">
  {{ assessment.label }}
  <input type="checkbox" v-model="form.assessments.enabled[index]" class="md-check" />
  <input type="number" :disabled="!form.assessments.enabled[index]" v-model="form.assessments.value[index]" />
</div>

A full working example can be found on codesandbox: Edit Vue Template