How to create v-sliders using a matrix?

243 Views Asked by At

I'm trin' to create a loop with some v-sliders inside it, besides, I need to use a matrix to store the data obtained from value param of v-slider tag. How can I do this?

Note.: I've tried to create a function that generates my matrix and assign the variable within data() to it, but it didn't work. Something like :value="this.matrix[iA * 21 + iB][iA * 21 + iB]", where iB and iA are indexes equivalent to for-loop. And the function was called in created() or even before.

It raises the following error to me: Error in render: "TypeError: Cannot read property 'matrix' of undefined"

Edit (component code):

<template>
  <div class="form">
    <v-form>
      <v-container class="pt-5">
        <v-divider></v-divider>
        <p class="text-center display-1 mb-5" id="conhecimentotec">
          Conhecimento técnico
        </p>

        <!-- Questions -->
        <div v-for="(a, iA) in questions" :key="a">
          <v-row v-for="(b, iB) in questions.slice(iA)" :key="b" min-height="">
            <!-- Nome (pergunta) -->
            <v-tooltip top color="indigo darken-2">
              <template v-slot:activator="{ on, attrs }">
                <v-row v-if="a != b" class="px-5" v-on="on" v-bind="attrs">
                  <v-subheader>IdA: {{ iA }}___IdB: {{ iB }} </v-subheader>
                  <v-col cols="5"
                    ><span class="font-weight-bold"> {{ a }} </span></v-col
                  >
                  <v-col cols="2" class="text-center"
                    ><span class="font-weight-bold"> vs </span></v-col
                  >
                  <v-col cols="5" class="text-right"
                    ><span class="font-weight-bold">
                      {{ b }}
                    </span></v-col
                  >
                </v-row>
              </template>
              <h4>
                O quão [<i
                  ><b>{{ a }}</b></i
                >] é mais "importante" com relação à [<i
                  ><b>{{ b }}</b></i
                >]
              </h4>
            </v-tooltip>

            <!-- Slider -->
            <v-card-text v-if="a != b">
              <v-slider
                persistent-hint
                step="2"
                thumb-label
                ticks="always"
                tick-size="1"
                :min="ahp.min"
                :max="ahp.max"
                :tick-labels="ahp.ticks"
                class="pb-5 mb-5 grey--text text-subtitle-1"
                color="indigo lighten-1"
                track-color="indigo lighten-1"
                dense
                :value="this.matrix[iA * 21 + iB][iA * 21 + iB]"
              >
              </v-slider>
            </v-card-text>
          </v-row>
        </div>

        <!-- User infos -->
        <v-divider></v-divider>
        <v-divider></v-divider>
        <v-row>
          <span class="pa-5 display-1 my-5">Confirmar e enviar</span>
        </v-row>
        <v-row align-self class="mb-5 pb-5">
          <v-col cols="5">
            <v-text-field
              v-model="user.username"
              :rules="rules.empty"
              :counter="10"
              label="Nome"
              required
            ></v-text-field>
          </v-col>
          <v-col cols="5">
            <v-text-field
              v-model="user.email"
              :rules="rules.email"
              label="E-mail"
              required
            ></v-text-field>
          </v-col>
          <v-spacer></v-spacer>
          <v-col>
            <v-btn class="success" right @click="submit">Enviar</v-btn>
          </v-col>
        </v-row>
      </v-container>
    </v-form>
  </div>
</template>

<script>
function createMatrix() {
  let matrix = new Array(21);
  for (let i = 0; i < 21; i++) {
    matrix[i] = new Array(21);
    for (let j = 0; j < 21; j++) matrix[i][j] = 1;
  }
  console.log("createMatrix -> matrix", matrix);
  return matrix;
}

export default {
  data() {
    return {
      alignmentsAvailable: ["start", "center", "end", "baseline", "stretch"],
      alignment: "center",
      dense: false,
      justifyAvailable: [
        "start",
        "center",
        "end",
        "space-around",
        "space-between",
      ],
      justify: "center",

      ahp: {
        ticks: [
          "Igual",
          "Moderada",
          "Mais importante",
          "Muito mais",
          "Extremamente mais",
        ],
        min: 1,
        max: 9,
        step: 2,
      },
      rules: {
        email: [
          (v) =>
            /^([\w-]+(?:\.[\w-]+)*)@((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$/.test(
              v
            ) || "E-mail inválido",
        ],
        empty: [
          (v) =>
            v.length >= 5 || "Não alcançou o tamanho mínimo de caracteres.",
        ],
      },
      user: { username: "", email: "" },

      // O número de perguntas é dado pela fórmula de combinação: n!/( p!(n-p)! )
      // onde n é a qnt do vetor e p são as perguntas (em pares => 2)
      questions: [
        "A",
        "B",
        "C",
      matrix: createMatrix(),
    };
  },
  methods: {
    debug(variable) {
      console.log(variable);
    },
    submit() {
      const { username, email } = this.user;
      console.log("submit -> email", email);
      console.log("submit -> username", username);
    },
  },
};
</script>
1

There are 1 best solutions below

0
On

How I solved it.

<script>
export default {
  data() {
    return {
      questions: [
        "Matemática e física",
        "Lógica, algoritmos e estrutura de dados",
        "Linguagens e paradigmas de programação específicos",
        "Teoria da computação",
        "Projeto e análise de algoritmos",
        "Configurar plataformas para aplicações de software e serviços",
        "Arquiteturas de computadores",
      ],
      matrix: undefined,
    };
  },
  created() {
    // Initiallize the matrix itself filled with ones
    this.matrix = new Array(this.questions.length);
    for (let row = 0; row < this.matrix.length; row++)
      this.matrix[row] = new Array(this.questions.length).fill(1);
  },
};
</script>
<v-slider
  persistent-hint
  step="2"
  thumb-label
  ticks="always"
  tick-size="1"
  :min="ahp.min"
  :max="ahp.max"
  :tick-labels="ahp.ticks"
  class="pb-5 mb-5 grey--text text-subtitle-1"
  color="indigo lighten-1"
  track-color="indigo lighten-1"
  dense
  v-model="matrix[iA][iB + iA]"
  @change="iMatrixValue(iA, iB + iA)"
>
</v-slider>

Usefull links: