Increment in Javascript function

Asked

Viewed 188 times

1

I’m having trouble making an increment in a javascript function.

I have a table with the following structure:

<table id="products-table">
<tbody>
 <tr>
   <th>Produto</th>
   <th>Código</th>
   <th>Quantidade</th>
   <th>Preço</th>
   <th>Ações</th>
 </tr>
 <tr>
   <td>&nbsp;</td>
   <td>&nbsp;</td>
   <td>&nbsp;</td>
   <td>&nbsp;</td>
   <td>
     <button onclick="RemoveTableRow(this)" type="button">Remover</button>
   </td>
 </tr>
</tbody>
<tfoot>
 <tr>
   <td colspan="5" style="text-align: left;">
     <button onclick="AddTableRow()" type="button">Adicionar Produto</button>
   </td>
 </tr>
</tfoot>
</table>

The Removetablerow(this) function has the following commands:

(function($) {
  remove = function(item) {
    var tr = $(item).closest('tr');
    tr.fadeOut(400, function() {
      tr.remove();  
    });
    return false;
  }
})(jQuery);

The Addtablerow() function has the following content:

var inicio = 1;
var maximo = 5;
(function($) {
if (inicio <= maximo) {
  AddTableRow = function() {
    var newRow = $("<tr>");
    var cols = "";
    cols += '<td>&nbsp;</td>';
    cols += '<td>&nbsp;</td>';
    cols += '<td>&nbsp;</td>';
    cols += '<td>&nbsp;</td>';
    cols += '<td>';
    cols += '<button onclick="RemoveTableRow(this)" type="button">Remover</button>';
    cols += '</td>';
    newRow.append(cols);
    $("#products-table").append(newRow);
    return false;
  };
    }
    inicio++;
})(jQuery);

These two functions insert and remove dynamic lines from a table. I need to create a condition so that it is allowed to insert only 5 lines and that when a line is deleted the counter is updated.

At the beginning of the Addtablerow() function I declared two variables and made a loop but the "start" value is always 1 and does not increment.

4 answers

1

Flávio, as many said you need to put the condition inside the function, but I see that you are having problems to manage content dynamically created in Javascript.

So in your case, maybe Vuejs can be more practical than jQuery.

follows below an example using Vuejs.:

var model = { 
  novo: {
    produto: "",
    codigo: "",
    quantidade: "",
    preco: "",
  },
  lista: []
};

var app = new Vue({
  el: '#tabela',
  data: model,
  methods: {
    deleteItem: function (item) {
      var index = this.lista.indexOf(item)
      this.lista.splice(index, 1);
    },
    novoItem: function (item) {
      if (this.lista.length == 5) {
        alert("Não é possivel ter mais de 5 produtos");
        return;
      }
      if (!item.produto || !item.codigo || !item.quantidade || !item.preco) {
        alert("Todos os campos são obrigatorios");
        return;
      }
      this.lista.push(item);
    }
  }
});
input {
  width: 100px;
}
<script src="https://unpkg.com/vue"></script>
<fieldset id="tabela">
  <legend>
    Hello Wolrd
  </legend>
  <table>
    <thead>
      <tr>
        <th>Indice</th>
        <th>Produto</th>
        <th>Código</th>
        <th>Quantidade</th>
        <th>Preço</th>
        <th>Ações</th>
      </tr>
    </thead>
    <tbody>
      <tr v-for="(item, index) in lista">
        <td>{{index}}</td>
        <td>{{item.produto}}</td>
        <td>{{item.codigo}}</td>
        <td>{{item.quantidade}}</td>
        <td>{{item.preco}}</td>
        <td><button v-on:click="deleteItem(item)">Delete</button></td>
      </tr>
    </tbody>
    <tfoot>
      <tr>
        <td></td>
        <td><input type="text" v-model="novo.produto" /></td>
        <td><input type="number" v-model="novo.codigo" /></td>
        <td><input type="number" v-model="novo.quantidade" /></td>
        <td><input type="number" v-model="novo.preco" /></td>
        <td><button v-on:click="novoItem(novo)">Incluir</button></td>
      </tr>
    </tfoot>
  </table>
</fieldset>

  • +Tobias Mesquita thanks for the suggestion. I don’t know the Vuejs you indicated, as this project is almost finished I adopted another solution but I will use Vuejs in another project.

1


You can change the logic a little, and instead of a counter you count the number of lines at the time of insertion, so you save a little code, example:

var maximo = 5;
(function($) {
   AddTableRow = function() {
      var qtd = $("#products-table tbody tr").length;
      //somente insere se a quantidade for menor ou igual a máximo
      if (qtd < maximo) {
         
         var newRow = $("<tr>");
         var cols = "";
         cols += '<td><input class="campo-dinamico" type="text"/></td>';
         cols += '<td>&nbsp;</td>';
         cols += '<td>&nbsp;</td>';
         cols += '<td>&nbsp;</td>';
         cols += '<td>';
         cols += '<button onclick="RemoveTableRow(this)" type="button">Remover</button>';
         cols += '</td>';
         newRow.append(cols);
         $("#products-table").append(newRow);
         resetId();
         return false;
       }
   };    
})(jQuery);

