Como tornar editável a célula da tabela HTML?

102

Gostaria de tornar editáveis ​​algumas células da tabela html, basta clicar duas vezes em uma célula, inserir algum texto e as alterações podem ser enviadas para o servidor. Não quero usar alguns kits de ferramentas como grade de dados dojo. Porque ele fornece alguns outros recursos. Você poderia me fornecer algum snippet de código ou conselhos sobre como implementá-lo?

wqfeng
fonte

Respostas:

116

Você pode usar o atributo contenteditable nas células, linhas ou tabela em questão.

Atualizado para compatibilidade com o IE8

<table>
<tr><td><div contenteditable>I'm editable</div></td><td><div contenteditable>I'm also editable</div></td></tr>
<tr><td>I'm not editable</td></tr>
</table>

Observe que se você tornar a tabela editável, pelo menos no Mozilla, você pode excluir linhas, etc.

Você também precisa verificar se os navegadores do seu público-alvo suportam esse atributo.

Quanto à escuta das mudanças (para que você possa enviar para o servidor), consulte eventos de mudança editáveis ​​de conteúdo

Brett Zamir
fonte
Obrigado. Parece que a edição de conteúdo é compatível com HTML5. Estou procurando uma solução que funcione em html4 também.
wqfeng
Embora seja finalmente codificado no padrão com HTML5, já era bem suportado na maioria dos navegadores mais antigos (com exceção do suporte apenas parcial em FF3): caniuse.com/contenteditable (embora não em dispositivos móveis)
Brett Zamir
Ótima dica. Eu estava procurando por isso. Te agradece.
praneybehl
Obrigado pela ótima dica.
Prasad Rajapaksha
1
Se você precisa de compatibilidade com o IE8, basta adicionar o contenteditablediv sempre que criar um novo <td>. Caso contrário, conforme mencionado na postagem, você pode adicionar o contenteditablenas células, linhas ou tabela.
Brett Zamir,
61

HTML5 suporta conteúdo editável,

<table border="3">
<thead>
<tr>Heading 1</tr>
<tr>Heading 2</tr>
</thead>
<tbody>
<tr>
<td contenteditable='true'></td>
<td contenteditable='true'></td>
</tr>
<tr>
<td contenteditable='true'></td>
<td contenteditable='true'></td>
</tr>
</tbody>
</table>

Edição de terceiros

Para citar a entrada mdn em contenteditable

O atributo deve ter um dos seguintes valores:

  • true ou a string vazia, que indica que o elemento deve ser editável;

  • false, que indica que o elemento não deve ser editável.

Se este atributo não for definido, seu valor padrão é herdado de seu elemento pai.

Este atributo é enumerado e não booleano. Isso significa que o uso explícito de um dos valores true, false ou a string vazia é obrigatório e que uma abreviação ... não é permitida.

// wrong not allowed
<label contenteditable>Example Label</label> 

// correct usage
<label contenteditable="true">Example Label</label>.
Vardhan
fonte
Esquisito. Normalmente, o valor do atributo não é true, é qualquer que seja o nome. Por exemplo <td contenteditable='contenteditable'></td>,.
trysis
1
Possíveis estados de contenteditable : contenteditable ** = "" ou ** contenteditable ** = "true" Indica que o elemento é editável. ** contenteditable ** = "false" Indica que o elemento não é editável. ** contenteditable ** = "inherit" Indica que o elemento é editável se seu elemento pai imediato for editável. Este é o valor padrão. Quando você adiciona ** contenteditable a um elemento, o navegador tornará esse elemento editável. Além disso, quaisquer filhos desse elemento também se tornarão editáveis, a menos que os elementos filhos sejam explicitamente ** contenteditable ** = "false".
vardhan
1
Eu sei disso, só pensei que era peculiar porque a maioria dos outros atributos não tem essa sintaxe.
trysis de
17

Eu tenho três abordagens, aqui você pode usar ambos <input>ou <textarea>conforme suas necessidades.

1. Use Input in <td>.

Usando o <input>elemento em todos os <td>s,

<tr><td><input type="text"></td>....</tr>

Além disso, você pode querer redimensionar a entrada para o tamanho dela td. ex.,

input { width:100%; height:100%; }

Além disso, você pode alterar a cor da borda da caixa de entrada quando ela não estiver sendo editada.

2. Use o contenteditable='true'atributo. (HTML5)

No entanto, se você deseja usar contenteditable='true', também pode salvar os valores apropriados no banco de dados. Você pode conseguir isso com ajax.

