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

wqfeng
źródło

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

Brett Zamir
źródło
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>.
vardhan
źródło
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.

Bhavesh Gangani
źródło
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>

ACE Arthur
źródło
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:

user3751006
źródło
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>

bharti parmar
źródło
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>

mathmaniac88
źródło
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>
Mahmoud powiedział
źródło