Create Editable Table

3

I would like to create a table where your cells can be edited but meet certain requirements. What I have is this:

HTML

<table class="table table-striped table-bordered" id="vendaTabela" width="100%">
    <thead>
      <tr>
        <th data-class="expand">Cód.</th>
        <th data-hide="phone">Designação</th>
        <th data-hide="phone">Qnt.</th>
        <th data-hide="phone,tablet">Uni.</th>
        <th>Preço</th>
        <th>Desconto</th>
        <th>IVA</th>
        <th>Sub-Total</th>
      </tr>
    </thead>
  <tbody>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
 </tbody>

JQUERY

$(function () {
        $("td").dblclick(function () {
            var conteudoOriginal = $(this).text();
            $(this).addClass("celulaEmEdicao");
            $(this).html("<input type='text' value='" + conteudoOriginal + "' />");
            $(this).children().first().focus();
            console.log($(this).attr('id'));
            $(this).children().first().keypress(function (e) {
                if (e.which == 13) {
                    var novoConteudo = $(this).val();
                    $(this).parent().text(novoConteudo);
                    $(this).parent().removeClass("celulaEmEdicao");
                }
            });
            $(this).children().first().blur(function () {
                $(this).parent().text(conteudoOriginal);
                $(this).parent().removeClass("celulaEmEdicao");
            });


        });
    });

I also have a button for adding new lines:

//ADICIONAR LINHA
    $("#btnAdd").click(function () {
        $('#vendaTabela').append('<tr><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr>');
    });

As far as requirements go, it is best to go by stages:

1st - I would like to find a way for cells to be identified. I know I can put id's in the HTML tags but when I add a new line, how are they identified?

2nd - How can I put function by columns? That is, I want the 'Sub-Total' column to be the column multiplication 'Qnt.' with the 'Price' column. I can do the function for the first line already created in HTML, but, how do I do when I add another line?

3º- How can I put an autocomplete in the column you want, for example in the 'Designation' column?

    
asked by anonymous 26.02.2015 / 11:38

2 answers

5

As I said above, you can do this using jsViews, as in the example below:

For this you will need an Entity that would serve as a template, in this case the following:

{
    Codigo: "",
    Designacao: "",
    Quantidade: "",
    Unidade: "",
    Preco: "",
    Desconto: "",
    IVA: "",
    SubTotal: ""
}

You will have the templates for each Row state (Details, Insert and Create):

<script id="tmplDetails" type="text/x-jsrender">
    <tr data-type="details">
        <td><input name="btEditar" type="button" value="Editar" /></td>
        <td>{{:Codigo}}</td>
        <td>{{:Designacao}}</td>
        <td>{{:Quantidade}}</td>
        <td>{{:Unidade}}</td>
        <td>{{:Preco}}</td>
        <td>{{:Desconto}}</td>
        <td>{{:IVA}}</td>
        <td>{{:SubTotal}}</td>
    </tr>
</script>

<script id="tmplEdit" type="text/x-jsrender">
    <tr data-type="edit">
        <td><input name="btSalvar" type="button" value="Salvar" /></td>
        <td><input name="txtCodigo" type="text" value="{{:Codigo}}" /></td>
        <td><input name="txtDesignacao" type="text" value="{{:Designacao}}" /></td>
        <td><input name="txtQuantidade" type="text" value="{{:Quantidade}}" /></td>
        <td><input name="txtUnidade" type="text" value="{{:Unidade}}" /></td>
        <td><input name="txtPreco" type="text" value="{{:Preco}}" /></td>
        <td><input name="txtDesconto" type="text" value="{{:Desconto}}" /></td>
        <td><input name="txtIVA" type="text" value="{{:IVA}}" /></td>
        <td><input name="txtSubTotal" type="text" value="{{:SubTotal}}" /></td>
    </tr>
</script>

