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