Você pode anexar keyhandlers keyup, keydown, keypressetc à <td>. Além disso, é bom usar algum delay () com esses eventos quando o usuário digita continuamente, o evento ajax não disparará com cada pressionamento de tecla do usuário. por exemplo,

$('table td').keyup(function() {
  clearTimeout($.data(this, 'timer'));
  var wait = setTimeout(saveData, 500); // delay after user types
  $(this).data('timer', wait);
});
function saveData() {
  // ... ajax ...
}

3. Anexe <input>a <td>quando for clicado.

Adicione o elemento de entrada tdao <td>clicar em, substitua seu valor de acordo com o tdvalor de. Quando a entrada estiver borrada, altere o valor de `td's com o valor da entrada. Tudo isso com javascript.

Bhavesh Gangani
fonte
Infelizmente, você perdeu a parte da pergunta "Como tornar editável a célula da tabela HTML?" especialmente no exemplo 2. O usuário perguntou como fazer isso com um clique duplo. Você pode gentilmente implementar a parte que falta?
Robert,
@BhaveshGangani eu tenho algum problema com contenteditable=truevocê pode me ajudar nisso, por favor?
1
Claro que posso tentar. Você tem um violino js para isso?
Bhavesh Gangani
6

Este é um exemplo executável.

$(function(){
  $("td").click(function(event){
    if($(this).children("input").length > 0)
          return false;

    var tdObj = $(this);
    var preText = tdObj.html();
    var inputObj = $("<input type='text' />");
    tdObj.html("");

    inputObj.width(tdObj.width())
            .height(tdObj.height())
            .css({border:"0px",fontSize:"17px"})
            .val(preText)
            .appendTo(tdObj)
            .trigger("focus")
            .trigger("select");

    inputObj.keyup(function(event){
      if(13 == event.which) { // press ENTER-key
        var text = $(this).val();
        tdObj.html(text);
      }
      else if(27 == event.which) {  // press ESC-key
        tdObj.html(preText);
      }
    });

    inputObj.click(function(){
      return false;
    });
  });
});
<html>
    <head>
        <!-- jQuery source -->
        <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
    </head>
    <body>
        <table align="center">
            <tr> <td>id</td> <td>name</td> </tr>
            <tr> <td>001</td> <td>dog</td> </tr>
            <tr> <td>002</td> <td>cat</td> </tr>
            <tr> <td>003</td> <td>pig</td> </tr>
        </table>
    </body>
</html>

ACE Arthur
fonte
4

Experimente este código.

$(function () {
 $("td").dblclick(function () {
    var OriginalContent = $(this).text();

    $(this).addClass("cellEditing");
    $(this).html("<input type="text" value="&quot; + OriginalContent + &quot;" />");
    $(this).children().first().focus();

    $(this).children().first().keypress(function (e) {
        if (e.which == 13) {
            var newContent = $(this).val();
            $(this).parent().text(newContent);
            $(this).parent().removeClass("cellEditing");
        }
    });

 $(this).children().first().blur(function(){
    $(this).parent().text(OriginalContent);
    $(this).parent().removeClass("cellEditing");
 });
 });
});

Você também pode visitar este link para obter mais detalhes:

user3751006
fonte
Para evitar problemas no IE com $ (this) .children (). First (). Focus (); - stackoverflow.com/a/3562193/5234417
Alexei Zababurin
4

Estou usando isso para campo editável

<table class="table table-bordered table-responsive-md table-striped text-center">
  <thead>
    <tr>
      <th class="text-center">Citation</th>
      <th class="text-center">Security</th>
      <th class="text-center">Implementation</th>
      <th class="text-center">Description</th>
      <th class="text-center">Solution</th>
      <th class="text-center">Remove</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td class="pt-3-half" contenteditable="false">Aurelia Vega</td>
      <td class="pt-3-half" contenteditable="false">30</td>
      <td class="pt-3-half" contenteditable="false">Deepends</td>
      <td class="pt-3-half" contenteditable="true"><input type="text" name="add1" value="spain" class="border-none"></td>
      <td class="pt-3-half" contenteditable="true"><input type="text" name="add1" value="marid" class="border-none"></td>
      <td>
        <span class="table-remove"><button type="button"
                              class="btn btn-danger btn-rounded btn-sm my-0">Remove</button></span>
      </td>
    </tr>
  </tbody>
</table>

bharti parmar
fonte
3

Este é o ponto essencial, embora você não precise tornar o código tão confuso. Em vez disso, você pode apenas iterar por meio de todos os <td>e adicionar o <input>com os atributos e, finalmente, inserir os valores.

function edit(el) {
  el.childNodes[0].removeAttribute("disabled");
  el.childNodes[0].focus();
  window.getSelection().removeAllRanges();
}
function disable(el) {
  el.setAttribute("disabled","");
}
<table border>
<tr>
<td ondblclick="edit(this)"><input value="cell1" disabled onblur="disable(this)"></td>
<td ondblclick="edit(this)"><input value="cell2" disabled onblur="disable(this)"></td>
<td ondblclick="edit(this)"><input value="cell3" disabled onblur="disable(this)"></td>
<td ondblclick="edit(this)"><input value="so forth..." disabled onblur="disable(this)">
</td>
</tr>
</table>

mathmaniac88
fonte
0

isso é realmente tão direto, este é meu HTML, amostra jQuery .. e funciona perfeitamente, eu construo todo o código usando uma amostra de dados json online. Felicidades

<< HTML >>

<table id="myTable"></table>

<< jQuery >>

<script>
        var url = 'http://jsonplaceholder.typicode.com/posts';
        var currentEditedIndex = -1;
        $(document).ready(function () {
            $.getJSON(url,
            function (json) {
                var tr;
                tr = $('<tr/>');
                tr.append("<td>ID</td>");
                tr.append("<td>userId</td>");
                tr.append("<td>title</td>");
                tr.append("<td>body</td>");
                tr.append("<td>edit</td>");
                $('#myTable').append(tr);

                for (var i = 0; i < json.length; i++) {
                    tr = $('<tr/>');
                    tr.append("<td>" + json[i].id + "</td>");
                    tr.append("<td>" + json[i].userId + "</td>");
                    tr.append("<td>" + json[i].title + "</td>");
                    tr.append("<td>" + json[i].body + "</td>");
                    tr.append("<td><input type='button' value='edit' id='edit' onclick='myfunc(" + i + ")' /></td>");
                    $('#myTable').append(tr);
                }
            });


        });


        function myfunc(rowindex) {

            rowindex++;
            console.log(currentEditedIndex)
            if (currentEditedIndex != -1) {  //not first time to click
                cancelClick(rowindex)
            }
            else {
                cancelClick(currentEditedIndex)
            }

            currentEditedIndex = rowindex; //update the global variable to current edit location

            //get cells values
            var cell1 = ($("#myTable tr:eq(" + (rowindex) + ") td:eq(0)").text());
            var cell2 = ($("#myTable tr:eq(" + (rowindex) + ") td:eq(1)").text());
            var cell3 = ($("#myTable tr:eq(" + (rowindex) + ") td:eq(2)").text());
            var cell4 = ($("#myTable tr:eq(" + (rowindex) + ") td:eq(3)").text());

            //remove text from previous click


            //add a cancel button
            $("#myTable tr:eq(" + (rowindex) + ") td:eq(4)").append(" <input type='button' onclick='cancelClick("+rowindex+")' id='cancelBtn' value='Cancel'  />");
            $("#myTable tr:eq(" + (rowindex) + ") td:eq(4)").css("width", "200");

            //make it a text box
            $("#myTable tr:eq(" + (rowindex) + ") td:eq(0)").html(" <input type='text' id='mycustomid' value='" + cell1 + "' style='width:30px' />");
            $("#myTable tr:eq(" + (rowindex) + ") td:eq(1)").html(" <input type='text' id='mycustomuserId' value='" + cell2 + "' style='width:30px' />");
            $("#myTable tr:eq(" + (rowindex) + ") td:eq(2)").html(" <input type='text' id='mycustomtitle' value='" + cell3 + "' style='width:130px' />");
            $("#myTable tr:eq(" + (rowindex) + ") td:eq(3)").html(" <input type='text' id='mycustomedit' value='" + cell4 + "' style='width:400px' />");

        }

        //on cancel, remove the controls and remove the cancel btn
        function cancelClick(indx)
        {

            //console.log('edit is at row>> rowindex:' + currentEditedIndex);
            indx = currentEditedIndex;

            var cell1 = ($("#myTable #mycustomid").val());
            var cell2 = ($("#myTable #mycustomuserId").val());
            var cell3 = ($("#myTable #mycustomtitle").val());
            var cell4 = ($("#myTable #mycustomedit").val()); 

            $("#myTable tr:eq(" + (indx) + ") td:eq(0)").html(cell1);
            $("#myTable tr:eq(" + (indx) + ") td:eq(1)").html(cell2);
            $("#myTable tr:eq(" + (indx) + ") td:eq(2)").html(cell3);
            $("#myTable tr:eq(" + (indx) + ") td:eq(3)").html(cell4);
            $("#myTable tr:eq(" + (indx) + ") td:eq(4)").find('#cancelBtn').remove();
        }



    </script>
Mahmoud Sayed
fonte