<script id="tmplCreate" type="text/x-jsrender">
    <tr data-type="create">
        <td><input name="btSalvar" type="button" value="Salvar" /></td>
        <td><input name="txtCodigo" type="text" value="{{:Codigo}}" /></td>
        <td><input name="txtDesignacao" type="text" value="{{:Designacao}}" /></td>
        <td><input name="txtQuantidade" type="text" value="{{:Quantidade}}" /></td>
        <td><input name="txtUnidade" type="text" value="{{:Unidade}}" /></td>
        <td><input name="txtPreco" type="text" value="{{:Preco}}" /></td>
        <td><input name="txtDesconto" type="text" value="{{:Desconto}}" /></td>
        <td><input name="txtIVA" type="text" value="{{:IVA}}" /></td>
        <td><input name="txtSubTotal" type="text" value="{{:SubTotal}}" /></td>
    </tr>
</script>

Remembering that you can use aritimeticas operations in the template, then {{:Quantidade * Preco}} is valid and can be used in SubTotal.

Note that I used the template properties in the templates, so we know how to fill in the template.

Finally we will have the HTML of the table itself:

<table id="vendaTabela">
    <thead>
        <tr>
            <th></th>
            <th data-class="expand">Cód.</th>
            <th data-hide="phone">Designação</th>
            <th data-hide="phone">Qnt.</th>
            <th data-hide="phone,tablet">Uni.</th>
            <th>Preço</th>
            <th>Desconto</th>
            <th>IVA</th>
            <th>Sub-Total</th>
        </tr>
    </thead>
    <tbody>
    </tbody>
    <tfoot>
        <tr>
            <td><input name="btCreate" type="button" value="Criar" /></td>
            <td colspan="8"></td>
        </tr>
    <tfoot>
<table>

The script below is mounting the table using a Source, which in this case can be an AJAX request, however I am using a list with 10 Entities.

var documento = $(document);
var vendaTabela = $("#vendaTabela");
var tabelaBody = $("tbody", vendaTabela);

var tmplDetails = $.templates("#tmplDetails");
var tmplEdit = $.templates("#tmplEdit");
var tmplCreate = $.templates("#tmplCreate");

var entidades = [];
for (var i = 1; i <= 10; i++) {
    entidades.push({
        Codigo: "Codigo" + i,
        Designacao: "Designacao" + i,
        Quantidade: "Quantidade" + i,
        Unidade: "Unidade" + i,
        Preco: "Preco" + i,
        Desconto: "Desconto" + i,
        IVA: "IVA" + i,
        SubTotal: "SubTotal" + i
    });
}

tabelaBody.empty();
$.each(entidades, function (indice, entidade) {
    var novaLinha = $(tmplDetails.render(entidade));
    novaLinha.data("Entidade", entidade);

    tabelaBody.append(novaLinha);
});

documento.on("click", "#vendaTabela input[name='btCreate']", function () {
    var novaEntidade = {};
    var novaLinha = $(tmplCreate.render(novaEntidade));
    novaLinha.data("Entidade", novaEntidade);

    tabelaBody.append(novaLinha);
});

documento.on("click", "#vendaTabela input[name='btEditar']", function () {
    var linha = $(this).closest("[data-type]");
    var entidade = linha.data("Entidade");
    var novaLinha = $(tmplCreate.render(entidade));
    novaLinha.data("Entidade", entidade);

    linha.replaceWith(novaLinha);    
});

documento.on("click", "#vendaTabela input[name='btSalvar']", function () {
    var linha = $(this).closest("[data-type]");
    var txtCodigo = $("[name='txtCodigo']", linha);
    var txtDesignacao = $("[name='txtDesignacao']", linha);
    var txtQuantidade = $("[name='txtQuantidade']", linha);
    var txtUnidade = $("[name='txtUnidade']", linha);
    var txtPreco = $("[name='txtPreco']", linha);
    var txtDesconto = $("[name='txtDesconto']", linha);
    var txtIVA = $("[name='txtIVA']", linha);
    var txtSubTotal = $("[name='txtSubTotal']", linha);

    var entidade = linha.data("Entidade");
    entidade.Codigo = txtCodigo.val();
    entidade.Designacao = txtDesignacao.val();
    entidade.Quantidade = txtQuantidade.val();
    entidade.Unidade = txtUnidade.val();
    entidade.Preco = txtPreco.val();
    entidade.Desconto = txtDesconto.val();
    entidade.IVA = txtIVA.val();
    entidade.SubTotal = txtSubTotal.val();    

    var novaLinha = $(tmplDetails.render(entidade));    
    novaLinha.data("Entidade", entidade);

    linha.replaceWith(novaLinha);

});

