วิธีทำให้เซลล์ตาราง HTML สามารถแก้ไขได้?


105

ฉันต้องการทำให้เซลล์บางส่วนของตาราง html สามารถแก้ไขได้เพียงดับเบิลคลิกที่เซลล์ป้อนข้อความและสามารถส่งการเปลี่ยนแปลงไปยังเซิร์ฟเวอร์ได้ ฉันไม่ต้องการใช้ชุดเครื่องมือบางอย่างเช่นตารางข้อมูล dojo เนื่องจากมีคุณสมบัติอื่น ๆ คุณช่วยให้ข้อมูลโค้ดหรือคำแนะนำเกี่ยวกับวิธีใช้งานได้หรือไม่

คำตอบ:


121

คุณสามารถใช้แอตทริบิวต์ contenteditable ในเซลล์แถวหรือตารางที่เป็นปัญหา

อัปเดตสำหรับความเข้ากันได้กับ 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>

โปรดทราบว่าถ้าคุณทำให้ตารางสามารถแก้ไขได้อย่างน้อยใน Mozilla คุณสามารถลบแถว ฯลฯ

คุณต้องตรวจสอบด้วยว่าเบราว์เซอร์ของกลุ่มเป้าหมายของคุณรองรับแอตทริบิวต์นี้หรือไม่

เท่าที่รับฟังการเปลี่ยนแปลง (เพื่อให้คุณสามารถส่งไปยังเซิร์ฟเวอร์ได้) โปรดดูเหตุการณ์การเปลี่ยนแปลงที่สามารถแก้ไขได้


ขอบคุณ. ดูเหมือนว่า contenteditable ได้รับการสนับสนุนใน HTML5 ฉันกำลังมองหาวิธีแก้ปัญหาที่ใช้งานได้ใน html4 ด้วย
wqfeng

แม้ว่าสุดท้ายแล้วจะได้รับการเข้ารหัสในมาตรฐานด้วย HTML5 แต่ก็ได้รับการสนับสนุนอย่างดีในเบราว์เซอร์รุ่นเก่าส่วนใหญ่ (ยกเว้นการสนับสนุนเพียงบางส่วนใน FF3): caniuse.com/contenteditable (แม้ว่าจะไม่ได้อยู่ในอุปกรณ์พกพา)
Brett Zamir

เคล็ดลับที่ดี ฉันกำลังมองหามัน ขอบคุณ.
praneybehl

ขอบคุณสำหรับเคล็ดลับดีๆ
ปราสาทราชภั

1
หากคุณต้องการความเข้ากันได้กับ IE8 คุณก็ต้องเพิ่มcontenteditablediv ทุกครั้งที่คุณสร้างไฟล์<td>. มิฉะนั้นดังที่กล่าวไว้ในโพสต์คุณสามารถเพิ่มcontenteditableเซลล์แถวหรือตารางได้
Brett Zamir

65

HTML5 รองรับเนื้อหาที่แก้ไขได้

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

บุคคลที่สามแก้ไข

เพื่ออ้างรายการ mdn บน contenteditable

แอตทริบิวต์ต้องใช้ค่าใดค่าหนึ่งต่อไปนี้:

  • จริงหรือสตริงว่างซึ่งระบุว่าองค์ประกอบต้องแก้ไขได้

  • เท็จซึ่งบ่งชี้ว่าองค์ประกอบต้องไม่สามารถแก้ไขได้

หากไม่ได้ตั้งค่าแอตทริบิวต์นี้ค่าเริ่มต้นจะสืบทอดมาจากองค์ประกอบหลัก

แอตทริบิวต์นี้เป็นแอตทริบิวต์ที่แจกแจงและไม่ใช่แบบบูลีน ซึ่งหมายความว่าจำเป็นต้องมีการใช้ค่าหนึ่งในค่าจริงเท็จหรือสตริงว่างอย่างชัดเจนและไม่อนุญาตให้ใช้ชวเลข ...

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

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

แปลก. โดยปกติค่าแอตทริบิวต์จะไม่ใช่trueชื่ออะไรก็ตาม ตัวอย่างเช่น<td contenteditable='contenteditable'></td>.
trysis

1
สถานะที่เป็นไปได้ของcontenteditable : contenteditable ** = "" หรือ ** contenteditable ** = "true" แสดงว่าองค์ประกอบนั้นแก้ไขได้ ** contenteditable ** = "false" แสดงว่าองค์ประกอบนั้นไม่สามารถแก้ไขได้ ** contenteditable ** = "inherit" ระบุว่าองค์ประกอบสามารถแก้ไขได้หากองค์ประกอบหลักในทันทีสามารถแก้ไขได้ นี่คือค่าเริ่มต้น เมื่อคุณเพิ่ม ** contenteditableให้กับองค์ประกอบเบราว์เซอร์จะทำให้องค์ประกอบนั้นแก้ไขได้ นอกจากนี้ลูก ๆ ขององค์ประกอบนั้นจะสามารถแก้ไขได้ด้วยเว้นแต่ว่าองค์ประกอบลูกนั้นมีความชัดเจน ** contenteditable ** = "false"
vardhan

