如何使 HTML 表格单元格可编辑?

发布于 2024-11-07 02:31:43 字数 119 浏览 1 评论 0原文

我想让 html 表格的某些单元格可编辑,只需双击单元格,输入一些文本,所做的更改就可以发送到服务器。我不想使用一些像dojo数据网格这样的工具包。因为它提供了一些其他功能。您能为我提供一些代码片段或有关如何实现它的建议吗?

I'd like to make some cells of html table editable, simply double click a cell, input some text and the changes can be sent to server. I don't want to use some toolkits like dojo data grid. Because it provides some other features. Would you provide me some code snippet or advices on how to implement it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(14

千年*琉璃梦 2024-11-14 02:31:43

您可以在相关单元格、行或表格上使用 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 更改事件

You can use the contenteditable attribute on the cells, rows, or table in question.

Updated for IE8 compatibility

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

Just note that if you make the table editable, in Mozilla at least, you can delete rows, etc.

You'd also need to check whether your target audience's browsers supported this attribute.

As far as listening for the changes (so you can send to the server), see contenteditable change events

月棠 2024-11-14 02:31:43

HTML5 支持 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>

第三方编辑

引用 contenteditable 上的 mdn 条目< /a>

该属性必须采用以下值之一:

  • true 或空字符串,表示该元素必须可编辑;

  • false,表示该元素不可编辑。

如果未设置此属性,则其默认值将从其继承
父元素。

该属性是一个枚举属性,而不是布尔属性。这意味着
显式使用值 true、false 或空之一
字符串是强制性的,并且不允许使用简写...。

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

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

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

3rd party edit

To quote the mdn entry on contenteditable

The attribute must take one of the following values:

  • true or the empty string, which indicates that the element must be editable;

  • false, which indicates that the element must not be editable.

If this attribute is not set, its default value is inherited from its
parent element.

This attribute is an enumerated one and not a Boolean one. This means
that the explicit usage of one of the values true, false or the empty
string is mandatory and that a shorthand ... is not allowed.

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

// correct usage
<label contenteditable="true">Example Label</label>.
是你 2024-11-14 02:31:43

我有三种方法,
在这里,您可以根据您的要求使用

1.在 中使用输入。

在所有 中使用 元素,

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

此外,您可能想要将输入的大小调整为其 td 的大小。例如,

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

您还可以在未编辑时更改输入框边框的颜色。

2.使用 contenteditable='true' 属性。 (HTML5)

但是,如果您想要使用 contenteditable='true',您可能还需要将适当的值保存到数据库中。您可以使用 ajax 来实现这一点。

您可以将按键处理程序 keyupkeydownkeypress 等附加到 。另外,当用户连续键入,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。单击时将

附加到 。 >被点击,根据td的值替换它的值。当输入模糊时,用输入的值更改 td 的值。这一切都通过 JavaScript 完成。

I have three approaches,
Here you can use both <input> or <textarea> as per your requirements.

1. Use Input in <td>.

Using <input> element in all <td>s,

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

Also, you might want to resize the input to the size of its td. ex.,

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

You can additionally change the colour of the border of the input box when it is not being edited.

2. Use contenteditable='true' attribute. (HTML5)

However, if you want to use contenteditable='true', you might also want to save the appropriate values to the database. You can achieve this with ajax.

You can attach keyhandlers keyup, keydown, keypress etc to the <td>. Also, it is good to use some delay() with those events when user continuously types, the ajax event won't fire with every key user press. for example,

$('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. Append <input> to <td> when it is clicked.

Add the input element in td when the <td> is clicked, replace its value according to the td's value. When the input is blurred, change the `td's value with the input's value. All this with javascript.

緦唸λ蓇 2024-11-14 02:31:43

这是一个可运行的示例。

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

This is a runnable example.

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

山色无中 2024-11-14 02:31:43

我将其用于可编辑字段

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

I am using this for editable field

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

掌心的温暖 2024-11-14 02:31:43

您可以使用 x-editable https://vitalets.github.io/x-editable/
来自 bootstrap 的很棒的库

You can use x-editable https://vitalets.github.io/x-editable/
its awesome library from bootstrap

灯下孤影 2024-11-14 02:31:43

只需在单击单元格时动态地将 元素插入 中。只有简单的 HTML 和 Javascript。不需要 contentEditablejqueryHTML5

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

Just insert <input> element in <td> dynamically, on cell click. Only simple HTML and Javascript. No need for contentEditable , jquery, HTML5

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

一身软味 2024-11-14 02:31:43

试试这个代码。

$(function () {
 $("td").dblclick(function () {
    var OriginalContent = $(this).text();

    $(this).addClass("cellEditing");
    $(this).html("<input type="text" value="" + OriginalContent + "" />");
    $(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");
 });
 });
});

您还可以访问此链接了解更多详细信息:

Try this code.

$(function () {
 $("td").dblclick(function () {
    var OriginalContent = $(this).text();

    $(this).addClass("cellEditing");
    $(this).html("<input type="text" value="" + OriginalContent + "" />");
    $(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");
 });
 });
});

