我想使 HTML 表格的一些单元格可编辑,只需双击一个单元格,输入一些文本和更改可以发送到服务器。我不想使用像道场数据网格这样的工具包。因为它提供了一些其他特性。你能给我提供一些代码片段或关于如何实现它的建议吗?
可以对有问题的单元格、行或表使用 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 change events
如果您使用 Jquery,这个插件可以帮助您 很简单,但是很好
Https://github.com/samuelsantosdev/tableedit
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 条目的话
属性必须采用下列值之一: True 或空字符串,表示元素必须是可编辑的; False,表示元素不可编辑。 如果未设置此属性,则从其 父元素。 这个属性是枚举的,而不是布尔的。这意味着 that the explicit usage of one of the values true, false or the empty 字符串是强制性的,不允许使用速记。
属性必须采用下列值之一:
True 或空字符串,表示元素必须是可编辑的;
False,表示元素不可编辑。
如果未设置此属性,则从其 父元素。
这个属性是枚举的,而不是布尔的。这意味着 that the explicit usage of one of the values true, false or the empty 字符串是强制性的,不允许使用速记。
// wrong not allowed <label contenteditable>Example Label</label> // correct usage <label contenteditable="true">Example Label</label>.
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"); }); }); });
你亦可浏览此连结了解更多资料:
我有三个办法, 在这里,您可以使用 <input>或 <textarea>,根据您的要求。
<input>
<textarea>
1. 在 <td>中使用输入法。
<td>
Using <input> element in all <td>s,
<tr><td><input type="text"></td>....</tr>
另外,您可能希望将输入的大小调整为其 td.ex. 的大小,
td
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. 使用 contenteditable='true'属性(HTML5)
contenteditable='true'
但是,如果要使用 contenteditable='true',可能还需要将适当的值保存到数据库中。你可以通过 Ajax 实现这一点。
您可以将密钥处理程序 keyup、 keydown、 keypress等附加到 <td>。此外,当用户连续输入时,最好使用一些 延迟()和这些事件,Ajax 事件不会随着用户每次按键而触发。比如说,
keyup
keydown
keypress
$('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”的值。所有这些都是用 javascript 完成的。
这实际上太直接了, this is my HTML, jQuery sample.. and it works like a charm, I build all the code using an online json data sample. 干杯
< 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 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>
你可以使用 x-editable < a href = “ https://vitalets.github.io/x-editable/”rel = “ norefrer”> https://vitalets.github.io/x-editable/ 引导程序提供的令人敬畏的库
只需在 <td>中动态插入 <input>元素,单击单元格即可。只有简单的 HTML 和 Javascript。不需要 contentEditable,jquery,HTML5
contentEditable
jquery
HTML5
Https://jsfiddle.net/gsivanov/38tlqobw/2/
这是关键的一点,尽管您不需要让代码变得如此混乱。相反,您可以遍历所有的 <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>
我将这个字段用于可编辑字段
<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>
单击时将 <input>添加到 <td>。 模糊时将 <input>改为 <span>。
<span>
如果表有许多功能(排序、导出、更新、编辑等) ,
I would recommend the bootstrap table.
关于编辑实践:
侦听事件: click-cell.bs.table然后将属性 很满足单击后立即添加到 td
您可能不希望在每一列中都允许编辑,所以我自己用 JS 添加了 data-editable属性来确定这一点。
data-editable
Title列允许您编辑
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/bootstrap@5.0.0-beta3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-eOJMYsd53ii+scO/bJGFsiCZc+5NDVN2yr8+0RDqr0Ql0h+rP48ckxlpbzKgwra6" crossorigin="anonymous"> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta3/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/es6-promise@4.2.8/dist/es6-promise.auto.min.js" integrity="sha256-Xxrdry6fWSKu1j2ALyuK/gHFQ+2Bp76ZrR6f3QXI47Y=" crossorigin="anonymous"></script> <script src="https://cdn.jsdelivr.net/npm/html2canvas@1.0.0-rc.7/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/tableexport.jquery.plugin@1.10.22/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>