1
ฉันรู้ว่าฉันแค่คิดว่ามันแปลกเพราะแอตทริบิวต์อื่น ๆ ส่วนใหญ่ไม่มีไวยากรณ์นั้น
trysis

18

ฉันมีสามวิธีที่นี่คุณสามารถใช้ได้ทั้งสองอย่าง<input>หรือ<textarea>ตามความต้องการของคุณ

1. <td>ใช้การป้อนข้อมูลใน

การใช้<input>องค์ประกอบในทุก<td>วินาที

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

นอกจากนี้คุณอาจต้องการปรับขนาดอินพุตเป็นขนาดtdไฟล์. เช่น

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

คุณสามารถเปลี่ยนสีของเส้นขอบของช่องป้อนข้อมูลเพิ่มเติมได้เมื่อไม่มีการแก้ไข

2. ใช้contenteditable='true'แอตทริบิวต์ (HTML5)

อย่างไรก็ตามหากคุณต้องการใช้contenteditable='true'คุณอาจต้องการบันทึกค่าที่เหมาะสมลงในฐานข้อมูล คุณสามารถบรรลุสิ่งนี้ได้ด้วย ajax

คุณสามารถแนบ keyhandlers keyup, keydown, keypressฯลฯ <td>ไป นอกจากนี้ควรใช้การหน่วงเวลา ()กับเหตุการณ์เหล่านั้นเมื่อผู้ใช้พิมพ์อย่างต่อเนื่องเหตุการณ์ ajax จะไม่เริ่มทำงานเมื่อผู้ใช้กดปุ่มทุกครั้ง ตัวอย่างเช่น,

$('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. ผนวก<input>ไป<td>เมื่อมีการคลิก

เพิ่มองค์ประกอบอินพุตtdเมื่อ<td>คลิกแทนที่ค่าตามtdค่าของ เมื่ออินพุตเบลอให้เปลี่ยนค่าของ "td ด้วยค่าของอินพุต ทั้งหมดนี้ด้วยจาวาสคริปต์


น่าเสียดายที่คุณพลาดคำถามส่วน "วิธีทำให้เซลล์ตาราง HTML แก้ไขได้" โดยเฉพาะอย่างยิ่งในตัวอย่างที่ 2 ผู้ใช้ถามว่าจะบรรลุสิ่งนี้ได้อย่างไรใน doubleclick คุณช่วยนำส่วนที่ขาดหายไปใช้งานได้ไหม
Robert

@BhaveshGangani ฉันมีปัญหาบางอย่างcontenteditable=trueคุณสามารถช่วยฉันในเรื่องนี้ได้ไหม

1
แน่นอนว่าฉันสามารถลองได้ คุณมีซอ js สำหรับสิ่งนั้นหรือไม่?
Bhavesh Gangani

7

นี่คือตัวอย่างที่รันได้

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

ลองใช้รหัสนี้

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

คุณสามารถเยี่ยมชมลิงค์นี้เพื่อดูรายละเอียดเพิ่มเติม:


เพื่อหลีกเลี่ยงปัญหาใน IE ด้วย $ (this) .children (). first (). focus (); - stackoverflow.com/a/3562193/5234417
Alexei Zababurin


4

ฉันใช้สิ่งนี้สำหรับฟิลด์ที่แก้ไขได้

<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

หากคุณใช้ Jquery ปลั๊กอินนี้จะช่วยให้คุณง่าย แต่เป็นสิ่งที่ดี

https://github.com/samuelsantosdev/TableEdit


2
ดูเหมือนปลั๊กอินที่น่าสนใจ เอกสารสำหรับวิธีการใช้งานสามารถพบได้ในไฟล์ index.html โปรดดูที่meta.stackexchange.com/questions/8231/…เพื่อดูว่าเหตุใดจึงมีข้อมูลมากกว่าลิงก์เพียงอย่างเดียวเพื่อให้ได้คำตอบที่ดีกว่า
Jason Aller

3

นี่เป็นจุดสำคัญแม้ว่าคุณจะไม่จำเป็นต้องทำให้โค้ดยุ่งขนาดนี้ แต่คุณสามารถทำซ้ำทุก ๆ<td>และเพิ่ม<input>แอตทริบิวต์และสุดท้ายใส่ค่า

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

นี่คือสิ่งที่ตรงไปตรงมานี่คือ HTML ตัวอย่าง jQuery ของฉัน .. และมันใช้งานได้ดีฉันสร้างโค้ดทั้งหมดโดยใช้ตัวอย่างข้อมูล json ออนไลน์ ไชโย

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

0

เพิ่ม<input>ไป<td>เมื่อมีการคลิก เปลี่ยน<input>เป็น<span>เมื่อเบลอ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.