You can also visit this link for more details :

洛阳烟雨空心柳 2024-11-14 02:31:43

这是要点,尽管您不需要使代码如此混乱。相反,您可以迭代所有 并添加带有属性的 ,最后输入值。

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>

This is the essential point although you don't need to make the code this messy. Instead you could just iterate through all the <td> and add the <input> with the attributes and finally put in the values.

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>

笑饮青盏花 2024-11-14 02:31:43

如果你使用Jquery,这个插件可以帮助你
很简单,但是很好

https://github.com/samuelsantosdev/TableEdit

If you use Jquery, this plugin help you
is simple, but is good

https://github.com/samuelsantosdev/TableEdit

丶情人眼里出诗心の 2024-11-14 02:31:43

要设置单元格可编辑,您可以使用此关键字“contenteditable”
这是一个例子

tr td {
  border: solid 2px black
}
<table>
  <tr>
    <td contenteditable>CELL EDITABLE</td><!--CELL EDITABLE-->
    <td contenteditable>CELL EDITABLE</td><!--CELL EDITABLE-->
  </tr>
  <tr>
    <td>CELL NOT EDITABLE</td> 
    <td>CELL NOT EDITABLE</td>
  </tr>
</table>

FOR SET A CELL EDITABLE YOU CAN USE THIS KEYWORD "contenteditable"
THIS IS AN EXAMPLE

tr td {
  border: solid 2px black
}
<table>
  <tr>
    <td contenteditable>CELL EDITABLE</td><!--CELL EDITABLE-->
    <td contenteditable>CELL EDITABLE</td><!--CELL EDITABLE-->
  </tr>
  <tr>
    <td>CELL NOT EDITABLE</td> 
    <td>CELL NOT EDITABLE</td>
  </tr>
</table>

留一抹残留的笑 2024-11-14 02:31:43

这实际上很简单,
这是我的 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>

this is actually so straight forward,
this is my HTML, jQuery sample.. and it works like a charm, I build all the code using an online json data sample.
cheers

<< 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>
南风几经秋 2024-11-14 02:31:43

单击时将 添加到 中。
模糊时,将其更改为

Add <input> to <td> when it is clicked.
Change <input> to <span> when it is blurred.

追风人 2024-11-14 02:31:43

如果你的表有很多功能(排序、导出、更新、编辑等),

我会推荐引导表。

wenzhixin/bootstrap-table

关于编辑实践:

监听事件:click-cell.bs.table 然后添加属性 contenteditable 点击后立即添加到 td

您可能不希望允许在每一列中进行编辑,因此我添加了 data-editable code> 属性我自己用JS来确定这一点。

演示

Title列允许您编辑