(function($) {
  RemoveTableRow = function(item) {
    var tr = $(item).closest('tr');
    tr.fadeOut(400, function() {
      tr.remove();  
      resetId();
    });
    
    return false;
  }
})(jQuery);
//renova os ids dos campos dinâmicos
function resetId(){
    $('.campo-dinamico').each(function(i){
       $(this).attr('id','campo-' + (i + 1)).val('campo-' + (i + 1));
    });
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="products-table" border="1">
<thead>
<tr>
   <th>Produto</th>
   <th>Código</th>
   <th>Quantidade</th>
   <th>Preço</th>
   <th>Ações</th>
 </tr>
</thead>
<tbody>
 <tr>
   <td><input type="text" id="campo-1" class="campo-dinamico" value="campo-1"/></td>
   <td>&nbsp;</td>
   <td>&nbsp;</td>
   <td>&nbsp;</td>
   <td>
     <button onclick="RemoveTableRow(this)" type="button">Remover</button>
   </td>
 </tr>
</tbody>
<tfoot>
 <tr>
   <td colspan="5" style="text-align: left;">
     <button onclick="AddTableRow()" type="button">Adicionar Produto</button>
   </td>
 </tr>
</tfoot>
</table>

For that you need to change some things:

  1. The table structure, put the table header in the thead, so you can count the exact number of lines in the tbody.
  2. The if that checks the amount of lines is in the wrong place, it should be within the function AddTableRow.
  3. The name of the function you remove is incorrect, change remove for RemoveTableRow
  • actually I forgot to mention, but I need the counter because I use it to name the fields created, like <input id="field + i" and by aeh will...

  • @Fláviokowalske need to test more I’m almost sure you will have problem if you use the counter to create the id of the fields, let’s assume that the counter is in 4 ie campo-4 user deletes field with id 1 campo-1 your counter will go back to 3, so when you add another field you will have two fields with id campo-3.

  • @Fláviokowalske see my edition including the function to "reset" the dynamic field ids. NOTE: I left the field value with field id for better visualization and understanding.

  • 1

    I saw your edition and am applying here in the project to see the result.

  • @Fláviokowalske ok any doubt let me know.

  • the script ran right, however, as I will have calculations between the fields created as for example: tab1total1 = tab1quantity1 * tab1valor1; tab1totalN = tab1quantityN * tab1valorN I need that the Ids do not renew, because the same "N" which passes in the input id will be passed as parameter in the function.

  • @Fláviokowalske you may not even need id in the fields, see this example: https://jsfiddle.net/LLudnhw2/

Show 2 more comments

0

I would do something like:

var inicio = 1, maximo = 5;

function addTableRow(){
   if (inicio <= maximo) {
    var newRow = $("<tr>");
    var cols = "";
    cols += '<td>&nbsp;</td>';
    cols += '<td>&nbsp;</td>';
    cols += '<td>&nbsp;</td>';
    cols += '<td>&nbsp;</td>';
    cols += '<td>';
    cols += '<button onclick="RemoveTableRow(this)" type="button">Remover</button>';
    cols += '</td>';
    newRow.append(cols);
    $("#products-table").append(newRow);
    inicio++;
   }
}

function removeTableRow(element){
    var tr = $(item).closest('tr');
    tr.fadeOut(400, function() {
     tr.remove();  
    }
    inicio--;
}
  • your solution worked almost 100% but I forgot to mention that I use the "start" counter to name the fields created type: '<td class="col-Md-1"><input type="number" min="1" max="90" step="1" class="form-control" name="tab1quantity' + start + '" id="tab1quantidade' + inicio + '"></td>'. So if at a given start moment = 5 I delete a line and add another I will have two fields called tab1quantity5.

  • There are ways to control this, you can: in the removal function, go through the trs again and rename td. This way, it will maintain the sequence of the elements. Or, have another variable, which only increases. and use this new variable to name its elements. ok?

0

I just modified where the counter is applied so as not to run away from what you thought:

(function($) {
  RemoveTableRow = function(item) {
    inicio--;
    var tr = $(item).closest('tr');
    tr.fadeOut(400, function() {
      tr.remove();
    });
    return false;
  }
})(jQuery);

var inicio = 1;
var maximo = 5;
(function($) {

  AddTableRow = function() {
    if (inicio < maximo) {
      inicio++;
      var newRow = $("<tr>");
      var cols = "";
      cols += '<td>&nbsp;</td>';
      cols += '<td>&nbsp;</td>';
      cols += '<td>&nbsp;</td>';
      cols += '<td>&nbsp;</td>';
      cols += '<td>';
      cols += '<button onclick="RemoveTableRow(this)" type="button">Remover</button>';
      cols += '</td>';
      newRow.append(cols);
      $("#products-table").append(newRow);
      return false;
    };
  }

})(jQuery);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="products-table">
  <tbody>
    <tr>
      <th>Produto</th>
      <th>Código</th>
      <th>Quantidade</th>
      <th>Preço</th>
      <th>Ações</th>
    </tr>
    <tr>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>&nbsp;</td>
      <td>
        <button onclick="RemoveTableRow(this)" type="button">Remover</button>
      </td>
    </tr>
  </tbody>
  <tfoot>
    <tr>
      <td colspan="5" style="text-align: left;">
        <button onclick="AddTableRow()" type="button">Adicionar Produto</button>
      </td>
    </tr>
  </tfoot>
</table>

I put the increment inside the click event and inside the condition that checks the line limit, and decreasing in the function that removes the line.

Browser other questions tagged

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