Add columns Vue.js

Asked

Viewed 883 times

1

I need to add the two columns when one of them is changed, for example: if evaluation is changed the highest grade is in final grade, the same thing for oriented studies.

var vm = new Vue({
  el: '#vue-instance',
  data: {
    tablenotas: [
       {
          avaliacao: 1,
          estudos_orientados: 2,
          nota_final: 3,
   		 }, 
       {
          avaliacao: 4,
          estudos_orientados: 5,
          nota_final: 9,
			 }
    ]
  },
  methods: {
  nota: function (avaliacao, estudos_orientados) {
    if (avaliacao >= estudos_orientados) {
      return avaliacao
    }
    else if (estudos_orientados > avaliacao) {
      return estudos_orientados
    }
  }
  }
})
body {
  background: #20262E;
  padding: 20px;
  font-family: Helvetica;
}

#app {
  background: #fff;
  border-radius: 4px;
  padding: 20px;
  transition: all 0.2s;
}

li {
  margin: 8px 0;
}

h2 {
  font-weight: bold;
  margin-bottom: 15px;
}

del {
  color: rgba(0, 0, 0, 0.3);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>
<div id="vue-instance">
  <table>
  <thead>
    <th>Avaliação</th>
    <th>Estudos Orientados</th>
    <th>Nota Final</th>
  </thead>
    <tbody>
      <tr v-for="item in tablenotas">
        <td><input type="text" v-model="item.avaliacao"></td>
        <td><input type="text" v-model="item.estudos_orientados"></td>
        <td><input type="text">{{nota(item.avaliacao, item.estudos_orientados)}}</td>

      </tr>


    </tbody>
  </table>

</div>

I also put in the jsfiddle

  • What you want is to add and add this value in nota_final ? Or that the value of {{nota(item.avaliacao, item.estudos_orientados)}} stay in the field?

  • @Noobsaibot I need both. Show value and change nota_end value

  • Okay, I left an answer. But it wouldn’t be right to display the sum of the notes ?

3 answers

1


I believe that in your answer the problem is that you are using interpolation, and how you are using an <input> within the <td>, one can use a v-bind:value or just :value to accomplish a bind of the value being returned from the method to the input.

Another point is that I modified the method using something that, I’m not sure of the correct nomenclature but I believe the name is Early Return, where you avoid working with Else, and rather prioritizing the Return.

Check in the example below:

EDIT: Missed putting the parseInt in the comparison of the note, soon problems were occurring in converting string for integer.

EDIT#2: Added validations for in cases where the whole field is deleted and empty. In this case it will show in the last field what is filled. If both are empty will put 0.

var vm = new Vue({
  el: '#vue-instance',
  data: {
    tablenotas: [
       {
          avaliacao: 1,
          estudos_orientados: 2,
          nota_final: 3,
   		 }, 
       {
          avaliacao: 4,
          estudos_orientados: 5,
          nota_final: 9,
			 }
    ]
  },
  methods: {
    nota (avaliacao, estudos_orientados) {
      if ((avaliacao !== '') && (estudos_orientados !== '')) {
      
        if (parseInt(avaliacao) > parseInt(estudos_orientados)) {
          return avaliacao
        }      

        return estudos_orientados
      }
      
      if (avaliacao === '') {
        if (estudos_orientados === '') {
          return 0
        }
        
        return estudos_orientados
      }
      
      return avaliacao
    }
  }
})
body {
  background: #20262E;
  padding: 20px;
  font-family: Helvetica;
}

#app {
  background: #fff;
  border-radius: 4px;
  padding: 20px;
  transition: all 0.2s;
}

li {
  margin: 8px 0;
}

h2 {
  font-weight: bold;
  margin-bottom: 15px;
}