<!DOCTYPE html>
<html>
<head>
  <!-- jquery -->
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js" integrity="sha512-894YE6QWD5I59HgZOGReFYm4dnWc1Qt5NtvYSaNcOP+u1T9qYdvdihz0PPSiiqn/+/3e7Jo4EaG7TubfWGUrMQ==" crossorigin="anonymous"></script>

  <!-- bootstrap -->
  <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-eOJMYsd53ii+scO/bJGFsiCZc+5NDVN2yr8+0RDqr0Ql0h+rP48ckxlpbzKgwra6" crossorigin="anonymous">
  <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-JEW9xMcG8R+pH31jmWH6WWP0WintQrMb4s7ZOdauHnUtxwoG2vI5DkLtS3qm9Ekf" crossorigin="anonymous"></script>

  <!-- bootstrap-table-->
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-table/1.18.3/bootstrap-table.min.css" integrity="sha512-5RNDl2gYvm6wpoVAU4J2+cMGZQeE2o4/AksK/bi355p/C31aRibC93EYxXczXq3ja2PJj60uifzcocu2Ca2FBg==" crossorigin="anonymous" />
  <script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-table/1.18.3/bootstrap-table.min.js" integrity="sha512-Wm00XTqNHcGqQgiDlZVpK4QIhO2MmMJfzNJfh8wwbBC9BR0FtdJwPqDhEYy8jCfKEhWWZe/LDB6FwY7YE9QhMg==" crossorigin="anonymous"></script>

  <!--bootstrap-table-lanuage-->
  <script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-table/1.18.3/bootstrap-table-locale-all.min.js" integrity="sha512-1PCRWIvrSQaZjCRWaa0GHWKr1jQA8u79VnIvkAme6BKeoNWe5N89peawTXdVp+kukb8rzNsEY89ocMJqVivdSA==" crossorigin="anonymous"></script>
  <!--bootstrap-table-export-->
  <script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-table/1.18.3/extensions/export/bootstrap-table-export.min.js" integrity="sha512-cAMZL39BuY4jWHUkLWRS+TlHzd/riowdz6RNNVI6CdKRQw1p1rDn8n34lu6pricfL0i8YXeWQIDF5Xa/HBVLRg==" crossorigin="anonymous"></script>

  <!-- screenshots -->
  <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/es6-promise.auto.min.js" integrity="sha256-Xxrdry6fWSKu1j2ALyuK/gHFQ+2Bp76ZrR6f3QXI47Y=" crossorigin="anonymous"></script>
  <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/html2canvas.min.js" integrity="sha256-Ax1aqtvxWBY0xWND+tPZVva/VQZy9t1Ce17ZJO+NTRc=" crossorigin="anonymous"></script>


  <!-- tableexport.jquery.plugin If you want to export, then you must add it. -->
  <script src="https://cdn.jsdelivr.net/npm/[email protected]/tableExport.min.js" integrity="sha256-Dsris8trQzzQXIM6PgMzSugaNyUacxaR9o2VrJalh6Y=" crossorigin="anonymous"></script>

  <!-- font-awesome -->
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css" integrity="sha512-iBBXm8fW90+nuLcSKlbmrPcLa0OT92xO1BIsZ+ywDWZCvqsWgccV3gFoRBv0z+8dLJgyAHIhR35VZc2oM/gI1w==" crossorigin="anonymous" />
  <script src="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/js/all.min.js" integrity="sha512-RXf+QSDCUQs5uwRKaDoXt55jygZZm2V++WUZduaU/Ui/9EGp3f/2KZVahFZBKGH0s774sd3HmrhUy+SgOFQLVQ==" crossorigin="anonymous"></script>

  <style>
    html {
      font-family: sans-serif;
      line-height: 1.15;
      -webkit-text-size-adjust: 100%;
      -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
    }

    h1, h2, h3, h4, h5, h6 {
      margin-top: 0;
      margin-bottom: 0.5rem;
      color: #004a88;
      text-align: center;
    }

    .table-blue {
      font-family: Arial, Helvetica, sans-serif;
      border-collapse: collapse;
      width: 100%;
    }

    .table-blue td, .table-blue th {
      border: 1px solid #ddd;
      padding: 8px;
    }

    .table-blue tr:hover {background-color: #ddd;}

    .table-blue th {
      background-color: #004a88;
      font-size: larger;
      font-weight: bold;
      padding-top: 5px;
      padding-bottom: 5px;
      text-align: left;
      color: white;
    }

    /* https://stackoverflow.com/a/63412885 */
    thead, tbody tr {
      display: table;
      width: 100%;
      table-layout: fixed;
    }
    tbody {
      display: block;
      overflow-y: auto;
      table-layout: fixed;
      max-height: 512px;
    }

    td {
      word-break: break-all;
    }

  </style>
</head>

<body>
<!-- Table-options:
- https://bootstrap-table.com/docs/api/table-options/
- https://bootstrap-table.com/docs/extensions/export/
-->
<table id="myTable" class="table table-striped table-blue"
       data-toggle="table"
       data-search="true"
       data-search-highlight="true"
       data-show-refresh="true"
       data-show-toggle="true"
       data-show-columns="true"
       data-show-export="true"
       data-minimum-count-columns="2"
       data-show-pagination-switch="true"
       data-pagination="true"
       data-id-field="id"
       data-page-list="[10, 25, 50, 100, ALL]"
       data-show-footer="false"
       data-side-pagination="client"
       data-export-types='["csv", "json", "excel", "doc", "sql", "png"]'
       data-editable = '[false, true, false, false]'
       data-export-options='{
        "fileName": "products"
        }'
       data-url="https://jsonplaceholder.typicode.com/photos">
  <thead>
  <tr>
    <th data-sortable="true" data-field="id">Id</th>
    <th data-sortable="true" data-field="title">Title</th>
    <th data-sortable="true" data-field="url">URL</th>
    <th data-sortable="true" data-formatter="imageFormatter" data-field="thumbnailUrl">Thumbnail URL</th>
  </tr>
  </thead>
