Предварительный выбор радиовхода в компоненте Vue в сложном цикле v-for - PullRequest
0 голосов
/ 25 января 2019

У меня есть компонент Vue, который обрабатывает несколько форм, извлекает и отправляет данные из и в API форм Gravity.Все работает отлично, за исключением предварительного выбора значения по умолчанию для радиовхода (который представлен как переключатель).

Вот сокращенная версия компонента:

<template>
    <form :id="gf" ref="form">
        <div
            v-for="field in fields"
            :key="field.id"
            :id="`field_${field.id}`"
            :class="`field field__${field.type}`"
        >
            <div v-if="field.type == 'radio'">
                <div v-for="(choice, index) in field.choices" :key="choice.value">
                    <input
                        type="radio"
                        :id="`gf_${index}_${field.id}`"
                        :name="`input_${field.id}`"
                        :value="choice.value"
                        v-model="entries[`input_${field.id}`]"

                        // insert way of checking input with isSelected == true here
                    >
                    <label :for="`gf_${index}_${field.id}`">{{ choice.text }}</label>
                </div>
            </div>
        </div>
    </form>
</template>

<script>
export default {
    props: {
        formId: {
            type: String,
            default: '',
        },
        formName: {
            type: String,
            default: '',
        },
    },

    data() {
        return {
            fields: '',
            form: '',
            entries: {},
        }
    },

    mounted: function() {
        this.getForm()
    },

    methods: {
        getForm() {
            const vm = this
            axios
                .post('path/to/gravity/forms/api', {
                    id: vm.formId,
                })
                .then(result => {
                    vm.form = result.data
                    vm.fields = result.data.fields
                })
                .catch(err => {
                    console.log(err)
                })
        },

    },
}
</script>

Обратите внимание, чтозначения передаются в форму правильным образом, но только при нажатии.Мне нужно найти способ автоматической проверки ввода на основе данных, полученных из API.

API возвращает простой массив для каждого радиовхода, вход по умолчанию (как определено в формах гравитации) выглядит следующим образом:

isSelected: true
text: "Email"
value: "Email"

Примечание: я прочитал много ответов на связанныепроблемы с переполнением стека, но решение неизменно включает в себя жесткое кодирование значений в данные, что невозможно.Также запись должна быть добавлена ​​в указанном выше формате, чтобы API мог понять представление (код для этого не имеет значения, поэтому не включен).

Все предложения приветствуются.

Ответы [ 2 ]

0 голосов
/ 26 января 2019

Благодаря указателям от Даниэля и Роя Дж, я смог решить эту проблему достаточно просто, добавив метод для циклического обхода входящих полей и соответственно обновляя объект записи.

   getForm() {
        const vm = this
        axios
            .post('/path/to/gf/api', {
                id: vm.formId,
            })
            .then(result => {
                vm.form = result.data
                vm.fields = result.data.fields
                vm.getRadios()
            })
            .catch(err => {
                console.log(err)
            })
    },
    getRadios() {
        let radios = this.fields.filter(field => field.type == 'radio')
        radios.forEach(radio => {
            let selected = radio.choices.find(
                choice => choice.isSelected == true
            )
            this.entries[`input_${radio.id}`] = selected.value
        })
    },

Я также добавил

 :checked="choice.isSelected"

на шаблоне вместе с v-моделью, как и раньше.

0 голосов
/ 25 января 2019

Если вы не используете entries для чего-либо еще, вам это вообще не нужно. Вам не нужно v-model, вы просто хотите установить checked, что довольно просто:

:checked="choice.isSelected"

new Vue({
  el: '#app',
  data: {
    fields: []
  },
  methods: {
    fetchData() {
      setTimeout(() => {
        this.fields = [
          {
            id: 1,
            type: 'radio',
            choices: [
              {
                isSelected: false,
                value: 1,
                text: 'one'
              },
              {
                isSelected: true,
                value: 2,
                text: 'two'
              }
            ]
          },
          {
            id: 2,
            type: 'radio',
            choices: [
              {
                isSelected: true,
                value: 1,
                text: 'three'
              },
              {
                isSelected: false,
                value: 2,
                text: 'four'
              }
            ]
          },
        ];
      }, 500);
    }
  },
  created() {
    this.fetchData();
  }
});
<script src="https://unpkg.com/vue@latest/dist/vue.js"></script>
<form id="app">
  <div v-for="field in fields" :key="field.id" :class="`field field__${field.type}`">
    <div v-for="(choice, index) in field.choices" :key="choice.value">
      <input type="radio" :id="`gf_${index}_${field.id}`" :name="`input_${field.id}`" :value="choice.value" :checked="choice.isSelected">
      <label :for="`gf_${index}_${field.id}`">{{ choice.text }}</label>
    </div>
  </div>
</form>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...