Jak sprawić, by komórka tabeli HTML była edytowalna?


102

Chciałbym, aby niektóre komórki tabeli html były edytowalne, po prostu kliknij dwukrotnie komórkę, wprowadź tekst, a zmiany zostaną wysłane na serwer. Nie chcę używać niektórych zestawów narzędzi, takich jak siatka danych dojo. Ponieważ zapewnia kilka innych funkcji. Czy możesz podać mi fragment kodu lub porady, jak go zaimplementować?

Odpowiedzi:


116

Możesz użyć atrybutu contenteditable w odpowiednich komórkach, wierszach lub tabeli.

Zaktualizowano pod kątem zgodności z 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>

Zwróć uwagę, że jeśli umożliwisz edycję tabeli, przynajmniej w Mozilli możesz usuwać wiersze itp.

Musisz również sprawdzić, czy przeglądarki docelowych odbiorców obsługują ten atrybut.

Jeśli chodzi o nasłuchiwanie zmian (aby można było wysyłać je na serwer), zobacz treść edytowalnych zdarzeń zmian


Dziękuję Ci. Wygląda na to, że jest obsługiwany w HTML5. Szukam rozwiązania działającego również w html4.
wqfeng

Chociaż ostatecznie jest zakodowany w standardzie w HTML5, był już dobrze obsługiwany w większości starszych przeglądarek (z wyjątkiem tylko częściowego wsparcia w FF3): caniuse.com/contenteditable (choć nie na urządzeniach mobilnych)
Brett Zamir

Świetna wskazówka. Szukałem tego. Dzięki Ci.
praneybehl

Dzięki za wspaniałą poradę.
Prasad Rajapaksha

1
Jeśli potrzebujesz zgodności z IE8, wystarczy dodać element contenteditablediv za każdym razem, gdy tworzysz nowy <td>. W przeciwnym razie, jak wspomniano w poście, możesz dodać contenteditablekomórki, wiersze lub tabelę.
Brett Zamir

61

HTML5 obsługuje treść z możliwością edycji,

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

Edycja zewnętrzna

Cytując wpis mdn na contenteditable

Atrybut musi przyjmować jedną z następujących wartości:

  • true lub pusty ciąg, który wskazuje, że element musi być edytowalny;

  • false, co oznacza, że ​​element nie może być edytowalny.

Jeśli ten atrybut nie jest ustawiony, jego wartość domyślna jest dziedziczona z elementu nadrzędnego.

Ten atrybut jest atrybutem wyliczonym, a nie logicznym. Oznacza to, że jawne użycie jednej z wartości true, false lub pustego łańcucha jest obowiązkowe, a skrót ... jest niedozwolony.

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

// correct usage
<label contenteditable="true">Example Label</label>.

Dziwne. Zwykle wartość atrybutu nie jest true, niezależnie od nazwy. Na przykład <td contenteditable='contenteditable'></td>.
trysis

1
Możliwe stany contenteditable : contenteditable ** = "" lub ** contenteditable ** = "true" Wskazuje, że element można edytować. ** contenteditable ** = "false" Wskazuje, że elementu nie można edytować. ** contenteditable ** = "inherit" Wskazuje, że element jest edytowalny, jeśli jego bezpośredni element nadrzędny jest edytowalny. To jest wartość domyślna. Kiedy dodasz ** contenteditable do elementu, przeglądarka uczyni ten element edytowalnym. Ponadto wszystkie elementy podrzędne tego elementu również będą dostępne do edycji, chyba że elementy podrzędne są wyraźnie ** contenteditable ** = "false".
vardhan,

1
Wiem o tym, po prostu pomyślałem, że to dziwne, ponieważ większość innych atrybutów nie ma takiej składni.
trysis

17

Mam trzy podejścia, tutaj możesz użyć obu <input>lub <textarea>zgodnie ze swoimi wymaganiami.

1. Użyj Input in <td>.

Używanie <input>elementu we wszystkich <td>s,

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

Możesz także zmienić rozmiar wejścia do jego rozmiaru td. dawny.,

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

Możesz dodatkowo zmienić kolor obramowania pola wprowadzania, gdy nie jest ono edytowane.

2. Użyj contenteditable='true'atrybutu. (HTML5)

Jeśli jednak chcesz użyć contenteditable='true', możesz również zapisać odpowiednie wartości w bazie danych. Możesz to osiągnąć dzięki Ajax.

Można dołączyć keyhandlers keyup, keydown, keypressetc do <td>. Ponadto dobrze jest użyć opóźnienia () z tymi zdarzeniami, gdy użytkownik ciągle wpisuje, zdarzenie ajax nie będzie uruchamiane przy każdym naciśnięciu klawisza przez użytkownika. na przykład,

$('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. Dołącz <input>do <td>po kliknięciu.

Dodaj element wejściowy tdpo <td>kliknięciu, zamień jego wartość zgodnie z wartością td's. Kiedy dane wejściowe są zamazane, zmień wartość td na wartość wejścia. Wszystko to za pomocą javascript.


Niestety przegapiłeś część z pytaniem "Jak uczynić komórkę tabeli HTML edytowalną?" szczególnie w przykładzie 2. Użytkownik zapytał, jak to osiągnąć, po dwukrotnym kliknięciu. Czy możesz uprzejmie zaimplementować brakującą część?
Robert,

@BhaveshGangani Mam problem, contenteditable=trueczy możesz mi w tym pomóc?

1
Jasne, że mogę spróbować. Czy masz do tego skrzypce js?
Bhavesh Gangani

6

To jest przykład do uruchomienia.

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



4

Wypróbuj ten kod.

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

Możesz również odwiedzić ten link, aby uzyskać więcej informacji:


Aby uniknąć problemów w IE z $ (this) .children (). First (). Focus (); - stackoverflow.com/a/3562193/5234417
Alexei Zababurin


4

Używam tego do edytowalnego pola

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



3

To jest najważniejsza kwestia, chociaż nie musisz robić tego bałaganu w kodzie. Zamiast tego możesz po prostu iterować przez wszystkie <td>i dodać <input>atrybuty, a na koniec wstawić wartości.

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>


0

to jest rzeczywiście tak proste, to jest mój przykład HTML, jQuery .. i działa jak urok, buduję cały kod, używając próbki danych json online. Twoje zdrowie

<< 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>
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.