</table>
</body>

<script>
  const TABLE_ID = "myTable";
  const TABLE = document.getElementById(TABLE_ID)

  window.onload = () => {
    const table = $(`#${TABLE_ID}`)

    function imageFormatter(value, row) {
      return `<img src="${value}"  style="width:60px;height:60px" loading="lazy"/>`;
    }

    function saveData(tdData) {
      // ... ajax ...
      console.log("save")
    }

    const infoEditable = JSON.parse(TABLE.getAttribute("data-editable"))
    if (infoEditable === null) {
      return
    }
    table.on('click-cell.bs.table', function (event, field, value, row, td) {
      td = td[0]
      if (td.getAttribute("contentEditable")) {
        return
      }
      const index = Array.prototype.indexOf.call(td.parentNode.children, td)
      if (infoEditable[index]) {
        td.contentEditable = "true"
      }

      td.addEventListener("keyup", (event) => {
        clearTimeout($.data(this, 'timer'));
        const wait = setTimeout(saveData, 1000); // delay after user types
        $(this).data('timer', wait);
      })
    })
  }
</script>
</html>

If your table has many functions (sorting, exporting, updating, editing, etc.),

I would recommend the bootstrap table.

wenzhixin/bootstrap-table

About editing practices:

Listen to events: click-cell.bs.table then adds the attribute contenteditable to the td as soon as it is clicked

You may not want to allow editing in every column, so I added the data-editable attribute myself with JS to determine this.

Demo

column of Title allows you to edit

<!DOCTYPE html>
<html>
<head>
  <!-- jquery -->
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js" integrity="sha512-894YE6QWD5I59HgZOGReFYm4dnWc1Qt5NtvYSaNcOP+u1T9qYdvdihz0PPSiiqn/+/3e7Jo4EaG7TubfWGUrMQ==" crossorigin="anonymous"></script>

  <!-- bootstrap -->
  <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-eOJMYsd53ii+scO/bJGFsiCZc+5NDVN2yr8+0RDqr0Ql0h+rP48ckxlpbzKgwra6" crossorigin="anonymous">
  <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-JEW9xMcG8R+pH31jmWH6WWP0WintQrMb4s7ZOdauHnUtxwoG2vI5DkLtS3qm9Ekf" crossorigin="anonymous"></script>

  <!-- bootstrap-table-->
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-table/1.18.3/bootstrap-table.min.css" integrity="sha512-5RNDl2gYvm6wpoVAU4J2+cMGZQeE2o4/AksK/bi355p/C31aRibC93EYxXczXq3ja2PJj60uifzcocu2Ca2FBg==" crossorigin="anonymous" />
  <script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-table/1.18.3/bootstrap-table.min.js" integrity="sha512-Wm00XTqNHcGqQgiDlZVpK4QIhO2MmMJfzNJfh8wwbBC9BR0FtdJwPqDhEYy8jCfKEhWWZe/LDB6FwY7YE9QhMg==" crossorigin="anonymous"></script>

  <!--bootstrap-table-lanuage-->
  <script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-table/1.18.3/bootstrap-table-locale-all.min.js" integrity="sha512-1PCRWIvrSQaZjCRWaa0GHWKr1jQA8u79VnIvkAme6BKeoNWe5N89peawTXdVp+kukb8rzNsEY89ocMJqVivdSA==" crossorigin="anonymous"></script>
  <!--bootstrap-table-export-->
  <script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-table/1.18.3/extensions/export/bootstrap-table-export.min.js" integrity="sha512-cAMZL39BuY4jWHUkLWRS+TlHzd/riowdz6RNNVI6CdKRQw1p1rDn8n34lu6pricfL0i8YXeWQIDF5Xa/HBVLRg==" crossorigin="anonymous"></script>

  <!-- screenshots -->
  <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/es6-promise.auto.min.js" integrity="sha256-Xxrdry6fWSKu1j2ALyuK/gHFQ+2Bp76ZrR6f3QXI47Y=" crossorigin="anonymous"></script>
  <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/html2canvas.min.js" integrity="sha256-Ax1aqtvxWBY0xWND+tPZVva/VQZy9t1Ce17ZJO+NTRc=" crossorigin="anonymous"></script>


  <!-- tableexport.jquery.plugin If you want to export, then you must add it. -->
  <script src="https://cdn.jsdelivr.net/npm/[email protected]/tableExport.min.js" integrity="sha256-Dsris8trQzzQXIM6PgMzSugaNyUacxaR9o2VrJalh6Y=" crossorigin="anonymous"></script>

  <!-- font-awesome -->
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css" integrity="sha512-iBBXm8fW90+nuLcSKlbmrPcLa0OT92xO1BIsZ+ywDWZCvqsWgccV3gFoRBv0z+8dLJgyAHIhR35VZc2oM/gI1w==" crossorigin="anonymous" />
  <script src="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/js/all.min.js" integrity="sha512-RXf+QSDCUQs5uwRKaDoXt55jygZZm2V++WUZduaU/Ui/9EGp3f/2KZVahFZBKGH0s774sd3HmrhUy+SgOFQLVQ==" crossorigin="anonymous"></script>

  <style>
    html {
      font-family: sans-serif;
      line-height: 1.15;
      -webkit-text-size-adjust: 100%;
      -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
    }

    h1, h2, h3, h4, h5, h6 {
      margin-top: 0;
      margin-bottom: 0.5rem;
      color: #004a88;
      text-align: center;
    }

    .table-blue {
      font-family: Arial, Helvetica, sans-serif;
      border-collapse: collapse;
      width: 100%;
    }

    .table-blue td, .table-blue th {
      border: 1px solid #ddd;
      padding: 8px;
    }

    .table-blue tr:hover {background-color: #ddd;}

    .table-blue th {
      background-color: #004a88;
      font-size: larger;
      font-weight: bold;
      padding-top: 5px;
      padding-bottom: 5px;
      text-align: left;
      color: white;
    }

    /* https://stackoverflow.com/a/63412885 */
    thead, tbody tr {
      display: table;
      width: 100%;
      table-layout: fixed;
    }
    tbody {
      display: block;
      overflow-y: auto;
      table-layout: fixed;
      max-height: 512px;
    }

    td {
      word-break: break-all;
    }

  </style>
</head>

<body>
<!-- Table-options:
- https://bootstrap-table.com/docs/api/table-options/
- https://bootstrap-table.com/docs/extensions/export/
-->
<table id="myTable" class="table table-striped table-blue"
       data-toggle="table"
       data-search="true"
       data-search-highlight="true"
       data-show-refresh="true"
       data-show-toggle="true"
       data-show-columns="true"
       data-show-export="true"
       data-minimum-count-columns="2"
       data-show-pagination-switch="true"
       data-pagination="true"
       data-id-field="id"
       data-page-list="[10, 25, 50, 100, ALL]"
       data-show-footer="false"
       data-side-pagination="client"
       data-export-types='["csv", "json", "excel", "doc", "sql", "png"]'
       data-editable = '[false, true, false, false]'
       data-export-options='{
        "fileName": "products"
        }'
       data-url="https://jsonplaceholder.typicode.com/photos">
  <thead>
  <tr>
    <th data-sortable="true" data-field="id">Id</th>
    <th data-sortable="true" data-field="title">Title</th>
    <th data-sortable="true" data-field="url">URL</th>
    <th data-sortable="true" data-formatter="imageFormatter" data-field="thumbnailUrl">Thumbnail URL</th>
  </tr>
  </thead>
</table>
</body>

<script>
  const TABLE_ID = "myTable";
  const TABLE = document.getElementById(TABLE_ID)

  window.onload = () => {
    const table = $(`#${TABLE_ID}`)

    function imageFormatter(value, row) {
      return `<img src="${value}"  style="width:60px;height:60px" loading="lazy"/>`;
    }

    function saveData(tdData) {
      // ... ajax ...
      console.log("save")
    }

    const infoEditable = JSON.parse(TABLE.getAttribute("data-editable"))
    if (infoEditable === null) {
      return
    }
    table.on('click-cell.bs.table', function (event, field, value, row, td) {
      td = td[0]
      if (td.getAttribute("contentEditable")) {
        return
      }
      const index = Array.prototype.indexOf.call(td.parentNode.children, td)
      if (infoEditable[index]) {
        td.contentEditable = "true"
      }

      td.addEventListener("keyup", (event) => {
        clearTimeout($.data(this, 'timer'));
        const wait = setTimeout(saveData, 1000); // delay after user types
        $(this).data('timer', wait);
      })
    })
  }
</script>
</html>

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文