jqueryの勉強してて、例えばHTMLのtableをExcelみたいにしてみたらどうだろうと思った。
まずは、Tableを編集可能にしてみるところから作ってみました。
editable-table.cssとeditable-table.jsを参照に追加して、
編集可能にしたい既存のTableタグにclass="editable-table"を追加するだけで
tdタグの内容を変更可能なTableになるっていうスクリプトです。
必要な設定は、これだけ↓↓↓
<table class="editable-table">
このスクリプトはjqueryを使っています。
逆に、表中のtdタグで編集されたくないところには、lock属性を追加すれば編集不可にできます。
<td lock>おれ</td>
こんなバルーンがでて編集モードにはなりません。
これをベースにして、本物のExcelみたいに関数とか使えるようにして
画面上のテーブル使って簡単な集計処理とかできたら便利そーだなーとか思ったり。
これから徐々に機能拡張していこうかなと考えてます。
次回は、選択中のセルを方向キーで移動できるようにして、F2で編集っていうのも足してみよう。
サンプルHTML
<html> <head> <meta charset="UTF-8"> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <script src="editable-table.js"></script> <link href="editable-table.css" rel="stylesheet"> </head> <body> <table class="editable-table"> <tr><th>#</th><th>name</th><th>status</th></tr> <tr><th>1</th><td lock>おれ</td><td>元気</td></tr> <tr><th>2</th><td>おまえ</td><td>超元気</td></tr> </table> <hr> <table class="editable-table"> <tr><th>#</th><th>name</th><th>status</th></tr> <tr><th>10</th><td>キサマ</td><td lock>千鳥</td></tr> <tr><th>11</th><td>おぬし</td><td>武士</td></tr> </table> </body> </html>
editable-table.css
.editable-table,.editable-table th,td{ border: 1px solid darkgray; border-collapse: collapse; } .editable-table th { background-color: paleturquoise; } .editable-table td.selected { border: 2px solid black;} textarea.cell-edit { display: block; padding: 6px 24px; height: 100%; width: 100%; -webkit-box-sizing: border-box; -khtml-box-sizing: border-box; -moz-box-sizing: border-box; -ms-box-sizing: border-box; box-sizing: border-box;} span.tooltip { position:absolute; z-index:9999; display:block; color:#0000ff; font-size:14px; line-height:1.2; } span.tooltip__body { position:relative; top:-15px; padding:10px; background:#f0e68c; -webkit-border-radius:3px; -moz-border-radius:3px; -ms-border-radius:3px; border-radius:3px; -webkit-box-shadow:0 2px 4px rgba(0, 0, 0, .4); -moz-box-shadow:0 2px 4px rgba(0, 0, 0, .4); -ms-box-shadow:0 2px 4px rgba(0, 0, 0, .4); box-shadow:0 2px 4px rgba(0, 0, 0, .4); } span.tooltip__body:after { content:""; position:absolute; bottom:-5px; left:50%; display:block; width:0; height:0; margin-left:-5px; border-width:5px 5px 0 5px; border-style:solid; border-color:#f0e68c transparent transparent transparent; }
editable-table.js
$(function (){ editable_table.Initalize(); }); var editable_table_val = {}; var editable_table = { Initalize: function () { $('.editable-table').find('td').each(function(){ var $td = $(this); var tr = $(this).parent(); var row = $('.editable-table').find('tr').index(tr); var col = $(tr).find('td').index(this); var idx = "$"+col+"_"+row; $(this).attr("data-address", idx); editable_table_val[idx] = $td.html(); $td.click(function () { editable_table.ClearSelectionCells(); $(this).toggleClass("selected", true); }); $td.dblclick(function () { var $this = $(this); if ($this.hasClass("editing")) { return } if ($this.attr("lock") != undefined) { editable_table.CellLock(this); return } var adrs = $this.attr("data-address"); var cell_val = editable_table_val[adrs]; editable_table.ClearSelectionCells(); var input = $("<textarea />").attr("id", "edit_target").attr("data-address", adrs).addClass("cell-edit").text(cell_val); $this.toggleClass("selected",true).html("").append(input); $this.addClass("editing"); $("#edit_target").focus().blur(function (){ var adrs = $(this).attr("data-address"); var edit_val = $(this).text().toString(); var rollback = editable_table_val[adrs]; editable_table_val[adrs] = edit_val; $(this).remove(); $("td[data-address='" + adrs + "']").toggleClass("editing", false); editable_table.Recalculation(); }); }); $(document).keydown(function(e){ // Esc キー if (e.keyCode == 27) { var adrs = $("#edit_target").attr("data-address"); if (adrs == undefined) { return } $("#edit_target").remove(); $("td[data-address='" + adrs + "']").toggleClass("editing", false); editable_table.Recalculation(); } }); }); }, ClearSelectionCells: function () { $('.editable-table').find('td').each(function(){ $(this).toggleClass("selected", false); }); }, Recalculation: function() { for (idx in editable_table_val) { $("td[data-address='" + idx + "']").html(editable_table_val[idx]); } }, CellLock: function(cell) { var msg = "このセルは変更できません。"; var $tooltip = $("<span />").addClass("tooltip").append($("<span />").addClass("tooltip__body").text(msg)); $('body').append($tooltip); var $cell = $(cell); var cell_offset = $cell.offset(); var cell_size = { width: $cell.outerWidth(), height: $cell.outerHeight() }; var tip_size = { width: $tooltip.outerWidth(), height: $tooltip.outerHeight() }; $tooltip.css({ top: cell_offset.top - tip_size.height, left: cell_offset.left + cell_size.width / 2 - tip_size.width / 2}); $cell.mouseout(function (){ $('.tooltip').fadeOut("slow", function() {$(this).remove(); })}); } }