Note that I bind events using on direct in document , I made this so that these events are available for elements created through the template.

end the code in its entirety:

var documento = $(document);
var vendaTabela = $("#vendaTabela");
var tabelaBody = $("tbody", vendaTabela);

var tmplDetails = $.templates("#tmplDetails");
var tmplEdit = $.templates("#tmplEdit");
var tmplCreate = $.templates("#tmplCreate");

var entidades = [];
for (var i = 1; i <= 10; i++) {
    entidades.push({
        Codigo: "Codigo" + i,
        Designacao: "Designacao" + i,
        Quantidade: "Quantidade" + i,
        Unidade: "Unidade" + i,
        Preco: "Preco" + i,
        Desconto: "Desconto" + i,
        IVA: "IVA" + i,
        SubTotal: "SubTotal" + i
    });
}

tabelaBody.empty();
$.each(entidades, function (indice, entidade) {
    var novaLinha = $(tmplDetails.render(entidade));
    novaLinha.data("Entidade", entidade);
    
    tabelaBody.append(novaLinha);
});

documento.on("click", "#vendaTabela input[name='btCreate']", function () {
    var novaEntidade = {};
    var novaLinha = $(tmplCreate.render(novaEntidade));
    novaLinha.data("Entidade", novaEntidade);
    
    tabelaBody.append(novaLinha);
});

documento.on("click", "#vendaTabela input[name='btEditar']", function () {
    var linha = $(this).closest("[data-type]");
    var entidade = linha.data("Entidade");
    var novaLinha = $(tmplEdit.render(entidade));
    novaLinha.data("Entidade", entidade);
    
    linha.replaceWith(novaLinha);    
});

documento.on("click", "#vendaTabela input[name='btSalvar']", function () {
    var linha = $(this).closest("[data-type]");
    var txtCodigo = $("[name='txtCodigo']", linha);
    var txtDesignacao = $("[name='txtDesignacao']", linha);
    var txtQuantidade = $("[name='txtQuantidade']", linha);
    var txtUnidade = $("[name='txtUnidade']", linha);
    var txtPreco = $("[name='txtPreco']", linha);
    var txtDesconto = $("[name='txtDesconto']", linha);
    var txtIVA = $("[name='txtIVA']", linha);
    var txtSubTotal = $("[name='txtSubTotal']", linha);
    
    var entidade = linha.data("Entidade");
    entidade.Codigo = txtCodigo.val();
    entidade.Designacao = txtDesignacao.val();
    entidade.Quantidade = txtQuantidade.val();
    entidade.Unidade = txtUnidade.val();
    entidade.Preco = txtPreco.val();
    entidade.Desconto = txtDesconto.val();
    entidade.IVA = txtIVA.val();
    entidade.SubTotal = txtSubTotal.val();    
    
    var novaLinha = $(tmplDetails.render(entidade));    
    novaLinha.data("Entidade", entidade);
    
    linha.replaceWith(novaLinha);
    
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><scriptsrc="http://www.jsviews.com/download/jsviews.js"></script>
<script src="http://cdn.foundation5.zurb.com/foundation.js"></script><linkhref="http://cdn.foundation5.zurb.com/foundation.css" rel="stylesheet"/>
<table id="vendaTabela">
    <thead>
        <tr>
            <th></th>
            <th data-class="expand">Cód.</th>
            <th data-hide="phone">Designação</th>
            <th data-hide="phone">Qnt.</th>
            <th data-hide="phone,tablet">Uni.</th>
            <th>Preço</th>
            <th>Desconto</th>
            <th>IVA</th>
            <th>Sub-Total</th>
        </tr>
    </thead>
    <tbody>
    </tbody>
    <tfoot>
        <tr>
            <td><input name="btCreate" type="button" value="Criar" /></td>
            <td colspan="8"></td>
        </tr>
    <tfoot>
<table>
    

<script id="tmplDetails" type="text/x-jsrender">
    <tr data-type="details">
        <td><input name="btEditar" type="button" value="Editar" /></td>
        <td>{{:Codigo}}</td>
        <td>{{:Designacao}}</td>
        <td>{{:Quantidade}}</td>
        <td>{{:Unidade}}</td>
        <td>{{:Preco}}</td>
        <td>{{:Desconto}}</td>
        <td>{{:IVA}}</td>
        <td>{{:SubTotal}}</td>
    </tr>
</script>

<script id="tmplEdit" type="text/x-jsrender">
    <tr data-type="edit">
        <td><input name="btSalvar" type="button" value="Salvar" /></td>
        <td><input name="txtCodigo" type="text" value="{{:Codigo}}" /></td>
        <td><input name="txtDesignacao" type="text" value="{{:Designacao}}" /></td>
        <td><input name="txtQuantidade" type="text" value="{{:Quantidade}}" /></td>
        <td><input name="txtUnidade" type="text" value="{{:Unidade}}" /></td>
        <td><input name="txtPreco" type="text" value="{{:Preco}}" /></td>
        <td><input name="txtDesconto" type="text" value="{{:Desconto}}" /></td>
        <td><input name="txtIVA" type="text" value="{{:IVA}}" /></td>
        <td><input name="txtSubTotal" type="text" value="{{:SubTotal}}" /></td>
    </tr>
</script>

<script id="tmplCreate" type="text/x-jsrender">
    <tr data-type="create">
        <td><input name="btSalvar" type="button" value="Salvar" /></td>
        <td><input name="txtCodigo" type="text" value="{{:Codigo}}" /></td>
        <td><input name="txtDesignacao" type="text" value="{{:Designacao}}" /></td>
        <td><input name="txtQuantidade" type="text" value="{{:Quantidade}}" /></td>
        <td><input name="txtUnidade" type="text" value="{{:Unidade}}" /></td>
        <td><input name="txtPreco" type="text" value="{{:Preco}}" /></td>
        <td><input name="txtDesconto" type="text" value="{{:Desconto}}" /></td>
        <td><input name="txtIVA" type="text" value="{{:IVA}}" /></td>
        <td><input name="txtSubTotal" type="text" value="{{:SubTotal}}" /></td>
    </tr>
</script>
    
26.02.2015 / 15:15
2

1. You can solve using classes in the columns and id's in the rows to identify them. For example:

<tr id="linha1">
    <td class="numero">123</td>
    <td class="nome">Teste</td>
</tr>
<tr id="linha2">
    <td class="numero">123</td>
    <td class="nome">Teste</td>

var $numero = $("#linha1 .numero"); // coluna número na linha 1

2. Following the example above, you could do something like this:

var subTotal = 0;
var $linhas = $("#minhaTabela tbody > tr");
// aconselho a usar o tbody na seleção para evitar selecionar o header e o footer

// percorre todas as linhas
$linhas.each(function() {
    // o this refere-se a linha
    var qtd = $(".quantidade", this).html();
    var vlr = $(".valor", this).html();

    // tenta converter para float e retorna 0 caso esteja em branco
    qtd = parseFloat(qtd) || 0;
    vlr = parseFloat(vlr) || 0;

    subTotal += qtd * vlr;
});

$("#subTotal").html(subTotal);

To update the subtotal when adding a line is simple: place the above code in a function and call again whenever necessary.

3. I did not understand your difficulty here, you do not know how to add an autocomplete? Since you already use jQuery, you can use jQueryUI. See the sample page .

    
26.02.2015 / 12:58