del {
  color: rgba(0, 0, 0, 0.3);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>
<div id="vue-instance">
  <table>
  <thead>
    <th>Avaliação</th>
    <th>Estudos Orientados</th>
    <th>Nota Final</th>
  </thead>
    <tbody>
      <tr v-for="item in tablenotas">
        <td><input type="text" v-model="item.avaliacao"></td>
        <td><input type="text" v-model="item.estudos_orientados"></td>
        <td><input type="text" :value="nota(item.avaliacao, item.estudos_orientados)"></td>

      </tr>


    </tbody>
  </table>

</div>

  • There are hours that work, there are hours that do not. For example: if you put 10 in the evaluation and then 99 in the oriented studies, it works. But, if you go back and put 100 in the evaluation it does not calculate anymore. In several tests it stops working

  • Sorry, I didn’t notice this, I’ll check here.

  • @Luissouza I edited the answer

  • The two answers are working. How I select?

  • It’s working, but there’s a catch. If a note is blank or 0 does not work.

  • Not always the two values will be filled in. Sometimes only one, so it will be the largest

  • I got it, I didn’t get this detail either. See if the validations I did are enough.

  • 1

    Worked perfectly!!!!

Show 3 more comments

1

Complementing the response of guastallaigor, your code has a problem, when editing the fields the values are converted to string, what ends up making your code stop working.

So recommend converting to whole before checking which one is larger.

avaliacao = parseInt(avaliacao);
estudos_orientados = parseInt(estudos_orientados);

But I would do the following instead of passing the properties as a parameter item.avaliacao and item.estudos_orientados I would only pass the index, for that have to modify the attribute v-for for:

v-for="(item, index) in tablenotas"

and in the template the field:

<input type="text" :value="nota(index)">

the method would look like this:

nota(index) {
  // parseInt converte a string para inteiro
  var avaliacao = parseInt(this.tablenotas[index].avaliacao),
      estudos_orientados = parseInt(this.tablenotas[index].estudos_orientados);
  if (!avaliacao) avaliacao = 0;
  if (!estudos_orientados) estudos_orientados = 0;
  // Abaixo é feita a soma e atribuido a propriedade "nota_final" do
  // índice "index"
  this.tablenotas[index].nota_final = avaliacao + estudos_orientados;
  return (avaliacao >= estudos_orientados) ? avaliacao : estudos_orientados;
}

See working:

var vm = new Vue({
  el: '#vue-instance',
  data: {
    tablenotas: [
      {
        avaliacao: 1,
        estudos_orientados: 2,
        nota_final: 3,
      }, 
      {
        avaliacao: 4,
        estudos_orientados: 5,
        nota_final: 9,
      }
    ]
  },
  methods: {
    nota(index) {
      // parseInt converte a string para inteiro
      var avaliacao = parseInt(this.tablenotas[index].avaliacao),
          estudos_orientados = parseInt(this.tablenotas[index].estudos_orientados);
      if (!avaliacao) avaliacao = 0;
      if (!estudos_orientados) estudos_orientados = 0;
      // Abaixo é feita a soma e atribuido a propriedade "nota_final" do
      // índice "index"
      this.tablenotas[index].nota_final = avaliacao + estudos_orientados;
      return (avaliacao >= estudos_orientados) ? avaliacao : estudos_orientados;
    }
  }
})
body {
  background: #20262E;
  padding: 20px;
  font-family: Helvetica;
}

#app {
  background: #fff;
  border-radius: 4px;
  padding: 20px;
  transition: all 0.2s;
}

li {
  margin: 8px 0;
}

h2 {
  font-weight: bold;
  margin-bottom: 15px;
}

del {
  color: rgba(0, 0, 0, 0.3);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>
<div id="vue-instance">
  <table>
    <thead>
      <th>Avaliação</th>
      <th>Estudos Orientados</th>
      <th>Nota Final</th>
    </thead>
    <tbody>
      <tr v-for="(item, index) in tablenotas">
        <td><input type="text" v-model="item.avaliacao"></td>
        <td><input type="text" v-model="item.estudos_orientados"></td>
        <td><input type="text" :value="nota(index)"></td>
      </tr>
    </tbody>
  </table>
</div>

  • It’s working, but there’s a catch. If a note is blank or 0 does not work.

  • @Luissouza see now, for me it just wasn’t working when the field was empty, already putting the zero in anyone works perfectly.

1

You can simplify that and use the Math.maxthus:

methods: {
    nota: function() {
        return Math.max(...arguments);
    }
}

so you don’t get stuck with only 2 values. You could still make a new array in computed and add to it the notes already calculated, the best solution depends on what you want to do with the data after.

var vm = new Vue({
  el: '#vue-instance',
  data: {
    tablenotas: [{
        avaliacao: 1,
        estudos_orientados: 2,
        nota_final: 3,
      },
      {
        avaliacao: 4,
        estudos_orientados: 5,
        nota_final: 9,
      }
    ]
  },
  methods: {
    nota: function() {
      return Math.max(...arguments);
    }
  }
})
body {
  background: #20262E;
  padding: 20px;
  font-family: Helvetica;
  color: #ccc;
}

#app {
  background: #fff;
  border-radius: 4px;
  padding: 20px;
  transition: all 0.2s;
}

li {
  margin: 8px 0;
}

h2 {
  font-weight: bold;
  margin-bottom: 15px;
}

del {
  color: rgba(0, 0, 0, 0.3);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.min.js"></script>
<div id="vue-instance">
  <table>
    <thead>
      <th>Avaliação</th>
      <th>Estudos Orientados</th>
      <th>Nota Final</th>
    </thead>
    <tbody>
      <tr v-for="item in tablenotas">
        <td><input type="text" v-model="item.avaliacao"></td>
        <td><input type="text" v-model="item.estudos_orientados"></td>
        <td><input type="text" readonly :value="nota(item.avaliacao, item.estudos_orientados)"></td>

      </tr>


    </tbody>
  </table>

</div>

Browser other questions tagged

You are not signed in. Login or sign up in order to post.