@katyamishha
Front-end junior

Как проверить выбранный checkbox во vue.js?

Создаю тест опросник на vue.js, опросник состоит из слайдов, выбрал вариант на первом слайде, нажимаешь далее, там новые варианты, нужно, чтоб если ни один checkbox не выбран, кнопка далее не работала.
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <script src="https://vuejs.org/js/vue.js"></script>
    <title>Опрос</title>
  </head>
  <body>
    <div id="app">
      <div class="container">
        <!-- index is used to check with current question index -->
        <div class="first_screen" v-show="questionIndex === 0">
          <h1>Пройди опрос</h1>
          <div class="pink_text">Это займет 1-2 минуты</div>
          
                <button class="btn-pink_bg mr-3" v-on:click="next_first">
                  Пройти опрос
                </button>
        </div>
        <div class="screen" v-for="(question, index) in quiz.questions" :class="'screen_' + question.id">
          <transition 
                      v-on:before-enter="beforeEnter"
                      v-on:enter="enter"
                      v-bind:css="false"
                      >
            <div v-show="index+1 === questionIndex">
              <h2>{{ question.text }}</h2>
              <ol>
                <li v-for="response in question.responses" :class="question.id" >
                  <label :class="question.pswdType">
                    <input v-if="questionIndex < 3" type="radio"
                           :value="response.text"
                           :name="index" 
                           v-model="pickeds"> 
                    <input v-else type="checkbox"
                           :value="response.text"
                           :name="index" 
                           v-model="checkedNames"> 
                    <div :class="question.pswdType + '__text'">{{response.text}}</div> 
                  </label>
                </li>
              </ol>
              <div class="text-center">
                <button class="btn-prev" v-if="questionIndex > 0" v-on:click="prev">
                  Назад
                </button>
                <button class="btn-pink_bg" v-on:click="next">
                  Далее
                </button>
              </div>
            </div>
          </transition>
        </div>
        <div v-show="questionIndex === quiz.questions.length+1">
          <h2>
            Опрос успешно завершен
          </h2>
          <p>
            Отмеченные поля: 
          </p> 
          <ul >

            <li v-for="checkedName in checkedNames">
              {{ checkedName }}
            </li>
          </ul>
        </div>
      </div>
    </div>



    <script>
      let quiz = {
        questions: [
          {
            text: "тут выбираем только один ответ",
            pswdType: 'radio', 
            id: 'type_site',
            responses: [
              {text: 'первый '}, 
              {text: 'второй'}, 
              {text: 'третий'}, 
              {text: 'четвертый'},
            ]
          } , {
            text: "тут  ТОЖЕ выбираем только один ответ",
            pswdType: 'radio',
            id: 'design',
            responses: [
              {text: 'Уникальный'}, 
              {text: 'Шаблонный'}, 
              {text: 'Рассчитать оба варианта'}, 
            ]
          }
          , {
            text: "Здесь множественный выбор",
            pswdType: 'checkbox',
            id: 'cart_product',
            responses: [ 
              {text: 'Выбор цвета'}, 
              {text: 'Рекомендации'}, 
              {text: 'Выбор размера'}, 
              {text: 'Выбрать ширину'}, 
            ]
          }
          , {
            text: "И здесь множественный выбор",
            pswdType: 'checkbox',
            id: 'list_product',
            responses: [
              {text: 'Вес'}, 
              {text: 'Рост'},
              {text: 'Ширина'}, 
              {text: 'Глубина'},  
            ]
          }
        ]
      };

      new Vue({
        el: '#app',
        data: {
          quiz: quiz,
          questionIndex: 0,
          pickeds: [],
          checkedNames: [],
        },

        methods: {

          next_first: function() {
            this.questionIndex++;
            this.updateHistory();
          },
          next: function(index) {
            if((this.checkedNames.length!==0) || (this.pickeds.length!==0)){
              this.questionIndex++;
              this.updateHistory();
            }
          },

          prev: function() {
              this.questionIndex--;
              this.updateHistory();
          },

          updateHistory: function() {
            history.pushState({questionIndex: this.questionIndex}, "Question " + this.questionIndex);
          }

        }
      });
    </script>
  </body>
  • Вопрос задан
  • 2396 просмотров
Решения вопроса 1
0xD34F
@0xD34F Куратор тега Vue.js
Создаёте массив answers для хранения ответов. В зависимости от количества ожидаемых ответов (один или несколько) его элементы будут строками или массивами.

Связываете элементы answers с радиокнопками/чекбоксами вариантов ответов:

v-model="answers[questionIndex]"

Создаёте вычисляемое свойство, которое будет индикатором наличия ответа/ответов на текущий вопрос:

computed: {
  answerSelected() {
    return this.answers[this.questionIndex].length;
  },
},

И, наконец, используете это свойство для блокирования кнопки перехода к следующему вопросу:

:disabled="!answerSelected"

UPD. https://jsfiddle.net/20L61r85/

UPD. Вынесено из комментариев:

А можете подсказать, как в результат вывести не только отмеченные поля, но на какой вопрос были эти поля отмечены?

Можно в шаблоне добавить индекс при переборе ответов, по которому будем доставать вопрос. Или можно сделать ответ свойством вопроса - тогда при выводе результатов перебираем вопросы, и вся нужная информация доступна в одном месте.
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
@dGololobov
начинающий
Попробуйте на кнопке добавить
<button  class="btn-pink_bg" v-on:click="next" v-bind:disabled="!checked[0]">Далее </button>
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы