Pivot table with row and column addition

2

Is it possible to create a table with the addition of rows and columns? According to the image, the situation is: - Start a table with 3 columns and a row; - Considering that the first line and the first column would have to be editable (being possible for the user to type in it); - Inside the empty lines would bring radio button;

Now comes the part that I can not find a solution: - When you click the + button on the horizontal you will add one more column (at most 5 columns); - When you click the + button on the vertical you will add one more line; - And they must always be beating the column with the lines, as the example in the image.

Is it possible to make such a dynamic table?

    
asked by anonymous 14.06.2017 / 22:38

3 answers

5

You will have some challenges to solve, such as correctly identifying the "radio buttons" for each question, but I leave a code for suggestion.

//Adiciona linhas
$(".add-row").click(function () {
    if ($('.row-title').val() == '') {
        alert('Digite o título da pergunta');
        return;
    }

    if ($("#pergunta tbody tr td").length) {
        //clona a última linha
        $tr = $("#pergunta tbody tr:last-child").clone(true);
        var index = $("#pergunta tbody tr").length;
        var name = 'rd[' + (index + 1) + ']';
        //altera o nome e a propriedade checked do input
        $tr.find('td').children('input').attr('name', name).prop('checked', false);
        //altera o texto da primeira célula com o valor do input
        $tr.children('td:first-child').text($('.row-title').val());
        //adiciona no corpo da tabela
        $("#pergunta tbody").append($tr);
    } else {
        $("#pergunta tbody tr").append('<td>' + $('.row-title').val() + '</td>');
    }

});
//Adiciona colunas
$(".add-col").click(function () {

    if ($("#pergunta tbody tr td").length) {

        if ($('.col-title').val() == '') {
            alert('Digite a resposta');
            return;
        }

        var qtdMax = 5;//quantidade máxima de colunas
        if ($("#pergunta thead tr th").length < qtdMax) {
            //adiciona nova coluna com o texto do input
            $("#pergunta thead tr").append('<th>' + $('.col-title').val() + '</th>');
            //percorre cada linha do corpo da tabela
            $("#pergunta tbody tr").each(function () {
                //verifica o nome dos inputs da linha correspondente
                var name = 'rd[' + ($(this).index() + 1) + ']';
                //adiciona o input na coluna
                $(this).append('<td><input type="radio" name="' + name + '"></td>');
            });
        }
    } else {
        alert('Adicione a primeira pergunta antes de adicionar respostas!');
    }


});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><tableborder="1" id="pergunta">
    <thead>
        <tr>
            <th></th>
        </tr>
    </thead>
    <tbody>
        <tr>

        </tr>
    </tbody>
</table>
<div>

</div>
<p>
    <input type="text" class="row-title" />
    <button type="button" class="add-row">
        + Pergunta
    </button>
</p>
<p>
    <input type="text" class="col-title" />
    <button type="button" class="add-col">
        + Resposta
    </button>

</p>
    
14.06.2017 / 22:58
3

First advice I give you, if you really need something so dynamic, jQUery is not the path, try VueJS .

Below is a complete example, see that manipulating the table is not so painful.

var app = new Vue({
  el: '#tabela',
  data: {
    respostas: [ 
      { texto: 'Sim' }, 
      { texto: 'Não' } 
    ],
    perguntas: [
      { 
        texto: 'Pergunta 1', 
        respostas: [ 
          { selecionado: false }, 
          { selecionado: false } 
        ] 
      }
    ]
  },
  methods: {
    addResposta: function (event) {
      var count = this.respostas.length + 1;
      if (count <= 5) {
        this.respostas.push({ texto: 'Resposta ' + count });
        this.perguntas.forEach(function (pergunta) {
          pergunta.respostas.push({ selecionado: false });
        })
      } else {
        alert('Não é possivel adicionar mais que 5 perguntas');
      }
    },
    delResposta: function (indice) {
      this.respostas.splice(indice, 1);
      this.perguntas.forEach(function (pergunta) {
        pergunta.respostas.splice(indice, 1);
      })
    },
    addPergunta: function (event) {
      var count = this.perguntas.length + 1;
      var respostas = this.respostas.map(function () {
        return { selecionado: false };
      })
      this.perguntas.push({ 
        texto: 'Pergunta ' + count,
        respostas: respostas
      });
    },
    delPergunta: function (indice) {
      this.perguntas.splice(indice, 1);
    }
  }
})
.resposta {
  white-space: nowrap;
}
.resposta input[type='text'] {
  width: 75px;
}

.pergunta {
  width: 150px;
}

.padrao {
  width: 75px;
}

input {
  box-sizing: border-box;
}

input[type='radio'] {
  text-align: center;
  width: 75px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.3.4/vue.js"></script><tableid="tabela">
  <thead>
    <tr>
      <th></th>
      <th v-bind:colspan="respostas.length">Respostas</th>
      <th></th>
    </tr>
    <tr>
      <th>Perguntas</th>
      <th v-for="(resposta, indice) in respostas" class="resposta">
        <input type="text" class="resposta" v-model="resposta.texto" />
        <input type="button" value="X" v-on:click="delResposta(indice)" />
      </th>
      <th>
        <input type="button" class="padrao" value="Adicionar" v-on:click="addResposta" />
      </th>
    </tr>
  </thead>
  <tbody>
    <tr v-for="(pergunta, indice) in perguntas">
      <td>
        <input type="text" class="pergunta" v-model="pergunta.texto" />
      </td>
      <td v-for="resposta in pergunta.respostas">
        <input type="radio" v-bind:name="'resposta' + indice" class="resposta" v-model="resposta.selecionado" />
      </td>
      <td>
        <input type="button" class="padrao" value="Remover" v-on:click="delPergunta(indice)" />
      </td>
    </tr>
  </tbody>
  <tfoot>
    <tr>
      <td>
        <input type="button" class="pergunta" value="Adicionar Pergunta" v-on:click="addPergunta" />
      </td>
      <th v-bind:colspan="respostas.length"></th>
      <td>
        <input type="button" class="padrao" value="Salvar" />
      </td>
    </tr>
  </tfoot>
</table>
    
15.06.2017 / 22:15
2

function myFunction() {
    var table = document.getElementById("myTable");
    var row = table.insertRow(0);
    var cell1 = row.insertCell(0);
    var cell2 = row.insertCell(1);
    cell1.innerHTML = "NEW CELL1";
    cell2.innerHTML = "<input type='text' >";
}
<table id="myTable">
  <tr>
    <td>Row1 cell1</td>
    <td>Row1 cell2</td>
  </tr>
  <tr>
    <td>Row2 cell1</td>
    <td>Row2 cell2</td>
  </tr>
  <tr>
    <td>Row3 cell1</td>
    <td>Row3 cell2</td>
  </tr>
</table>
<br>

<button onclick="myFunction()">Try it</button>

Hello, I believe that this is the path to what you are looking for, a button and your table will automatically go by the click of the button being changed.

    
14.06.2017 / 23:02