Handsontable より、もっと手軽に自分で書く table タグの td をクリックで、input にして編集するものを
汎用的に作ってみたくなりました。
結果、以下のようなサンプルページです。
td をクリックした時に、数値なら右寄せ、3桁区切りのオプション
blur() でフォーカスが離れたら、callback関数を実行するオプション、さらに、指定するフィールドに値をセット
このようなもに動き、設定が楽に書けるものを考えました。
書式は、
TableEdit.input( tdを指すセレクタ [ , option ] );
option は、Hash配列で、
type : で指定するものは、'text' , 'number' , 'digit' のいずれか。
digit は、3桁区切りの数値
setfield : で、input type="hidden" など、jQueryObject.val()でセットできるものを指定。
callback : で、blur() 時、input に入っている値を引数にした callback関数を指定します。
tableedit.js として、以下のソースになります。
/**
* tableedit.js
*/
$(function(){
TableEdit={};
TableEdit.input = function(td, options){
$(td).click(edit_input(options));
};
function edit_input(options){
return function(){
var inputstyle = "margin-left: 3px; margin-right: 3px; width: 92%;";
var type = "text";
var _callbackfunc = null;
var _setfield = null;
if (typeof options=="object" && _isHash(options)){
if (options['type'] != undefined){
type = options['type'].toLowerCase();
if (type=='number' || type=='digit'){
inputstyle = "text-align: right;margin-left: 3px; margin-right: 3px; width: 92%;";
}
}
if (options['callback'] != undefined){
_callbackfunc = options['callback'];
}
if (options['setfield'] != undefined){
_setfield = options['setfield'];
}
}
if (type=='number' || type=='digit'){
$(this).html($("<input>").attr("type","text").attr("style", inputstyle).val($(this).text().replace(/,/g, '')));
}else{
$(this).html($("<input>").attr("type","text").attr("style", inputstyle).val($(this).text()));
}
var paddingkeep = $(this).css("padding");
$(this).css("padding", "0 0 0 0");
$("input", this).focus().blur(function(){
$(this).parent().attr("style", "padding:" + paddingkeep);
if (type=='digit'){
var str = $(this).val();
str = str.replace(/[0-9]/g, function(s){ return String.fromCharCode(s.charCodeAt(0)-0xFEE0); });
str = str.replace(/,/g, '');
if (str.match(/^(|-)[0-9]+$/)){
str = str.replace(/^[0]+([0-9]+)/g, '$1');
str = str.replace(/([0-9]{1,3})(?=(?:[0-9]{3})+$)/g, '$1,');
}
$(this).after(str).unbind().remove();
}else{
$(this).after($(this).val()).unbind().remove();
}
if (typeof(_setfield) != "undefined"){
$(_setfield).val($(this).val());
}
if (typeof(_callbackfunc) != "undefined"){
_callbackfunc($(this).val());
}
});
return false;
};
}
function _isHash(obj){
if (typeof obj=="object"){
for(k in obj){
if(obj[k] != undefined){
return true;
}else{
return false;
}
}
}
return false;
}
});
サンプルHTMLは、以下のとおり。
テーブル複数行、tr のセレクタは、each関数で全行に効かせるようにします。
td 列に沿って、:eq(列インデックス)で指定します。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>sample</title>
<script type="text/javascript" src="../../js/jquery-2.0.3.min.js"></script>
<style type="text/css">
table.border-table{
border: 1px #000000 solid;
border-collapse: collapse;
border-spacing: 0;
white-space: nowrap;
}
.border-table th, .border-table td{ border: 1px #000000 solid; }
.edit td , .edit th {
padding: 4px;
padding-left : 10px;
padding-right: 10px;
padding-top: 4px;
padding-bottom: 4px;
width: 120px;
}
.edit td+td+td{
text-align: right;
}
.edit td+td{
text-align: right;
}
</style>
<script type="text/javascript" src="tableedit.js"></script>
<script type="text/javascript">
$(function(){
$('#target > tbody > tr').each(function(i,trobj){
TableEdit.input($(trobj).children('td:eq(0)'));
TableEdit.input($(trobj).children('td:eq(1)'), { type: "number" });
TableEdit.input($(trobj).children('td:eq(2)'),
{ type: "digit",
setfield: "#price",
callback: function(e){ alert("price = "+e); }
}
);
});
});
</script>
</head>
<body>
<h2>Table td click → input</h2>
<table id="target" class="border-table edit">
<thead>
<tr>
<th>品名</th><th>数量</th><th>価格</th>
</tr>
</thead>
<tbody>
<tr>
<td>ロクシタン</td><td>1200</td><td>120,000</td>
</tr>
<tr>
<td>リードケース</td><td>24</td><td>48,000</td>
</tr>
</tbody>
</table>
<br/>
<input type="hidden" id="price" name="price">
</body>
</html>