Wie kann eine HTML-Tabellenzelle bearbeitet werden?

102

Ich möchte einige Zellen der HTML-Tabelle bearbeitbar machen, einfach auf eine Zelle doppelklicken, Text eingeben und die Änderungen können an den Server gesendet werden. Ich möchte einige Toolkits wie das Dojo-Datenraster nicht verwenden. Weil es einige andere Funktionen bietet. Würden Sie mir ein Code-Snippet oder Ratschläge zur Implementierung geben?

wqfeng
quelle

Antworten:

116

Sie können das Attribut contenteditable für die betreffenden Zellen, Zeilen oder Tabellen verwenden.

Aus Gründen der IE8-Kompatibilität aktualisiert

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

Beachten Sie nur, dass Sie Zeilen usw. löschen können, wenn Sie die Tabelle bearbeitbar machen, zumindest in Mozilla.

Sie müssen auch überprüfen, ob die Browser Ihrer Zielgruppe dieses Attribut unterstützen.

Informationen zum Abhören der Änderungen (damit Sie diese an den Server senden können) finden Sie unter Inhaltsbearbeitbare Änderungsereignisse

Brett Zamir
quelle
Danke dir. Es scheint, dass contenteditable in HTML5 unterstützt wird. Ich suche nach einer Lösung, die auch in HTML4 funktioniert.
wqfeng
Obwohl es endgültig im Standard mit HTML5 kodifiziert ist, wurde es in den meisten älteren Browsern bereits gut unterstützt (mit Ausnahme der nur teilweisen Unterstützung in FF3): caniuse.com/contenteditable (jedoch nicht auf Mobilgeräten)
Brett Zamir
Toller Tipp. Ich habe danach gesucht. Danke.
Praneybehl
Danke für den tollen Tipp.
Prasad Rajapaksha
1
Wenn Sie IE8-Kompatibilität benötigen, müssen Sie das contenteditablediv nur hinzufügen, wenn Sie ein neues erstellen <td>. Andernfalls können Sie, wie im Beitrag erwähnt, contenteditabledie Zellen, Zeilen oder Tabellen hinzufügen .
Brett Zamir
61

HTML5 unterstützt inhaltsbearbeitbare,

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

Bearbeitung durch Dritte

Um den MDN-Eintrag auf contenteditable zu zitieren

Das Attribut muss einen der folgenden Werte annehmen:

  • true oder die leere Zeichenfolge, die angibt, dass das Element bearbeitet werden muss;

  • false, was darauf hinweist, dass das Element nicht bearbeitet werden darf.

Wenn dieses Attribut nicht festgelegt ist, wird sein Standardwert von seinem übergeordneten Element geerbt.

Dieses Attribut ist aufgezählt und kein boolesches. Dies bedeutet, dass die explizite Verwendung eines der Werte true, false oder der leeren Zeichenfolge obligatorisch ist und eine Kurzform ... nicht zulässig ist.

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

// correct usage
<label contenteditable="true">Example Label</label>.
Vardhan
quelle
Seltsam. Normalerweise ist der Attributwert nicht true, sondern der Name. Zum Beispiel <td contenteditable='contenteditable'></td>.
Tryse
1
Mögliche Zustände von contenteditable : contenteditable ** = "" oder ** contenteditable ** = "true" Gibt an, dass das Element bearbeitet werden kann. ** contenteditable ** = "false" Gibt an, dass das Element nicht bearbeitet werden kann. ** contenteditable ** = "erben" Gibt an, dass das Element bearbeitet werden kann, wenn sein unmittelbares übergeordnetes Element bearbeitet werden kann. Dies ist der Standardwert. Wenn Sie einem Element ** contenteditable hinzufügen , macht der Browser dieses Element bearbeitbar. Darüber hinaus können alle untergeordneten Elemente dieses Elements bearbeitet werden, es sei denn, die untergeordneten Elemente sind explizit ** contenteditable ** = "false".
Vardhan
1
Ich weiß das, ich dachte nur, dass es eigenartig ist, weil die meisten anderen Attribute diese Syntax nicht haben.
Tryse
17

Ich habe drei Ansätze. Hier können Sie beide <input>oder <textarea>gemäß Ihren Anforderungen verwenden.

1. Verwenden Sie Input in <td>.

Mit <input>Elemente in allen <td>s,

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

Möglicherweise möchten Sie auch die Größe der Eingabe auf die Größe ändern td. Ex.,

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

Sie können zusätzlich die Farbe des Rahmens des Eingabefelds ändern, wenn es nicht bearbeitet wird.

2. Verwenden Sie das contenteditable='true'Attribut. (HTML5)

Wenn Sie jedoch verwenden möchten, möchten contenteditable='true'Sie möglicherweise auch die entsprechenden Werte in der Datenbank speichern. Sie können dies mit Ajax erreichen.

Sie können keyhandlers befestigen keyup, keydown, keypressetc zu der <td>. Es ist auch gut, bei diesen Ereignissen eine Verzögerung () zu verwenden, wenn der Benutzer kontinuierlich tippt. Das Ajax-Ereignis wird nicht bei jedem Tastendruck ausgelöst. beispielsweise,

$('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. Anhängen <input>an, <td>wenn darauf geklickt wird.

Fügen Sie das Eingabeelement hinzu, tdwenn Sie auf <td>klicken, und ersetzen Sie seinen Wert durch den tdWert des. Wenn die Eingabe unscharf ist, ändern Sie den Wert von `td mit dem Wert der Eingabe. All dies mit Javascript.

Bhavesh Gangani
quelle
Leider haben Sie den Fragenteil "Wie kann man HTML-Tabellenzellen bearbeitbar machen?" Verpasst. insbesondere in Beispiel 2. Der Benutzer fragte, wie dies durch Doppelklick erreicht werden kann. Können Sie bitte das fehlende Teil implementieren?
Robert
@ BhaveshGangani Ich habe ein Problem mit. Kannst contenteditable=truedu mir bitte dabei helfen?
1
Klar kann ich es versuchen. Hast du eine Geige dafür?
Bhavesh Gangani
6

Dies ist ein lauffähiges Beispiel.

$(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
quelle
4

Versuchen Sie diesen 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");
 });
 });
});

Sie können diesen Link auch für weitere Details besuchen:

user3751006
quelle
Um Probleme im IE mit $ (this) .children (). First (). Focus () zu vermeiden; - stackoverflow.com/a/3562193/5234417
Alexei Zababurin
4

Fügen Sie das <input>Element einfach <td>dynamisch ein, wenn Sie auf die Zelle klicken. Nur einfaches HTML und Javascript. Keine Notwendigkeit für contentEditable, jquery,HTML5

https://Jsfiddle.net/gsivanov/38tLqobw/2/

gsivanov
quelle
4

Ich benutze dies für bearbeitbare Felder

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

Dies ist der wesentliche Punkt, obwohl Sie den Code nicht so chaotisch machen müssen. Stattdessen können Sie einfach alle durchlaufen <td>und die <input>mit den Attributen hinzufügen und schließlich die Werte eingeben.

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

Das ist eigentlich so einfach, das ist mein HTML-, jQuery-Beispiel. Und es funktioniert wie ein Zauber. Ich erstelle den gesamten Code mithilfe eines Online-JSON-Datenbeispiels. Prost

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