Add columns Vue.js

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 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><divid="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 it in jsfiddle

    
asked by anonymous 12.05.2018 / 23:55

3 answers

1

I think in your answer the problem is that you are using interpolation, and since you are using <input> within <td> , you can use v-bind:value or just :value to perform bind of the value being returned from the method to input .

Another point is that I modified the method using something that I'm not sure of the correct nomenclature but I think the name is early return , where you avoid working with else but prioritizing return .

Check out the example below:

EDIT:

p>

EDIT # 2: Added validations for cases where the entire field is deleted and the field is empty. In this case it will show in the last field what is filled. If both are empty it 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><divid="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>
    
13.05.2018 / 00:18
1

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

So I recommend converting to integer 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 item.avaliacao and item.estudos_orientados as a parameter I would only pass the index, so you have to modify the v-for attribute to:

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><divid="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>
    
13.05.2018 / 01:11
1

You can simplify this and use Math.max like this:

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

This way you do not get stuck with only 2 values. You could also make a new array in computed and add the already calculated notes, the best solution depends on what you are trying to do with the data later.

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><divid="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>
    
16.05.2018 / 14:45