Comment rendre une cellule de tableau HTML modifiable?

102

Je voudrais rendre certaines cellules du tableau html modifiables, double-cliquez simplement sur une cellule, saisissez du texte et les modifications peuvent être envoyées au serveur. Je ne veux pas utiliser certaines boîtes à outils comme la grille de données dojo. Parce qu'il fournit d'autres fonctionnalités. Pourriez-vous me fournir un extrait de code ou des conseils sur la façon de l'implémenter?

wqfeng
la source

Réponses:

116

Vous pouvez utiliser l'attribut contenteditable sur les cellules, les lignes ou le tableau en question.

Mise à jour pour la compatibilité 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>

Notez simplement que si vous rendez la table modifiable, dans Mozilla au moins, vous pouvez supprimer des lignes, etc.

Vous devez également vérifier si les navigateurs de votre public cible prennent en charge cet attribut.

En ce qui concerne l'écoute des modifications (afin que vous puissiez les envoyer au serveur), consultez les événements de modification contenteditable

Brett Zamir
la source
Je vous remercie. Il semble que contenteditable soit pris en charge dans HTML5. Je recherche une solution qui fonctionne aussi en html4.
wqfeng
Bien qu'il soit finalement codifié dans le standard avec HTML5, il était déjà bien pris en charge dans la plupart des navigateurs plus anciens (à l'exception d'un support partiel dans FF3): caniuse.com/contenteditable (mais pas dans les appareils mobiles)
Brett Zamir
Bon conseil. Je le cherchais. Merci.
praneybehl
Merci pour le bon conseil.
Prasad Rajapaksha le
1
Si vous avez besoin de la compatibilité IE8, il vous suffit d'ajouter le contenteditablediv chaque fois que vous créez un nouveau fichier <td>. Sinon, comme mentionné dans l'article, vous pouvez ajouter le contenteditablesur les cellules, les lignes ou le tableau.
Brett Zamir
61

HTML5 prend en charge contenteditable,

<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>

Modification tierce

Pour citer l' entrée mdn sur contenteditable

L'attribut doit prendre l'une des valeurs suivantes:

  • true ou la chaîne vide, qui indique que l'élément doit être modifiable;

  • false, ce qui indique que l'élément ne doit pas être modifiable.

Si cet attribut n'est pas défini, sa valeur par défaut est héritée de son élément parent.

Cet attribut est énuméré et non booléen. Cela signifie que l'utilisation explicite de l'une des valeurs true, false ou de la chaîne vide est obligatoire et qu'un raccourci ... n'est pas autorisé.

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

// correct usage
<label contenteditable="true">Example Label</label>.
vardhan
la source
Bizarre. Habituellement, la valeur de l'attribut n'est pas true, c'est quel que soit le nom. Par exemple <td contenteditable='contenteditable'></td>,.
trysis
1
États possibles de contenteditable : contenteditable ** = "" ou ** contenteditable ** = "true" Indique que l'élément est modifiable. ** contenteditable ** = "false" Indique que l'élément n'est pas modifiable. ** contenteditable ** = "inherit" Indique que l'élément est modifiable si son élément parent immédiat est modifiable. Ceci est la valeur par défault. Lorsque vous ajoutez ** contenteditable à un élément, le navigateur rend cet élément modifiable. En outre, tous les enfants de cet élément deviendront également modifiables à moins que les éléments enfants ne soient explicitement ** contenteditable ** = "false".
vardhan
1
Je le sais, je pensais juste que c'était particulier parce que la plupart des autres attributs n'ont pas cette syntaxe.
trysis
17

J'ai trois approches, ici vous pouvez utiliser les deux <input>ou <textarea>selon vos besoins.

1. Utilisez Input in <td>.

Utilisation de l' <input>élément dans tous les <td>s,

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

Vous pouvez également redimensionner l'entrée à la taille de son td. ex.,

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

Vous pouvez en outre modifier la couleur de la bordure de la zone de saisie lorsqu'elle n'est pas en cours de modification.

2. Utilisez l' contenteditable='true'attribut. (HTML5)

Toutefois, si vous souhaitez utiliser contenteditable='true', vous pouvez également enregistrer les valeurs appropriées dans la base de données. Vous pouvez y parvenir avec ajax.

Vous pouvez joindre keyhandlers keyup, keydown, keypressetc au <td>. En outre, il est bon d'utiliser un délai () avec ces événements lorsque l'utilisateur tape en continu, l'événement ajax ne se déclenchera pas à chaque pression de l'utilisateur clé. par exemple,

$('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. Ajoutez <input>à <td>quand vous cliquez dessus.

Ajoutez l 'élément d' entrée dans tdlorsque vous <td>cliquez sur, remplacez sa valeur en fonction de la tdvaleur de s. Lorsque l'entrée est floue, changez la valeur de `td avec la valeur de l'entrée. Tout cela avec javascript.

Bhavesh Gangani
la source
Malheureusement, vous avez manqué la partie de la question "Comment rendre une cellule de tableau HTML modifiable?" en particulier dans l'exemple 2. L'utilisateur a demandé comment y parvenir en double-clic. Pouvez-vous gentiment mettre en œuvre la partie manquante?
Robert
@BhaveshGangani j'ai un problème avec contenteditable=truepouvez-vous m'aider s'il vous plaît?
1
Bien sûr, je peux essayer. Avez-vous un violon js pour ça?
Bhavesh Gangani du
6

Ceci est un exemple exécutable.

$(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
la source
4

Essayez ce code.

$(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");
 });
 });
});

Vous pouvez également visiter ce lien pour plus de détails:

user3751006
la source
Pour éviter les problèmes dans IE avec $ (this) .children (). First (). Focus (); - stackoverflow.com/a/3562193/5234417
Alexei Zababurin
4

J'utilise ceci pour un champ modifiable

<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
la source
3

C'est le point essentiel bien que vous n'ayez pas besoin de rendre le code aussi compliqué. Au lieu de cela, vous pouvez simplement parcourir tous les <td>et ajouter les <input>avec les attributs et enfin mettre les valeurs.

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
la source
0

c'est en fait si simple, c'est mon HTML, exemple jQuery .. et cela fonctionne comme un charme, je construis tout le code en utilisant un échantillon de données json en ligne. à votre santé

<< 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
la source