<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <title>SOUM/misc</title>
<link rel="alternate" type="text/html" href="https://www.soum.co.jp/misc/" />
    <link rel="self" type="application/atom+xml" href="https://www.soum.co.jp/misc/rss.xml" />
    <id>tag:www.soum.co.jp,2017-06-13:/misc//22</id>
    <updated>2021-07-21T01:00:11Z</updated>
    
    <generator uri="http://www.sixapart.com/movabletype/">Movable Type Pro 6.3.3</generator>

<entry>
    <title>Tree-sitter について</title>
    <link rel="alternate" type="text/html" href="https://www.soum.co.jp/misc/vim-advanced/6/" />
    <id>tag:sh173.soum.co.jp,2021:/misc//22.2259</id>

    <published>2021-07-21T01:00:00Z</published>
    <updated>2021-07-21T01:00:11Z</updated>

    <summary>Vim 使いの「ブイ」(仮名)です。Vim のすゝめ改では、現代のテキストエディ...</summary>
    <author>
        <name>v</name>
        
    </author>
    
        <category term="Vimのすゝめ改" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="https://www.soum.co.jp/misc/">
        <![CDATA[<p>Vim 使いの「ブイ」(仮名)です。Vim のすゝめ改では、現代のテキストエディタについてのあらゆる話題をテーマに Vim の視点から見た話を行います。</p>

<p>今回のテーマは「Tree-sitter」です。</p>

<h2>1 Tree-sitter とは？</h2>

<p><a href="https://tree-sitter.github.io/tree-sitter/">https://tree-sitter.github.io/tree-sitter/</a></p>

<p>Tree-sitter は Atom のシンタックスハイライトとしても使用されている技術であり、最近になって neovim にも Tree-sitter によるシンタックスハイライトが導入されました。</p>

<p><a href="https://github.blog/2018-10-31-atoms-new-parsing-system/">https://github.blog/2018-10-31-atoms-new-parsing-system/</a></p>

<p><a href="https://github.com/neovim/neovim/pull/11113">https://github.com/neovim/neovim/pull/11113</a></p>

<p>従来、テキストエディタの汎用的なシンタックスハイライトには正規表現が使われることが多くありました。しかし正規表現は記述が難しい上に遅い、表現が限られるので正確なパースができないといった問題点が存在していました。詳しくは <a href="https://www.soum.co.jp/misc/vim-advanced/3/">以前の SOUM/misc</a>を参照してください。</p>

<p>Tree-sitter はシンタックスハイライトに特化していて、ソースファイルが更新されたときに即座に結果を返すことができ高速です。これは漸進的分析(Incremental Parsing)といい、テキストエディタで使用することが意図された解析パーサーだからだそうです。</p>

<p>Tree-sitter を用いた解析は簡単で、ソースコードをTree-sitter に与えると解析結果が返るのであとはテキストエディタが適切に色付けをすればよいです。</p>

<p>Tree-sitter はハイライト以外にも使用することができ、Tree-sitter の構文解析結果を用いて、特定の識別子を選択することも可能です。これは Vim でいうテキストオブジェクトに相当します。</p>

<p>Tree-sitter での構文解析処理は npm で実装されており、つまり JavaScript です。高速化のため、JavaScriptは C 言語のソースコードに変換されるようです。</p>

<p>Tree-sitter が対応している言語については、以下を参照してください。C, C++, C#, Rust, Go, Lua 等メジャーな言語には対応しています。</p>

<p><a href="https://tree-sitter.github.io/tree-sitter/#available-parsers">https://tree-sitter.github.io/tree-sitter/#available-parsers</a></p>

<p>Tree-sitter と LSP との違いとしては、LSP は IDE の処理をほとんど全て行う必要があるので、より処理が複雑であり時間がかかります。LSP の設定も大変です。
Tree-sitter はやることが限られていて明快なので適用できる領域は少ないものの、高速に単純に使うことができます。個人的には Tree-sitter と LSP の両方を併用するのがよいと考えます。</p>

<p>実は、Tree-sitter 以前にも似たようなコンセプトの Vim プラグインが存在していました。<code>ruby_hl_lvar.vim</code> です。</p>

<p><a href="https://github.com/todesking/ruby_hl_lvar.vim">https://github.com/todesking/ruby_hl_lvar.vim</a></p>

<p>このプラグインは独自に Ruby の構文を解析し、ローカル変数をハイライトします。Vim のハイライトは構文解析を行わないのでローカル変数をハイライトするといったことが行えません。この問題を解消するためのプラグインです。</p>

<p>Tree-sitter はこのような「ソースコードの構文を解析してテキストエディタのハイライト等に利用する」ことを汎用的インタフェースに落としこんだものと言えるでしょう。</p>

<h2>2 neovim における Tree-sitter の利用</h2>

<p>neovim で Tree-sitter を使うには <code>nvim-treesitter</code> というプラグインをインストールする必要があります。</p>

<p><a href="https://github.com/nvim-treesitter/nvim-treesitter">https://github.com/nvim-treesitter/nvim-treesitter</a></p>

<p>neovim 本体に Tree-sitter 用の基本機能は入っていますが、ユーザーにとって使いやすいようにはまとまっていません。neovim LSP と <code>nvim-lspconfig</code> の関係のように高レベルな機能やファイルタイプ毎の細かな設定については本体とは別になっているようです。</p>

<p><code>nvim-treesitter</code> のインストール方法は公式のドキュメントを参照してください。</p>

<p><a href="https://github.com/nvim-treesitter/nvim-treesitter#installation">https://github.com/nvim-treesitter/nvim-treesitter#installation</a></p>

<p><code>nvim-treesitter</code> をインストールした後は簡単な設定を vimrc に記述する必要があります。<code>nvim-treesitter</code> は Lua で書かれているので vimrc に Lua のコードを埋め込むことで設定を行います。</p>

<p><a href="https://github.com/nvim-treesitter/nvim-treesitter#setup">https://github.com/nvim-treesitter/nvim-treesitter#setup</a></p>

<pre><code>lua &lt;&lt;EOF
require'nvim-treesitter.configs'.setup {
  ensure_installed = "maintained",
  highlight = {
    enable = true,
    disable = {},
  },
}
EOF
</code></pre>

<p><code>nvim-treesitter</code> を有効にした場合、通常のハイライトプラグインの代わりに Tree-sitter を用いてハイライトが行われるようになります。</p>

<p>ちなみに Tree-sitter の構文情報を用いて補完を行う <code>completion-treesitter</code> というプラグインも存在しているようです。</p>

<p><a href="https://github.com/nvim-treesitter/completion-treesitter">https://github.com/nvim-treesitter/completion-treesitter</a></p>

<h2>3 neovim における Tree-sitter の補足事項</h2>

<p>余談ですが、外部パッケージへの依存を嫌う Vim では Tree-sitter 対応のような機能は取り込まれないだろうと思われます。本体はシンプルに、ただし使える外部ライブラリはどんどん使う方針の neovim だからこそ取り込みが実現したのでしょう。</p>

<p>自分は実際に Tree-sitter を使ってコードを記述しています。強力なシンタックスハイライトにより文法エラーが一発で分かるのでかなり開発効率の向上に役立っていると言えます。一度この強力なハイライトに慣れてしまうと戻ることが困難です。特に、Typescript + JSX のように複雑な解析が必要なハイライトで効力を発揮します。</p>

<p>Tree-sitter の欠点としては時々内部エラーが発生してシンタックスハイライトが消えたりすることです。毎日のように <code>nvim-treesitter</code> に更新がある開発中のプロダクトなのでそこは仕方がありません。Tree-sitter のパーサーが特定のシンタックス解析に対応してないということもあるようです。</p>

<p>それでも、Tree-sitter の機能はどんどん改善され使いやすくなっているので neovim を使用しているのなら使う価値はあると思います。</p>

<p><em>This article is made by Vim.</em></p>
]]>
        
    </content>
</entry>

<entry>
    <title>neovim への Pull Request 紹介</title>
    <link rel="alternate" type="text/html" href="https://www.soum.co.jp/misc/vim-advanced/5/" />
    <id>tag:sh173.soum.co.jp,2021:/misc//22.2255</id>

    <published>2021-07-07T00:10:00Z</published>
    <updated>2021-07-07T00:10:08Z</updated>

    <summary>Vim 使いの「ブイ」(仮名)です。Vim のすゝめ改では、現代のテキストエディ...</summary>
    <author>
        <name>v</name>
        
    </author>
    
        <category term="Vimのすゝめ改" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="https://www.soum.co.jp/misc/">
        <![CDATA[<p>Vim 使いの「ブイ」(仮名)です。Vim のすゝめ改では、現代のテキストエディタについ
てのあらゆる話題をテーマに Vim の視点から見た話を行います。</p>

<p>今回のテーマは「neovim への Pull Request 紹介」です。</p>

<p>前回は Vim への Pull Request を眺めましたが、それの neovim 版です。
neovim は Vim よりも Pull Request が活用されており、巨大な Pull Request のまま
開発が進むことが多くあります。
neovim の LSP Client 機能も、もとは Pull Request から始まったのです。
neovim HEAD を追い掛けるのに物足りなさを感じた場合は neovim の今後の方向性に思
いを馳せるのもよいのではないでしょうか。</p>

<h2>1 --server, --remote-{subcommand} 機能</h2>

<p><a href="https://github.com/neovim/neovim/pull/11326">https://github.com/neovim/neovim/pull/11326</a></p>

<p>Vim にはリモート編集機能と呼ばれるものがあり、外部から特定のコマンドを実行する
ことで現在実行中の Vim に任意のファイルを編集するようにすることができます。
この機能は neovim になってなくなってしまったのですが、上記の Pull Request で実
装されるようです。作業が止まってしまっているのが気がかりです。</p>

<h2>2 tree sitter</h2>

<p><a href="https://github.com/neovim/neovim/pull/11113">https://github.com/neovim/neovim/pull/11113</a></p>

<p><a href="https://github.com/tree-sitter/tree-sitter">tree sitter</a> によるハイライトを実
装する Pull Request です。tree sitter とはコードの解析を行う解析器であり、Atom
エディタにも使用されているようです。現在 Vim や neovim は正規表現を用いてハイラ
イトを行っているのでハイライトが遅いという問題を抱えています。
tree sitter により、この問題を根本的に解決することができるかもしれません。
この機能は既に neovim にマージされており、次回の「Vim のすゝめ改」にて解説予定
です。</p>

<h2>3 UIEnter/UILeave</h2>

<p><a href="https://github.com/neovim/neovim/pull/11263">https://github.com/neovim/neovim/pull/11263</a></p>

<p>neovim の GUI の起動・終了に hook するための autocmd 実装です。GVim でいう
GUIEnter に相当します。従来の neovim はこの hook がなかったので、GUI クライアン
トに依存した処理を書きにくいという問題がありました。</p>

<h2>4 Context and Multiprocessing</h2>

<p><a href="https://github.com/neovim/neovim/pull/10843">https://github.com/neovim/neovim/pull/10843</a></p>

<p>外部コマンドをバックグラウンドで実行するコマンドの追加です。
バックグラウンドでコマンドを起動するために、従来は複雑な Vim script を記述しな
ければならず、プラグインを用いなければ困難でした。
このパッチがマージされれば、Vim script を記述しなくても手軽にバックグラウンド実
行が行えるはずです。</p>

<p>例えば、</p>

<pre><code>:&amp;:vimgrep {pattern} {file} ...
</code></pre>

<p>でバックグラウンドによる grep が実行できます。</p>

<p>他にも <code>call_async()</code>, <code>call_parallel()</code>, <code>call_wait()</code> といった API が追加され
ています。</p>

<p>巨大なパッチなので取り込まれるのには時間がかかりそうだが、夢がある新機能ですね。
余談ですが、このプロジェクトは元々GSoC 2019 だったそうです。</p>

<p><a href="https://github.com/neovim/neovim/pull/9943">https://github.com/neovim/neovim/pull/9943</a></p>

<p><em>This article is made by Vim.</em></p>
]]>
        
    </content>
</entry>

<entry>
    <title>プルダウン後に処理を行う(cellEdited コールバック)</title>
    <link rel="alternate" type="text/html" href="https://www.soum.co.jp/misc/tabulator-tips/35/" />
    <id>tag:sh173.soum.co.jp,2020:/misc//22.2218</id>

    <published>2020-07-29T00:25:00Z</published>
    <updated>2020-07-29T00:25:11Z</updated>

    <summary>今回は editor:&quot;select&quot;で定義したプルダウンから選択した値により ...</summary>
    <author>
        <name>naka</name>
        
    </author>
    
        <category term="Tabulator tips" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="https://www.soum.co.jp/misc/">
        <![CDATA[<p>今回は editor:"select"で定義したプルダウンから選択した値により
処理を行う方法について記述します。</p>

<p>プルダウン後に処理を行うには、cellEdited コールバックを用います。</p>

<p><hr>
Tabulatorドキュメント<a href="http://tabulator.info/docs/4.6/callbacks#cell">「Cell Callbaks ページ」</a> 
の Cell Edited パラグラフより抜粋</p>

<p>cellEdited コールバックはセルのデータが変更されたときに呼び出されます。</p>

<pre><code>var table = new Tabulator("#example-table", {
    cellEdited:function(cell){
        //cell - セルデータ
    },
});
</code></pre>

<hr>

<p>cellEdited 処理は 
<a href="https://www.soum.co.jp/misc/tabulator-tips/14/">「第14回 グループ分け、表示制限」</a> 
でプログラムしています。</p>

<ul>
<li>#table のテーブルでプルダウンを定義。</li>
<li>#filter のテーブルを保存した変数 table でデータを table.setGroupBy() で操作。</li>
</ul>

<h2>処理コード</h2>

<pre><code>cellEdited: function(cell){
    var val = cell.getValue();
    if(val === "日付でグループ分け"){
        if(table)table.setGroupBy('date');
    }
    else if (val === "日付(英)でグループ分け"){
        if(table)table.setGroupBy('dateE');
    }
    else if (val === "月でグループ分け"){
        if(table)table.setGroupBy('month');
    }
    else if(val === "Marのみ表示") {
        if(table)table.setFilter("month","=","Mar");
    }
    else if (val === "日が１０日以上を表示") {
        if(table)table.setFilter("date","&gt;=",10);
    }
    else if (val === "制限解除"){
        if(table)table.clearFilter();
    }

}
</code></pre>

<p>以下、カラム定義、データ定義、実行結果、サンプルコードです。</p>

<h2>カラム定義</h2>

<pre><code>{ title:"日付",     field:"date" },
{ title:"日付(英)", field:"dateE" },
{ title:"月",       field:"month" },
{ title:"日",       field:"date" }
</code></pre>

<h2>データ定義</h2>

<pre><code>{ dateE : "Nov 1", date:"11/1" , month: "Nov", date:1},
{ dateE : "Aug 5", date:"8/5"  , month: "Aug", date:5},
{ dateE : "Mar 30",date:"5/9" ,  month: "Mar", date:9},
{ dateE : "Mar 30",date:"5/3"  , month: "Mar", date:3},
{ dateE : "Mar 30",date:"5/5"  , month: "Mar", date:5},
{ dateE : "Mar 30",date:"5/15" , month: "Mar", date:15},
{ dateE : "Mar 30",date:"5/30" , month: "Mar", date:30},
{ dateE : "Aug 10",date:"8/10" , month: "Aug", date:10},
{ dateE : "Jan 10",date:"1/10" , month: "Jan", date:10},
</code></pre>

<h2>実行結果</h2>

<div id=filter></div>

<p><div id=table></div></p>

<p><div id=table2></div></p>

<h2>サンプルコード</h2>

<pre><code>&lt;!doctype html&gt;
&lt;html lang="ja"&gt;
&lt;head&gt;
&lt;meta charset="utf-8"&gt;
&lt;link href="https://unpkg.com/tabulator-tables@4.6.3/dist/css/tabulator.min.css" rel="stylesheet"&gt;
&lt;script type="text/javascript" src="https://unpkg.com/tabulator-tables@4.6.3/dist/js/tabulator.min.js"&gt;&lt;/script&gt;
&lt;/head&gt;
&lt;body onload="show_table()"&gt;
&lt;h1 id=title&gt; プルダウン後に処理を行う(cellEdited コールバック) &lt;/h1&gt;

&lt;p&gt;&lt;div id="filter"&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;&lt;div id="table"&gt;&lt;/div&gt;&lt;/p&gt;

&lt;script type="text/javascript"&gt;
var show_table=function(){
    var tdata = [
        { dateE : "Nov 1", date:"11/1" , month: "Nov", date:1},
        { dateE : "Aug 5", date:"8/5"  , month: "Aug", date:5},
        { dateE : "Mar 30",date:"5/9" ,  month: "Mar", date:9},
        { dateE : "Mar 30",date:"5/3"  , month: "Mar", date:3},
        { dateE : "Mar 30",date:"5/5"  , month: "Mar", date:5},
        { dateE : "Mar 30",date:"5/15" , month: "Mar", date:15},
        { dateE : "Mar 30",date:"5/30" , month: "Mar", date:30},
        { dateE : "Aug 10",date:"8/10" , month: "Aug", date:10},
        { dateE : "Jan 10",date:"1/10" , month: "Jan", date:10},
    ];
    var table = new Tabulator("#table", {
        groupBy: "dateE",

        data:tdata,
        columns: [
            { title:"日付",     field:"date" },
            { title:"日付(英)", field:"dateE" },
            { title:"月",       field:"month" },
            { title:"日",       field:"date" }
        ]
    });
    new Tabulator("#filter", {
        data:[ {filter:"---"} ],
        columns: [
            {
                title:"表示制限",
                field:"filter",
                editor:"select",
                editorParams:{
                    values:[
                        "日付でグループ分け",
                        "日付(英)でグループ分け",
                        "月でグループ分け",
                        "Marのみ表示",
                        "日が１０日以上を表示",
                        "制限解除"
                    ]
                },
                cellEdited: function(cell){
                    var val = cell.getValue();
                    if(val === "日付でグループ分け"){
                        if(table)table.setGroupBy('date');
                    }
                    else if (val === "日付(英)でグループ分け"){
                        if(table)table.setGroupBy('dateE');
                    }
                    else if (val === "月でグループ分け"){
                        if(table)table.setGroupBy('month');
                    }
                    else if(val === "Marのみ表示") {
                        if(table)table.setFilter("month","=","Mar");
                    }
                    else if (val === "日が１０日以上を表示") {
                        if(table)table.setFilter("date","&gt;=",10);
                    }
                    else if (val === "制限解除"){
                        if(table)table.clearFilter();
                    }

                }
            }
        ]
    });
}
&lt;/script&gt;
</code></pre>

<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<link href="https://unpkg.com/tabulator-tables@4.6.3/dist/css/tabulator.min.css" rel="stylesheet">

<script type="text/javascript" src="https://unpkg.com/tabulator-tables@4.6.3/dist/js/tabulator.min.js"></script>

<script type="text/javascript">
$(function(){show_table()});
var show_table=function(){
    var tdata = [
// defined_data
        { dateE : "Nov 1", date:"11/1" , month: "Nov", date:1},
        { dateE : "Aug 5", date:"8/5"  , month: "Aug", date:5},
        { dateE : "Mar 30",date:"5/9" ,  month: "Mar", date:9},
        { dateE : "Mar 30",date:"5/3"  , month: "Mar", date:3},
        { dateE : "Mar 30",date:"5/5"  , month: "Mar", date:5},
        { dateE : "Mar 30",date:"5/15" , month: "Mar", date:15},
        { dateE : "Mar 30",date:"5/30" , month: "Mar", date:30},
        { dateE : "Aug 10",date:"8/10" , month: "Aug", date:10},
        { dateE : "Jan 10",date:"1/10" , month: "Jan", date:10},
// defined_data
    ];
    var table = new Tabulator("#table", {
        groupBy: "dateE",

        data:tdata,
        columns: [
// defined_columns
            { title:"日付",     field:"date" },
            { title:"日付(英)", field:"dateE" },
            { title:"月",       field:"month" },
            { title:"日",       field:"date" }
// defined_columns
        ]
    });
    new Tabulator("#filter", {
        data:[ {filter:"---"} ],
        columns: [
            {
                title:"表示制限",
                field:"filter",
                editor:"select",
                editorParams:{
                    values:[
                        "日付でグループ分け",
                        "日付(英)でグループ分け",
                        "月でグループ分け",
                        "Marのみ表示",
                        "日が１０日以上を表示",
                        "制限解除"
                    ]
                },
// defined_function
                cellEdited: function(cell){
                    var val = cell.getValue();
                    if(val === "日付でグループ分け"){
                        if(table)table.setGroupBy('date');
                    }
                    else if (val === "日付(英)でグループ分け"){
                        if(table)table.setGroupBy('dateE');
                    }
                    else if (val === "月でグループ分け"){
                        if(table)table.setGroupBy('month');
                    }
                    else if(val === "Marのみ表示") {
                        if(table)table.setFilter("month","=","Mar");
                    }
                    else if (val === "日が１０日以上を表示") {
                        if(table)table.setFilter("date",">=",10);
                    }
                    else if (val === "制限解除"){
                        if(table)table.clearFilter();
                    }

                }
// defined_function
            }
        ]
    });
}

</script>
]]>
        
    </content>
</entry>

<entry>
    <title>任意の文字列をソートする</title>
    <link rel="alternate" type="text/html" href="https://www.soum.co.jp/misc/tabulator-tips/34/" />
    <id>tag:sh173.soum.co.jp,2020:/misc//22.2217</id>

    <published>2020-07-22T00:10:00Z</published>
    <updated>2020-07-22T00:10:05Z</updated>

    <summary>ソートは「第11回 sorter で 日付をソートする」 を記述しましたが、少し...</summary>
    <author>
        <name>naka</name>
        
    </author>
    
        <category term="Tabulator tips" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="https://www.soum.co.jp/misc/">
        <![CDATA[<p>ソートは<a href="https://www.soum.co.jp/misc/tabulator-tips/11/">「第11回 sorter で 日付をソートする」</a>
を記述しましたが、少しわかりにくかったので簡単な例を記述します。</p>

<p>任意の文字列をソートするにはソートしたい文字列の順番を配列で定義します。</p>

<p>サンプルコードでは文字列の順番を以下のように定義しました。</p>

<pre><code>const list = [ "apple", "orange", "banana", "pineapple" ];
</code></pre>

<p>ソート処理は indexOf 関数により配列のインデックス番号を取得して、行います。</p>

<pre><code>sorter:function(a,b){
    // a、b-比較される2つの値
    return list.indexOf(a)-list.indexOf(b)
}
</code></pre>

<p>アロー関数を用いると return を省略できるので 一行で書くことができます。</p>

<pre><code>sorter:(a,b)=&gt;list.indexOf(a)-list.indexOf(b)
</code></pre>

<p>以下、カラム定義、データ定義、実行結果、サンプルコードです。</p>

<h2>カラム定義</h2>

<pre><code>{
    title:"item",
    field:"item",
    sorter:(a,b)=&gt;list.indexOf(a)-list.indexOf(b)
}
</code></pre>

<h2>データ定義</h2>

<pre><code>data: [
    { item: "banana" },
    { item: "apple" },
    { item: "orange" },
    { item: "pineapple" }
],
</code></pre>

<h2>実行結果</h2>

<div id=filter></div>

<p><div id=table></div></p>

<p><div id=table2></div></p>

<h2>サンプルコード</h2>

<pre><code>&lt;!doctype html&gt;
&lt;html lang="ja"&gt;
&lt;head&gt;
&lt;meta charset="utf-8"&gt;
&lt;link href="https://unpkg.com/tabulator-tables@4.6.3/dist/css/tabulator.min.css" rel="stylesheet"&gt;
&lt;script type="text/javascript" src="https://unpkg.com/tabulator-tables@4.6.3/dist/js/tabulator.min.js"&gt;&lt;/script&gt;
&lt;/head&gt;
&lt;body onload="show_table()"&gt;
&lt;h1 id=title&gt; 任意の文字列をソートする &lt;/h1&gt;
&lt;div id="table"&gt;&lt;/div&gt;

&lt;script type="text/javascript"&gt;
const list = [ "apple", "orange", "banana", "pineapple" ];
const show_table=function(){
    new Tabulator("#table", {
        data: [
            { item: "banana" },
            { item: "apple" },
            { item: "orange" },
            { item: "pineapple" }
        ],
        columns: [
            {
                title:"item",
                field:"item",
                sorter:(a,b)=&gt;list.indexOf(a)-list.indexOf(b)
            }
        ]
    });
}
&lt;/script&gt;
</code></pre>

<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<link href="https://unpkg.com/tabulator-tables@4.6.3/dist/css/tabulator.min.css" rel="stylesheet">

<script type="text/javascript" src="https://unpkg.com/tabulator-tables@4.6.3/dist/js/tabulator.min.js"></script>

<script type="text/javascript">
$(function(){show_table()});
// defined_function
const list = [ "apple", "orange", "banana", "pineapple" ];
// defined_function
const show_table=function(){
    new Tabulator("#table", {
// defined_data
        data: [
            { item: "banana" },
            { item: "apple" },
            { item: "orange" },
            { item: "pineapple" }
        ],
// defined_data
        columns: [
// defined_columns
            {
                title:"item",
                field:"item",
                sorter:(a,b)=>list.indexOf(a)-list.indexOf(b)
            }
// defined_columns
        ]
    });
}

</script>
]]>
        
    </content>
</entry>

<entry>
    <title>ajaxでjsonデータ読み込み後、データ修正</title>
    <link rel="alternate" type="text/html" href="https://www.soum.co.jp/misc/tabulator-tips/33/" />
    <id>tag:sh173.soum.co.jp,2020:/misc//22.2214</id>

    <published>2020-07-15T00:08:00Z</published>
    <updated>2020-07-15T00:08:21Z</updated>

    <summary>今回は、ajax で json データを読み込み後、データ修正を行います。 aj...</summary>
    <author>
        <name>naka</name>
        
    </author>
    
        <category term="Tabulator tips" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="https://www.soum.co.jp/misc/">
        <![CDATA[<p>今回は、ajax で json データを読み込み後、データ修正を行います。</p>

<p>ajax で json データを読み込み後、データ修正は ajaxResponse コールバックに
指定した関数で操作を行います。</p>

<hr />

<blockquote>
  <p>Tabulatorドキュメント<a href="
http://tabulator.info/docs/4.6/callbacks#ajax
">「Ajax Response」</a>より抜粋</p>

<p>ajaxResponse コールバックは、ajax リクエストが成功した時に呼び出されます。
このコールバックでデータを変更することができます。
データは return する必要があります。
return しない場合、データは表示されません。</p>
</blockquote>

<hr />

<p>ajaxURL 属性で読み込む json ファイルを指定します。
サンプルコードを実行する場合は、データ定義の内容を ajax.json というファイルに保存して、サンプルコードと同じディレクトリに置いてください。</p>

<pre><code>ajaxURL: "ajax.json"
</code></pre>

<p>ajaxResponse コールバックで、
name_date フィールド(タイトル:"日付(名称)")
に値を設定する処理を行います。</p>

<pre><code>ajaxResponse:function(url,params,response){
    //url - リクエストURL
    //params - リクエストで渡されるパラメーター
    //response - ajax から渡されたJSONオブジェクト
    response.forEach(item=&gt;{
        item.name_date = `${item.date}(${item.name})`;
    });
    // 修正したデータを返す
    return response;
},
</code></pre>

<p>以下、カラム定義、データ定義、実行結果、サンプルコードです。</p>

<h2>カラム定義</h2>

<pre><code>let columns=[
      {title:"名称", field:"name"},
      {title:"日付", field:"date"},
      {title:"日付(名称)", field:"name_date"},
  ];
</code></pre>

<h2>データ定義</h2>

<pre><code>[
  {
    "name": "May",
    "date": "2019/5"
  },
  {
    "name": "April",
    "date": "2019/4"
  }
]
</code></pre>

<h2>実行結果</h2>

<div id=filter></div>

<p><div id=table></div></p>

<p><div id=table2></div></p>

<h2>サンプルコード</h2>

<pre><code>&lt;!doctype html&gt;
&lt;html lang="ja"&gt;
&lt;head&gt;
&lt;meta charset="utf-8"&gt;
&lt;link href="https://unpkg.com/tabulator-tables@4.6.3/dist/css/tabulator.min.css" rel="stylesheet"&gt;
&lt;script type="text/javascript" src="https://unpkg.com/tabulator-tables@4.6.3/dist/js/tabulator.min.js"&gt;&lt;/script&gt;
&lt;/head&gt;
&lt;body onload="show_table()"&gt;
&lt;h1 id=title&gt;ajaxでjsonデータ読み込み後、データ修正&lt;/h1&gt;
&lt;div id="table"&gt;&lt;/div&gt;
&lt;script type="text/javascript"&gt;
const show_table = function(){
  let columns=[
        {title:"名称", field:"name"},
        {title:"日付", field:"date"},
        {title:"日付(名称)", field:"name_date"},
    ];
  new Tabulator("#table", {
    ajaxResponse:function(url,params,response){
        //url - リクエストURL
        //params - リクエストで渡されるパラメーター
        //response - ajax から渡されたJSONオブジェクト
        response.forEach(item=&gt;{
            item.name_date = `${item.date}(${item.name})`;
        });
        // 修正したデータを返す
        return response;
    },
    ajaxURL: "ajax.json",
    columns:columns
  });
}
&lt;/script&gt;
</code></pre>

<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<link href="https://unpkg.com/tabulator-tables@4.6.3/dist/css/tabulator.min.css" rel="stylesheet">

<script type="text/javascript" src="https://unpkg.com/tabulator-tables@4.6.3/dist/js/tabulator.min.js"></script>

<script type="text/javascript">
$(function(){show_table()});
const show_table = function(){
// defined_columns
  let columns=[
        {title:"名称", field:"name"},
        {title:"日付", field:"date"},
        {title:"日付(名称)", field:"name_date"},
    ];
// defined_columns
  new Tabulator("#table", {
// defined_function
    ajaxResponse:function(url,params,response){
        //url - リクエストURL
        //params - リクエストで渡されるパラメーター
        //response - ajax から渡されたJSONオブジェクト
        response.forEach(item=>{
            item.name_date = `${item.date}(${item.name})`;
        });
        // 修正したデータを返す
        return response;
    },
// defined_function
    ajaxURL: "ajax.json",
    columns:columns
  });
}

</script>
]]>
        
    </content>
</entry>

<entry>
    <title>横スクロール表示(scrollToColumns)</title>
    <link rel="alternate" type="text/html" href="https://www.soum.co.jp/misc/tabulator-tips/32/" />
    <id>tag:sh173.soum.co.jp,2020:/misc//22.2212</id>

    <published>2020-07-08T01:50:00Z</published>
    <updated>2020-07-08T01:50:20Z</updated>

    <summary>今回は scrollToColumns() を使用して、 横に長いデータの途中か...</summary>
    <author>
        <name>naka</name>
        
    </author>
    
        <category term="Tabulator tips" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="https://www.soum.co.jp/misc/">
        <![CDATA[<p>今回は
scrollToColumns() を使用して、
横に長いデータの途中から表示する方法について記述します。</p>

<p>scrollToColumns()の仕様は以下の通りです。</p>

<hr />

<blockquote>
  <p>Tabulatorドキュメント<a href="
http://tabulator.info/docs/4.6/navigation#scroll-column
">「Scroll To Columns」</a> </p>
</blockquote>

<pre><code>table.scrollToColumn("age", "middle", false); // ageフィールドが表示されていない場合は、フィールドを中央にスクロール
</code></pre>

<blockquote>
  <p>最初の引数はスクロールする列の標準列コンポーネント検索オプションのいずれかである必要があります。</p>

<p>2番目の引数はオプション。列の位置を設定するために使用されます。
値は"left", "middle", "right" 。
省略した場合、
デフォルトのscrollToColumnPositionオプションの値("left")に設定されます。</p>

<p>3番目の引数はオプション。列がすでに表示されている場合にテーブルをスクロールするかどうかを設定する。スクロールする場合はtrue、スクロールしない場合はfalse、省略した場合は
デフォルトのscrollToColumnIfVisibleオプションの値("true")に設定されます。</p>
</blockquote>

<hr />

<p>以下、カラム定義、データ定義、実行結果、サンプルコードです。</p>

<h2>カラム定義</h2>

<pre><code>const get_columns=()=&gt;{
    let col = [];
    for(let i=0;i&lt;50;i++){
        col.push({ title:`a${i}`, field:`a${i}`});
    }
    return col;
}
</code></pre>

<h2>データ定義</h2>

<pre><code>const get_data=()=&gt;{
    let data = {};
    for(let i=0;i&lt;50;i++){
        data[`a${i}`] = i;
    }
    return [data,data,data];
}
</code></pre>

<h2>実行結果</h2>

<div id=filter></div>

<p><div id=table></div></p>

<p><div id=table2></div></p>

<h2>サンプルコード</h2>

<pre><code>&lt;!doctype html&gt;
&lt;html lang="ja"&gt;
&lt;head&gt;
&lt;meta charset="utf-8"&gt;
&lt;link href="https://unpkg.com/tabulator-tables@4.6.3/dist/css/tabulator.min.css" rel="stylesheet"&gt;
&lt;script type="text/javascript" src="https://unpkg.com/tabulator-tables@4.6.3/dist/js/tabulator.min.js"&gt;&lt;/script&gt;
&lt;/head&gt;
&lt;body onload=show_table()&gt;
&lt;h1 id=title&gt;横スクロール表示(scrollToColumns) &lt;/h1&gt;

&lt;p&gt;&lt;div id="table"&gt;&lt;/div&gt;&lt;/p&gt;

&lt;script type="text/javascript"&gt;
const get_columns=()=&gt;{
    let col = [];
    for(let i=0;i&lt;50;i++){
        col.push({ title:`a${i}`, field:`a${i}`});
    }
    return col;
}
const get_data=()=&gt;{
    let data = {};
    for(let i=0;i&lt;50;i++){
        data[`a${i}`] = i;
    }
    return [data,data,data];
}
const show_table=function(){
    let table = new Tabulator("#table", {
        data:get_data(),
        columns: get_columns(),
    });
    table.scrollToColumn("a15", "left", true)
    .then(()=&gt;{console.log('scroll success')})
    .catch((error)=&gt;{console.log(error, 'scroll fail')});
}
&lt;/script&gt;
</code></pre>

<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<link href="https://unpkg.com/tabulator-tables@4.6.3/dist/css/tabulator.min.css" rel="stylesheet">

<script type="text/javascript" src="https://unpkg.com/tabulator-tables@4.6.3/dist/js/tabulator.min.js"></script>

<script type="text/javascript">
$(function(){show_table()});
// defined_columns
const get_columns=()=>{
    let col = [];
    for(let i=0;i<50;i++){
        col.push({ title:`a${i}`, field:`a${i}`});
    }
    return col;
}
// defined_columns
// defined_data
const get_data=()=>{
    let data = {};
    for(let i=0;i<50;i++){
        data[`a${i}`] = i;
    }
    return [data,data,data];
}
// defined_data
const show_table=function(){
    let table = new Tabulator("#table", {
        data:get_data(),
        columns: get_columns(),
    });
// defined_function
    table.scrollToColumn("a15", "left", true)
    .then(()=>{console.log('scroll success')})
    .catch((error)=>{console.log(error, 'scroll fail')});
// defined_function
}

</script>
]]>
        
    </content>
</entry>

<entry>
    <title>チェックボックス</title>
    <link rel="alternate" type="text/html" href="https://www.soum.co.jp/misc/tabulator-tips/31/" />
    <id>tag:sh173.soum.co.jp,2020:/misc//22.2211</id>

    <published>2020-07-01T00:55:00Z</published>
    <updated>2020-07-01T00:55:10Z</updated>

    <summary>今回はチェックボックスです。 formatter:&quot;tickCross&quot;を指定す...</summary>
    <author>
        <name>naka</name>
        
    </author>
    
        <category term="Tabulator tips" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="https://www.soum.co.jp/misc/">
        <![CDATA[<p>今回はチェックボックスです。
formatter:"tickCross"を指定することでチェックボックスを表示します。</p>

<p>チェックボックスの表示は以下になります。</p>

<ul>
<li>true: 緑のチェック表示</li>
<li>false: 赤のxマーク表示</li>
</ul>

<p>上記以外の表示にしたい場合は、formatterParamsの設定で変更します。</p>

<pre><code>formatterParams:{
    tickElement:"&lt;b&gt;check&lt;/b&gt;", // true の時の表示
    crossElement:"not check", // false の時の表示
}}
</code></pre>

<p>カラム定義 editor の設定により、操作可、不可になります。</p>

<ul>
<li>editor: true の場合、セルのチェック操作が可能</li>
<li>editor: false, 設定しない場合、表示のみ</li>
</ul>

<p>※ このページの「実行結果」を操作すると、チェック表示がずれます。
これは、このページの css 設定が影響しているようです。
サンプルコードを実行した場合、チェック表示は特にずれることはないようです。</p>

<p>以下、カラム定義、データ定義、実行結果、サンプルコードです。</p>

<h2>カラム定義</h2>

<pre><code>columns: [
{title:"操作可能1",field:"canEdit1",formatter:"tickCross",
    editor:true},
{title:"操作可能2",field:"canEdit2",formatter:"tickCross",
    editor:true, 
    formatterParams:{
        tickElement: "&lt;b&gt;check&lt;/b&gt;",
        crossElement:"not check"
    }
},
{title:"表示のみ1",field:"cantEdit1",formatter:"tickCross"},
{title:"表示のみ2",field:"cantEdit2",formatter:"tickCross"},
],
</code></pre>

<h2>データ定義</h2>

<pre><code>data:[
    {canEdit1:true, canEdit2:true, cantEdit1:true, cantEdit2:false}
]
</code></pre>

<h2>実行結果</h2>

<div id=filter></div>

<p><div id=table></div></p>

<p><div id=table2></div></p>

<h2>サンプルコード</h2>

<pre><code>&lt;!doctype html&gt;
&lt;html lang="ja"&gt;
&lt;head&gt;
&lt;meta charset="utf-8"&gt;
&lt;link href="https://unpkg.com/tabulator-tables@4.5.3/dist/css/tabulator.min.css" rel="stylesheet"&gt;
&lt;script type="text/javascript" src="https://unpkg.com/tabulator-tables@4.5.3/dist/js/tabulator.min.js"&gt;&lt;/script&gt;
&lt;style type="text/css"&gt;
{
    padding:100;
}
&lt;/style&gt;
&lt;/head&gt;
&lt;body onload=show_table()&gt;
&lt;h1 id=title&gt;チェックボックス&lt;/h1&gt;
&lt;div id="table"&gt;&lt;/div&gt;
&lt;script type="text/javascript"&gt;
const show_table=function(){
    new Tabulator("#table", {
        columns: [
        {title:"操作可能1",field:"canEdit1",formatter:"tickCross",
            editor:true},
        {title:"操作可能2",field:"canEdit2",formatter:"tickCross",
            editor:true, 
            formatterParams:{
                tickElement: "&lt;b&gt;check&lt;/b&gt;",
                crossElement:"not check"
            }
        },
        {title:"表示のみ1",field:"cantEdit1",formatter:"tickCross"},
        {title:"表示のみ2",field:"cantEdit2",formatter:"tickCross"},
        ],
        data:[
            {canEdit1:true, canEdit2:true, cantEdit1:true, cantEdit2:false}
        ]
    });
};
&lt;/script&gt;
</code></pre>

<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<link href="https://unpkg.com/tabulator-tables@4.5.3/dist/css/tabulator.min.css" rel="stylesheet">

<script type="text/javascript" src="https://unpkg.com/tabulator-tables@4.5.3/dist/js/tabulator.min.js"></script>

<script type="text/javascript">
$(function(){show_table()});
const show_table=function(){
    new Tabulator("#table", {
// defined_columns
        columns: [
        {title:"操作可能1",field:"canEdit1",formatter:"tickCross",
            editor:true},
        {title:"操作可能2",field:"canEdit2",formatter:"tickCross",
            editor:true, 
            formatterParams:{
                tickElement: "<b>check</b>",
                crossElement:"not check"
            }
        },
        {title:"表示のみ1",field:"cantEdit1",formatter:"tickCross"},
        {title:"表示のみ2",field:"cantEdit2",formatter:"tickCross"},
        ],
// defined_columns
// defined_data
        data:[
            {canEdit1:true, canEdit2:true, cantEdit1:true, cantEdit2:false}
        ]
// defined_data
    });
};

</script>
]]>
        
    </content>
</entry>

<entry>
    <title>列の値を折れ線グラフ表示</title>
    <link rel="alternate" type="text/html" href="https://www.soum.co.jp/misc/tabulator-tips/30/" />
    <id>tag:sh173.soum.co.jp,2020:/misc//22.2210</id>

    <published>2020-06-24T00:05:00Z</published>
    <updated>2020-06-24T00:05:08Z</updated>

    <summary>前回は行の値を折れ線グラフにしましたが、今回は bottomCalc に列の値を...</summary>
    <author>
        <name>naka</name>
        
    </author>
    
        <category term="Tabulator tips" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="https://www.soum.co.jp/misc/">
        <![CDATA[<p>前回は行の値を折れ線グラフにしましたが、今回は bottomCalc に列の値を折れ線グラフ表示します。</p>

<p>主な処理は以下の通り、</p>

<ul>
<li>列の値の配列(values)を bottomCalc のカスタム関数 saveCellData() で保存する。</li>
<li>bottomCalcFormatter のカスタム関数 lineFormatter()で保存した列の値の配列(values)を参照して折れ線グラフを描画する。</li>
</ul>

<p>sparkline, jquery は 以下の cdn を使用します。</p>

<pre><code>&lt;script src="https://code.jquery.com/jquery-3.4.1.min.js"&gt;&lt;/script&gt;
&lt;script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-sparklines/2.1.2/jquery.sparkline.min.js"&gt;&lt;/script&gt;
</code></pre>

<p>以下が折れ線グラフを描画する関数です。</p>

<p>「第29回 行の値を折れ線グラフ表示」
と異なるのは、表示する値を bottomCalc で保存している点です。</p>

<pre><code>// cell-セルデータ
// formatterParams-列に設定されたパラメーター
// onRendered-formatterがレンダリングされたときに呼び出す関数
const lineFormatter=(cell,formatterParams,onRendered)=&gt;{
    // 保存した列の値の配列を参照して折れ線グラフを描画する。
    let values = cell.getValue();
    onRendered(()=&gt;$(cell.getElement())
                    .sparkline(values,{width:"100%",type:"line"})
    );
}
// 列の値の配列を保存する。
const saveCellData=values=&gt;{
    return values;
}
</code></pre>

<p>以下、カラム定義、データ定義、実行結果、サンプルコードです。</p>

<h2>カラム定義</h2>

<pre><code>const get_column=()=&gt;{
    return [
    {title:"aa1",field:"aa1",align:"right",
        bottomCalc:saveCellData, bottomCalcFormatter: lineFormatter},
    {title:"aa2",field:"aa2",align:"right",
        bottomCalc:saveCellData, bottomCalcFormatter: lineFormatter},
    {title:"aa3",field:"aa3",align:"right",
        bottomCalc:saveCellData, bottomCalcFormatter: lineFormatter}
    ];
};
</code></pre>

<h2>データ定義</h2>

<pre><code>const get_data=()=&gt;{
    return [
        {"aa1":100, "aa2":200, "aa3":300 },
        {"aa1":120, "aa2":150, "aa3":100 },
        {"aa1":150, "aa2":300, "aa3": 50 }
    ];
}
</code></pre>

<h2>実行結果</h2>

<div id=filter></div>

<p><div id=table></div></p>

<p><div id=table2></div></p>

<h2>サンプルコード</h2>

<pre><code>&lt;!doctype html&gt;
&lt;html lang="ja"&gt;
&lt;head&gt;
&lt;meta charset="utf-8"&gt;
&lt;link href="https://unpkg.com/tabulator-tables@4.5.3/dist/css/tabulator.min.css" rel="stylesheet"&gt;
&lt;script type="text/javascript" src="https://unpkg.com/tabulator-tables@4.5.3/dist/js/tabulator.min.js"&gt;&lt;/script&gt;
&lt;script src="https://code.jquery.com/jquery-3.4.1.min.js"&gt;&lt;/script&gt;
&lt;script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-sparklines/2.1.2/jquery.sparkline.min.js"&gt;&lt;/script&gt;
&lt;/head&gt;
&lt;body onload=show_table()&gt;
&lt;h1 id=title&gt;列の値を折れ線グラフ表示&lt;/h1&gt;
&lt;div id="table"&gt;&lt;/div&gt;
&lt;script type="text/javascript"&gt;
// cell-セルデータ
// formatterParams-列に設定されたパラメーター
// onRendered-formatterがレンダリングされたときに呼び出す関数
const lineFormatter=(cell,formatterParams,onRendered)=&gt;{
    // 保存した列の値の配列を参照して折れ線グラフを描画する。
    let values = cell.getValue();
    onRendered(()=&gt;$(cell.getElement())
                    .sparkline(values,{width:"100%",type:"line"})
    );
}
// 列の値の配列を保存する。
const saveCellData=values=&gt;{
    return values;
}
const get_column=()=&gt;{
    return [
    {title:"aa1",field:"aa1",align:"right",
        bottomCalc:saveCellData, bottomCalcFormatter: lineFormatter},
    {title:"aa2",field:"aa2",align:"right",
        bottomCalc:saveCellData, bottomCalcFormatter: lineFormatter},
    {title:"aa3",field:"aa3",align:"right",
        bottomCalc:saveCellData, bottomCalcFormatter: lineFormatter}
    ];
};
const get_data=()=&gt;{
    return [
        {"aa1":100, "aa2":200, "aa3":300 },
        {"aa1":120, "aa2":150, "aa3":100 },
        {"aa1":150, "aa2":300, "aa3": 50 }
    ];
}
const show_table=function(){
    new Tabulator("#table", {
        data: get_data(),
        columns:get_column(),
    });
};
&lt;/script&gt;
</code></pre>

<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<link href="https://unpkg.com/tabulator-tables@4.5.3/dist/css/tabulator.min.css" rel="stylesheet">

<script type="text/javascript" src="https://unpkg.com/tabulator-tables@4.5.3/dist/js/tabulator.min.js"></script>
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-sparklines/2.1.2/jquery.sparkline.min.js"></script>

<script type="text/javascript">
$(function(){show_table()});
// defined_function
// cell-セルデータ
// formatterParams-列に設定されたパラメーター
// onRendered-formatterがレンダリングされたときに呼び出す関数
const lineFormatter=(cell,formatterParams,onRendered)=>{
    // 保存した列の値の配列を参照して折れ線グラフを描画する。
    let values = cell.getValue();
    onRendered(()=>$(cell.getElement())
                    .sparkline(values,{width:"100%",type:"line"})
    );
}
// 列の値の配列を保存する。
const saveCellData=values=>{
    return values;
}
// defined_function
// defined_columns
const get_column=()=>{
    return [
    {title:"aa1",field:"aa1",align:"right",
        bottomCalc:saveCellData, bottomCalcFormatter: lineFormatter},
    {title:"aa2",field:"aa2",align:"right",
        bottomCalc:saveCellData, bottomCalcFormatter: lineFormatter},
    {title:"aa3",field:"aa3",align:"right",
        bottomCalc:saveCellData, bottomCalcFormatter: lineFormatter}
    ];
};
// defined_columns
// defined_data
const get_data=()=>{
    return [
        {"aa1":100, "aa2":200, "aa3":300 },
        {"aa1":120, "aa2":150, "aa3":100 },
        {"aa1":150, "aa2":300, "aa3": 50 }
    ];
}
// defined_data
const show_table=function(){
    new Tabulator("#table", {
        data: get_data(),
        columns:get_column(),
    });
};

</script>
]]>
        
    </content>
</entry>

<entry>
    <title>行の値を折れ線グラフ表示</title>
    <link rel="alternate" type="text/html" href="https://www.soum.co.jp/misc/tabulator-tips/29/" />
    <id>tag:sh173.soum.co.jp,2020:/misc//22.2209</id>

    <published>2020-06-17T00:30:00Z</published>
    <updated>2020-06-17T00:30:11Z</updated>

    <summary>今回は行の値を折れ線グラフ表示します。 主な処理は以下の通り、 aa1,aa2,...</summary>
    <author>
        <name>naka</name>
        
    </author>
    
        <category term="Tabulator tips" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="https://www.soum.co.jp/misc/">
        <![CDATA[<p>今回は行の値を折れ線グラフ表示します。</p>

<p>主な処理は以下の通り、</p>

<ul>
<li>aa1,aa2,aa3のセル値を line のセルで折れ線グラフ表示にする。</li>
<li>aa1,aa2,aa3のセルの合計値(bottomCalc)を line のセルで折れ線グラフ表示にする。</li>
<li>formatter属性, bottomCalcFormatter属性で折れ線表示用の関数(lineFormatter)を指定する。formatter, bottomCalcFormatter で折れ線グラフを表示する関数(lineFormatter)は同じものです。</li>
</ul>

<p>なお、tabulator 4.4.3 の場合、bottomCalcFormatter で指定した関数内で 
onRendered(formatterがレンダリングされたときに呼び出す関数)が呼び出されず
折れ線グラフ表示処理が動作しないため、tabulator4.5.3 以上を使用する必要があります。</p>

<p>今回は tabulator4.5.3 を使用します。
sparkline, jquery は 以下の cdn を使用します。</p>

<pre><code>&lt;link href="https://unpkg.com/tabulator-tables@4.5.3/dist/css/tabulator.min.css" rel="stylesheet"&gt;
&lt;script type="text/javascript" src="https://unpkg.com/tabulator-tables@4.5.3/dist/js/tabulator.min.js"&gt;&lt;/script&gt;
&lt;script src="https://code.jquery.com/jquery-3.4.1.min.js"&gt;&lt;/script&gt;
&lt;script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-sparklines/2.1.2/jquery.sparkline.min.js"&gt;&lt;/script&gt;
</code></pre>

<p>以下が折れ線グラフを描画する関数です。</p>

<pre><code>// cell-セルデータ
// formatterParams-列に設定されたパラメーター
// onRendered-formatterがレンダリングされたときに呼び出す関数
const lineFormatter=(cell,formatterParams,onRendered)=&gt;{
    let ar = [];
    let data = cell.getData();
    for(let i in data){
        if(i.match(/^aa/)){
            // 'aa1,aa2,aa3' のデータを保存
            ar.push(data[i]);
        }
    }
    onRendered(()=&gt;$(cell.getElement())
                    .sparkline(ar,{width:"100%",type:"line"})
    );
}
</code></pre>

<p>以下、カラム定義、データ定義、実行結果、サンプルコードです。</p>

<h2>カラム定義</h2>

<pre><code>const get_column=()=&gt;{
    return [
    {title:"aa1",field:"aa1",align:"right",bottomCalc:"sum"},
    {title:"aa2",field:"aa2",align:"right",bottomCalc:"sum"},
    {title:"aa3",field:"aa3",align:"right",bottomCalc:"sum"},
    {title:"line",field:"line",width:100,
        formatter:lineFormatter, bottomCalcFormatter:lineFormatter},
    ];
};
</code></pre>

<h2>データ定義</h2>

<pre><code>const get_data=()=&gt;{
    return [
        {"aa1":100, "aa2":200, "aa3":300 },
        {"aa1":120, "aa2":150, "aa3":100 },
        {"aa1":150, "aa2":300, "aa3": 50 }
    ];
}
</code></pre>

<h2>実行結果</h2>

<div id=filter></div>

<p><div id=table></div></p>

<p><div id=table2></div></p>

<h2>サンプルコード</h2>

<pre><code>&lt;!doctype html&gt;
&lt;html lang="ja"&gt;
&lt;head&gt;
&lt;meta charset="utf-8"&gt;
&lt;link href="https://unpkg.com/tabulator-tables@4.5.3/dist/css/tabulator.min.css" rel="stylesheet"&gt;
&lt;script type="text/javascript" src="https://unpkg.com/tabulator-tables@4.5.3/dist/js/tabulator.min.js"&gt;&lt;/script&gt;
&lt;script src="https://code.jquery.com/jquery-3.4.1.min.js"&gt;&lt;/script&gt;
&lt;script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-sparklines/2.1.2/jquery.sparkline.min.js"&gt;&lt;/script&gt;
&lt;/head&gt;
&lt;body onload=show_table()&gt;
&lt;h1 id=title&gt;行の値を折れ線グラフ表示&lt;/h1&gt;
&lt;div id="table"&gt;&lt;/div&gt;
&lt;script type="text/javascript"&gt;
// cell-セルデータ
// formatterParams-列に設定されたパラメーター
// onRendered-formatterがレンダリングされたときに呼び出す関数
const lineFormatter=(cell,formatterParams,onRendered)=&gt;{
    let ar = [];
    let data = cell.getData();
    for(let i in data){
        if(i.match(/^aa/)){
            // 'aa1,aa2,aa3' のデータを保存
            ar.push(data[i]);
        }
    }
    onRendered(()=&gt;$(cell.getElement())
                    .sparkline(ar,{width:"100%",type:"line"})
    );
}
const get_column=()=&gt;{
    return [
    {title:"aa1",field:"aa1",align:"right",bottomCalc:"sum"},
    {title:"aa2",field:"aa2",align:"right",bottomCalc:"sum"},
    {title:"aa3",field:"aa3",align:"right",bottomCalc:"sum"},
    {title:"line",field:"line",width:100,
        formatter:lineFormatter, bottomCalcFormatter:lineFormatter},
    ];
};
const get_data=()=&gt;{
    return [
        {"aa1":100, "aa2":200, "aa3":300 },
        {"aa1":120, "aa2":150, "aa3":100 },
        {"aa1":150, "aa2":300, "aa3": 50 }
    ];
}
const show_table=function(){
    new Tabulator("#table", {
        data: get_data(),
        columns:get_column(),
    });
};
&lt;/script&gt;
</code></pre>

<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<link href="https://unpkg.com/tabulator-tables@4.5.3/dist/css/tabulator.min.css" rel="stylesheet">

<script type="text/javascript" src="https://unpkg.com/tabulator-tables@4.5.3/dist/js/tabulator.min.js"></script>
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-sparklines/2.1.2/jquery.sparkline.min.js"></script>

<script type="text/javascript">
$(function(){show_table()});
// defined_function
// cell-セルデータ
// formatterParams-列に設定されたパラメーター
// onRendered-formatterがレンダリングされたときに呼び出す関数
const lineFormatter=(cell,formatterParams,onRendered)=>{
    let ar = [];
    let data = cell.getData();
    for(let i in data){
        if(i.match(/^aa/)){
            // 'aa1,aa2,aa3' のデータを保存
            ar.push(data[i]);
        }
    }
    onRendered(()=>$(cell.getElement())
                    .sparkline(ar,{width:"100%",type:"line"})
    );
}
// defined_function
// defined_columns
const get_column=()=>{
    return [
    {title:"aa1",field:"aa1",align:"right",bottomCalc:"sum"},
    {title:"aa2",field:"aa2",align:"right",bottomCalc:"sum"},
    {title:"aa3",field:"aa3",align:"right",bottomCalc:"sum"},
    {title:"line",field:"line",width:100,
        formatter:lineFormatter, bottomCalcFormatter:lineFormatter},
    ];
};
// defined_columns
// defined_data
const get_data=()=>{
    return [
        {"aa1":100, "aa2":200, "aa3":300 },
        {"aa1":120, "aa2":150, "aa3":100 },
        {"aa1":150, "aa2":300, "aa3": 50 }
    ];
}
// defined_data
const show_table=function(){
    new Tabulator("#table", {
        data: get_data(),
        columns:get_column(),
    });
};

</script>
]]>
        
    </content>
</entry>

<entry>
    <title>HTML テーブルを Tabulator で表示</title>
    <link rel="alternate" type="text/html" href="https://www.soum.co.jp/misc/tabulator-tips/28/" />
    <id>tag:sh173.soum.co.jp,2020:/misc//22.2203</id>

    <published>2020-06-10T01:17:00Z</published>
    <updated>2020-06-10T01:17:09Z</updated>

    <summary>Tabulator は HTMLテーブルの id を指定することでテーブルのデー...</summary>
    <author>
        <name>naka</name>
        
    </author>
    
        <category term="Tabulator tips" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="https://www.soum.co.jp/misc/">
        <![CDATA[<p>Tabulator は HTMLテーブルの id を指定することでテーブルのデータ
を読み込み、表示することができます。</p>

<hr />

<blockquote>
  <p>Tabulatorドキュメント<a href="http://tabulator.info/docs/4.4/data#table">Load Data from HTML Table</a>
より抜粋</p>

<p>HTMLテーブル要素から直接Tabulatorテーブルを作成できます。 columnsオプションを使用して通常の方法で列を定義するか、テーブルのtheadのth要素として列を設定できます。
テーブルのtbodyにあるデータの行はすべて、結果のテーブルに表示されるtabulatorデータに自動的に変換されます。
テーブルヘッダーセルでwidth属性を定義する場合、これを使用してTabulatorの列の幅を設定します。</p>
</blockquote>

<hr />

<table id="table" border=1>
<thead>
    <tr><th>ヘッダー1</th><th >ヘッダー2</th></tr>
</thead>
<tbody>
       <tr><td>1000</td><td>2000</td></tr>
       <tr><td>1500</td><td>30000</td></tr>
</tbody>
</table>

<p>テーブルヘッダーの文字列を指定して、カラム定義をすることができます。</p>

<pre><code>var t = new Tabulator("#table",{
  columns: [
    {title:"ヘッダー1",align:"right",bottomCalc:"sum"},
    {title:"ヘッダー2",align:"center",formatter:"money",width:200} 
  ]
})
</code></pre>

<p>HTMLのテーブルになれているならテーブルでデータを記述して、
Tabulator でカラム定義するほうが、簡単かもしれません。
また、既存の HTMLテーブルを Tabulator フォーマットで
表示するのに便利です。</p>

<h2>データ定義</h2>

<pre><code>&lt;table id="table" border=1&gt;
&lt;thead&gt;
    &lt;tr&gt;&lt;th&gt;ヘッダー1&lt;/th&gt;&lt;th &gt;ヘッダー2&lt;/th&gt;&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
       &lt;tr&gt;&lt;td&gt;1000&lt;/td&gt;&lt;td&gt;2000&lt;/td&gt;&lt;/tr&gt;
       &lt;tr&gt;&lt;td&gt;1500&lt;/td&gt;&lt;td&gt;30000&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
</code></pre>

<h2>サンプルコード</h2>

<pre><code>&lt;!doctype html&gt;
&lt;html lang="ja"&gt;
&lt;head&gt;
&lt;meta charset="utf-8"&gt;
&lt;link href="https://unpkg.com/tabulator-tables@4.4.3/dist/css/tabulator.min.css" rel="stylesheet"&gt;
&lt;script type="text/javascript" src="https://unpkg.com/tabulator-tables@4.4.3/dist/js/tabulator.min.js"&gt;&lt;/script&gt;
&lt;/head&gt;
&lt;body onload="show_table()"&gt;
&lt;h1 id=title&gt;HTML テーブルを Tabulator で表示&lt;/h1&gt;

&lt;table id="table" border=1&gt;
&lt;thead&gt;
    &lt;tr&gt;&lt;th&gt;ヘッダー1&lt;/th&gt;&lt;th &gt;ヘッダー2&lt;/th&gt;&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
       &lt;tr&gt;&lt;td&gt;1000&lt;/td&gt;&lt;td&gt;2000&lt;/td&gt;&lt;/tr&gt;
       &lt;tr&gt;&lt;td&gt;1500&lt;/td&gt;&lt;td&gt;30000&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;

&lt;script type="text/javascript"&gt;
var show_table = function(){
  var t = new Tabulator("#table",{
    columns: [
      {title:"ヘッダー1",align:"right",bottomCalc:"sum"},
      {title:"ヘッダー2",align:"center",formatter:"money",width:200} 
    ]
  })
}
&lt;/script&gt;
</code></pre>

<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<link href="https://unpkg.com/tabulator-tables@4.4.3/dist/css/tabulator.min.css" rel="stylesheet">

<script type="text/javascript" src="https://unpkg.com/tabulator-tables@4.4.3/dist/js/tabulator.min.js"></script>

<script type="text/javascript">
var show_table = function(){
// defined_function
  var t = new Tabulator("#table",{
    columns: [
      {title:"ヘッダー1",align:"right",bottomCalc:"sum"},
      {title:"ヘッダー2",align:"center",formatter:"money",width:200} 
    ]
  })
// defined_function
}

</script>

<script>show_table()</script>
]]>
        
    </content>
</entry>

<entry>
    <title>データの途中から表示する(scrollToRow)</title>
    <link rel="alternate" type="text/html" href="https://www.soum.co.jp/misc/tabulator-tips/27/" />
    <id>tag:sh173.soum.co.jp,2020:/misc//22.2199</id>

    <published>2020-06-03T05:45:00Z</published>
    <updated>2020-06-03T05:45:14Z</updated>

    <summary>今回は scrollToRow() を使用して、指定した行を表示する方法 につい...</summary>
    <author>
        <name>naka</name>
        
    </author>
    
        <category term="Tabulator tips" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="https://www.soum.co.jp/misc/">
        <![CDATA[<p>今回は
scrollToRow() を使用して、指定した行を表示する方法
について記述します。
Tabulatorドキュメント<a href="
http://tabulator.info/docs/4.5/navigation#scroll-row
">「Scroll To Row」</a> </p>

<pre><code>table.scrollToRow(23, "center", false);
</code></pre>

<p>scrollToRow()の1番目の引数は以下を指定する。</p>

<pre><code>- Row コンポーネント
- Row のid
- Row のDOMノード
</code></pre>

<p>2番目の引数はオプションであり、行の位置(top,center,bottom,nearest)を設定します。省略された場合、scrollToRowPositionオプションの値に設定されます。
デフォルト値は"top"</p>

<p>3番目の引数はオプションであり、
行が既に表示されている場合にテーブルをスクロールするかどうかを設定する。
スクロールする場合はtrue、スクロールしない場合はfalse、省略した場合はscrollToRowIfVisibleオプションの値に設定されます。デフォルトはtrue。</p>

<pre><code>// id23の行を中央に表示する。
// id のデータがない場合は動作しない。
table.scrollToRow(23, "center", false); 


// 条件からrowコンポーネントを取得して指定する。
let row = table.searchRows("val","=","x50");
table.scrollToRow(row[0],"center");

// scroll rowコンポーネント
table.scrollToRow(cell.getRow());

// scroll DOMノード
table.scrollToRow(cell.getRow().getElement());
</code></pre>

<p>id:23を中央にスクロール</p>

<p><div id=table></div></p>

<p>値が"x50"の行をトップにスクロール</p>

<p><div id=table2></div></p>

<h2>カラム定義</h2>

<pre><code>{
    title:"id",
    field:"id",
},
{
    title:"値",
    field:"val",
},
</code></pre>

<h2>データ定義</h2>

<pre><code>var tdata = [];
for(let i=0;i&lt;100; i++){
    tdata.push({ id: i, val: 'x'+i });
}
</code></pre>

<h2>サンプルコード</h2>

<pre><code>&lt;!doctype html&gt;
&lt;html lang="ja"&gt;
&lt;head&gt;
&lt;meta charset="utf-8"&gt;
&lt;link href="https://unpkg.com/tabulator-tables@4.4.3/dist/css/tabulator.min.css" rel="stylesheet"&gt;
&lt;script type="text/javascript" src="https://unpkg.com/tabulator-tables@4.4.3/dist/js/tabulator.min.js"&gt;&lt;/script&gt;
&lt;/head&gt;
&lt;body onload=show_table()&gt;
&lt;h1 id=title&gt; データの途中から表示する(scrollToRow) &lt;/h1&gt;

&lt;p&gt;&lt;div id="table"&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;&lt;div id="table2"&gt;&lt;/div&gt;&lt;/p&gt;

&lt;script type="text/javascript"&gt;
var show_table=function(){
    var tdata = [];
    for(let i=0;i&lt;100; i++){
        tdata.push({ id: i, val: 'x'+i });
    }
    var columns = [
            {
                title:"id",
                field:"id",
            },
            {
                title:"値",
                field:"val",
            },
    ];
    let table = new Tabulator("#table", {
        height:350,
        data:tdata,
        columns: columns,
        cellClick: function(e,cell){
            // セルクリックした行をトップにスクロール
            // 第一引数は scroll DOMノード を指定
            table.scrollToRow(cell.getRow().getElement());
        }
    });
    // id:23を中央にスクロール
    table.scrollToRow(23, "center", false);

    let table2 = new Tabulator("#table2", {
        height:350,
        data:tdata,
        columns: columns,
        cellClick: function(e,cell){
            // scroll rowコンポーネント
            table2.scrollToRow(cell.getRow());
        }
    });
    let row = table2.searchRows("val","=","x50");
    row[0].getElement().style.backgroundColor='yellow';
    // 値が"x50"の行をトップにスクロール
    table2.scrollToRow(row[0]);
}
&lt;/script&gt;
</code></pre>

<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<link href="https://unpkg.com/tabulator-tables@4.4.3/dist/css/tabulator.min.css" rel="stylesheet">

<script type="text/javascript" src="https://unpkg.com/tabulator-tables@4.4.3/dist/js/tabulator.min.js"></script>

<script type="text/javascript">
var show_table=function(){
// defined_data
    var tdata = [];
    for(let i=0;i<100; i++){
        tdata.push({ id: i, val: 'x'+i });
    }
// defined_data
    var columns = [
// defined_columns
            {
                title:"id",
                field:"id",
            },
            {
                title:"値",
                field:"val",
            },
// defined_columns
    ];
    let table = new Tabulator("#table", {
        height:350,
        data:tdata,
        columns: columns,
        cellClick: function(e,cell){
            // セルクリックした行をトップにスクロール
            // 第一引数は scroll DOMノード を指定
            table.scrollToRow(cell.getRow().getElement());
        }
    });
// defined_function
    // id:23を中央にスクロール
    table.scrollToRow(23, "center", false);
// defined_function

    let table2 = new Tabulator("#table2", {
        height:350,
        data:tdata,
        columns: columns,
        cellClick: function(e,cell){
            // scroll rowコンポーネント
            table2.scrollToRow(cell.getRow());
        }
    });
// defined_function
    let row = table2.searchRows("val","=","x50");
    row[0].getElement().style.backgroundColor='yellow';
    // 値が"x50"の行をトップにスクロール
    table2.scrollToRow(row[0]);
// defined_function
}

</script>

<script>show_table()</script>
]]>
        
    </content>
</entry>

<entry>
    <title>formatterで他のセルのデータを参照する</title>
    <link rel="alternate" type="text/html" href="https://www.soum.co.jp/misc/tabulator-tips/26/" />
    <id>tag:sh173.soum.co.jp,2020:/misc//22.2190</id>

    <published>2020-05-27T00:10:00Z</published>
    <updated>2020-05-27T00:10:13Z</updated>

    <summary>今回は formatter 処理で他のセルのデータを参照する方法 について記述し...</summary>
    <author>
        <name>naka</name>
        
    </author>
    
        <category term="Tabulator tips" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="https://www.soum.co.jp/misc/">
        <![CDATA[<p>今回は
formatter 処理で他のセルのデータを参照する方法
について記述します。</p>

<p>formatter 関数において cell.getData() によりそのセルがあるカラムデータを取得します。
取得したデータからフィールド名を指定すれば、他のセルデータを参照できます。</p>

<pre><code>// 他のセルのデータ参照
let data = cell.getData();
let price = data.price;
</code></pre>

<p><div id=table></div></p>

<h2>カラム定義</h2>

<pre><code>{
    title:"価格",
    field:"price",
    align: "right",
    formatter: "money",
    formatterParams:{precision:0}, 
},
{
    title:"税率",
    field:"ritsu",
    align: "right",
    formatter: function(cell){
        let val = cell.getValue();
        if(val) return val+"%"
    }
},
{
    title:"税込み",
    field:"komi",
    align: "right",
    formatter: disp_zeikomi,
},
</code></pre>

<h2>データ定義</h2>

<pre><code>{ price: 1000, ritsu: 8 },
{ price: 5000, ritsu: 10 },
{ price: 8000, ritsu: 8 },
</code></pre>

<h2>サンプルコード</h2>

<pre><code>&lt;!doctype html&gt;
&lt;html lang="ja"&gt;
&lt;head&gt;
&lt;meta charset="utf-8"&gt;
&lt;link href="https://unpkg.com/tabulator-tables@4.4.3/dist/css/tabulator.min.css" rel="stylesheet"&gt;
&lt;script type="text/javascript" src="https://unpkg.com/tabulator-tables@4.4.3/dist/js/tabulator.min.js"&gt;&lt;/script&gt;
&lt;/head&gt;
&lt;body onload=show_table()&gt;
&lt;h1 id=title&gt; formatterで他のセルのデータを参照する &lt;/h1&gt;

&lt;p&gt;&lt;div id="table"&gt;&lt;/div&gt;&lt;/p&gt;

&lt;script type="text/javascript"&gt;
var disp_zeikomi = function(cell){
    // 他のセルのデータ参照
    let data = cell.getData();
    let price = data.price;
    let zei = data.ritsu/100;

    // 表示データ計算
    let zeikomi = price * (1 + zei);
    // カンマ表示
    return Math.round(zeikomi).toLocaleString()
}
var show_table=function(){
    var tdata = [
        { price: 1000, ritsu: 8 },
        { price: 5000, ritsu: 10 },
        { price: 8000, ritsu: 8 },
    ];
    var columns = [
            {
                title:"価格",
                field:"price",
                align: "right",
                formatter: "money",
                formatterParams:{precision:0}, 
            },
            {
                title:"税率",
                field:"ritsu",
                align: "right",
                formatter: function(cell){
                    let val = cell.getValue();
                    if(val) return val+"%"
                }
            },
            {
                title:"税込み",
                field:"komi",
                align: "right",
                formatter: disp_zeikomi,
            },
    ];
    new Tabulator("#table", {
        data:tdata,
        columns: columns,
    });
}
&lt;/script&gt;
</code></pre>

<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<link href="https://unpkg.com/tabulator-tables@4.4.3/dist/css/tabulator.min.css" rel="stylesheet">

<script type="text/javascript" src="https://unpkg.com/tabulator-tables@4.4.3/dist/js/tabulator.min.js"></script>

<script type="text/javascript">
var disp_zeikomi = function(cell){
    // 他のセルのデータ参照
    let data = cell.getData();
    let price = data.price;
    let zei = data.ritsu/100;

    // 表示データ計算
    let zeikomi = price * (1 + zei);
    // カンマ表示
    return Math.round(zeikomi).toLocaleString()
}
var show_table=function(){
    var tdata = [
// defined_data
        { price: 1000, ritsu: 8 },
        { price: 5000, ritsu: 10 },
        { price: 8000, ritsu: 8 },
// defined_data
    ];
    var columns = [
// defined_columns
            {
                title:"価格",
                field:"price",
                align: "right",
                formatter: "money",
                formatterParams:{precision:0}, 
            },
            {
                title:"税率",
                field:"ritsu",
                align: "right",
                formatter: function(cell){
                    let val = cell.getValue();
                    if(val) return val+"%"
                }
            },
            {
                title:"税込み",
                field:"komi",
                align: "right",
                formatter: disp_zeikomi,
            },
// defined_columns
    ];
    new Tabulator("#table", {
        data:tdata,
        columns: columns,
    });
// defined_function
}

</script>

<script>show_table()</script>
]]>
        
    </content>
</entry>

<entry>
    <title>max,min属性による開始、終了日制限付日付エディター</title>
    <link rel="alternate" type="text/html" href="https://www.soum.co.jp/misc/tabulator-tips/25/" />
    <id>tag:sh173.soum.co.jp,2020:/misc//22.2188</id>

    <published>2020-05-20T00:35:00Z</published>
    <updated>2020-05-20T00:35:15Z</updated>

    <summary>今回は、 html の date エレメントの max,min 属性を使用して ...</summary>
    <author>
        <name>naka</name>
        
    </author>
    
        <category term="Tabulator tips" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="https://www.soum.co.jp/misc/">
        <![CDATA[<p>今回は、
html の date エレメントの max,min 属性を使用して
開始日、終了日の入力制限を行います。</p>

<div id="table"></div>

<p>日付入力用のエディターは前回作成した関数dateEdit を流用しています。</p>

<p>日付の入力制限は date エレメントの max, min 属性で行います。
日付の入力制限を date エレメントの max,min 属性で行うため、
validate_start(), validate_end() の入力チェックは入力項目の未入力チェックだけとなります。</p>

<p>開始日、終了日の入力条件は以下の通りです。</p>

<ul>
<li><p>max,min属性で制御</p>

<ul>
<li>開始日は終了日より古い日付を入力</li>
<li>終了日は開始日より新しい日付を入力</li>
<li>終了日が未入力の場合、開始日は任意の日付入力OK</li>
</ul></li>
<li><p>validate_start() 入力チェック</p>

<ul>
<li>開始日は入力があれば OK</li>
<li>終了日時が入力済の場合、開始日未入力は NG</li>
<li>開始日、終了日ともに未入力は OK</li>
</ul></li>
<li><p>validate_end() 入力チェック</p>

<ul>
<li>終了日未入力は OK</li>
<li>開始日未入力の場合、終了日の入力は NG</li>
</ul></li>
</ul>

<p>以下は入力チェック関数です。</p>

<pre><code>// 開始日チェック
const validate_start=(cell,value)=&gt;{
    // 開始日入力がある場合は、OK(true)
    if(value) return true;

    // 以下、開始日未入力の処理。 
    // 終了日時が未入力の場合、  OK(true)
    // 終了日時が入力済みの場合、NG(false)
    return (!cell.getData().end)?true:false;
}
// 終了日チェック
const validate_end=(cell,value)=&gt;{
    // 終了日は入力なくても OK(true)
    if(!value) return true;

    // 開始日時がない場合、NG(false)
    return (!cell.getData().start)? false: true;
}
</code></pre>

<p>moment.js は以下のCDN を使用します。</p>

<pre><code>&lt;script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.10.6/moment.js"&gt;&lt;/script&gt;
</code></pre>

<p>カラム定義の width:120 により、日付入力時、日付入力クリア用の
xマークがカラムに隠れないように幅を確保しています。</p>

<h2>カラム定義</h2>

<pre><code>{title:"開始日",field:"start", width:120,
          editor:dateEdit, validator:{type:validate_start}},
{title:"終了日",field:"end", width:120, 
          editor:dateEdit, validator:{type:validate_end}}
</code></pre>

<h2>サンプルコード</h2>

<pre><code>&lt;!doctype html&gt;
&lt;html lang="ja"&gt;
&lt;head&gt;
&lt;meta charset="utf-8"&gt;
&lt;link href="https://unpkg.com/tabulator-tables@4.4.3/dist/css/tabulator.min.css" rel="stylesheet"&gt;
&lt;script type="text/javascript" src="https://unpkg.com/tabulator-tables@4.4.3/dist/js/tabulator.min.js"&gt;&lt;/script&gt;
&lt;script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.10.6/moment.js"&gt;&lt;/script&gt;
&lt;/head&gt;

&lt;body onload="show_table()"&gt;
&lt;h1 id=title&gt;max,min属性による開始、終了日制限付日付エディター&lt;/h1&gt;
&lt;div id="table"&gt;&lt;/div&gt;

&lt;script type="text/javascript"&gt;
// 開始日チェック
const validate_start=(cell,value)=&gt;{
    // 開始日入力がある場合は、OK(true)
    if(value) return true;

    // 以下、開始日未入力の処理。 
    // 終了日時が未入力の場合、  OK(true)
    // 終了日時が入力済みの場合、NG(false)
    return (!cell.getData().end)?true:false;
}
// 終了日チェック
const validate_end=(cell,value)=&gt;{
    // 終了日は入力なくても OK(true)
    if(!value) return true;

    // 開始日時がない場合、NG(false)
    return (!cell.getData().start)? false: true;
}
// 日付入力
const dateEdit = function(cell, onRendered, success, cancel, editorParams){
    var editor = document.createElement("input");
    editor.setAttribute("type","date");

    // date max, min setting
    var data = cell.getData();
    var field = cell.getField();

    // max,min 属性設定
    if(field === 'start' &amp;&amp; data.end){
        editor.setAttribute("max",
            moment(data.end, "YYYY/MM/DD").format("YYYY-MM-DD"));
    }
    else if (field === 'end' &amp;&amp; data.start){
        editor.setAttribute("min",
            moment(data.start, "YYYY/MM/DD").format("YYYY-MM-DD"));
    }
    editor.value = moment(cell.getValue(), "YYYY/MM/DD").format("YYYY-MM-DD");
    onRendered(function(){ editor.focus() });
    var successFunc = function() {
        let val = "";
        if(editor.value)
            val=moment(editor.value,"YYYY-MM-DD").format("YYYY/MM/DD")
        if(success(val)){ // 成功
            // 入力後処理
            console.log("date input", val);
        }
    }
    editor.addEventListener("change", successFunc);
    editor.addEventListener("blur", successFunc);
    return editor;
};
var show_table=function(){
    var tdata = [
        {start:"2019/5/1",end:"2019/5/2"},
    ];
    var columns= [
      {title:"開始日",field:"start", width:120,
                editor:dateEdit, validator:{type:validate_start}},
      {title:"終了日",field:"end", width:120, 
                editor:dateEdit, validator:{type:validate_end}}
    ];
    new Tabulator("#table", {
        data:tdata,
        columns: columns
    });
}
&lt;/script&gt;
</code></pre>

<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<link href="https://unpkg.com/tabulator-tables@4.4.3/dist/css/tabulator.min.css" rel="stylesheet">

<script type="text/javascript" src="https://unpkg.com/tabulator-tables@4.4.3/dist/js/tabulator.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.10.6/moment.js"></script>

<script type="text/javascript">
// defined_function
// 開始日チェック
const validate_start=(cell,value)=>{
    // 開始日入力がある場合は、OK(true)
    if(value) return true;

    // 以下、開始日未入力の処理。 
    // 終了日時が未入力の場合、  OK(true)
    // 終了日時が入力済みの場合、NG(false)
    return (!cell.getData().end)?true:false;
}
// 終了日チェック
const validate_end=(cell,value)=>{
    // 終了日は入力なくても OK(true)
    if(!value) return true;

    // 開始日時がない場合、NG(false)
    return (!cell.getData().start)? false: true;
}
// defined_function
// 日付入力
const dateEdit = function(cell, onRendered, success, cancel, editorParams){
    var editor = document.createElement("input");
    editor.setAttribute("type","date");

    // date max, min setting
    var data = cell.getData();
    var field = cell.getField();

    // max,min 属性設定
    if(field === 'start' && data.end){
        editor.setAttribute("max",
            moment(data.end, "YYYY/MM/DD").format("YYYY-MM-DD"));
    }
    else if (field === 'end' && data.start){
        editor.setAttribute("min",
            moment(data.start, "YYYY/MM/DD").format("YYYY-MM-DD"));
    }
    editor.value = moment(cell.getValue(), "YYYY/MM/DD").format("YYYY-MM-DD");
    onRendered(function(){ editor.focus() });
    var successFunc = function() {
        let val = "";
        if(editor.value)
            val=moment(editor.value,"YYYY-MM-DD").format("YYYY/MM/DD")
        if(success(val)){ // 成功
            // 入力後処理
            console.log("date input", val);
        }
    }
    editor.addEventListener("change", successFunc);
    editor.addEventListener("blur", successFunc);
    return editor;
};
var show_table=function(){
    var tdata = [
        {start:"2019/5/1",end:"2019/5/2"},
    ];
    var columns= [
// defined_columns
      {title:"開始日",field:"start", width:120,
                editor:dateEdit, validator:{type:validate_start}},
      {title:"終了日",field:"end", width:120, 
                editor:dateEdit, validator:{type:validate_end}}
// defined_columns
    ];
    new Tabulator("#table", {
        data:tdata,
        columns: columns
    });
}

</script>

<script>show_table()</script>
]]>
        
    </content>
</entry>

<entry>
    <title>入力チェック付日付入力用エディター</title>
    <link rel="alternate" type="text/html" href="https://www.soum.co.jp/misc/tabulator-tips/24/" />
    <id>tag:sh173.soum.co.jp,2020:/misc//22.2187</id>

    <published>2020-05-13T02:30:00Z</published>
    <updated>2020-05-13T02:30:11Z</updated>

    <summary>今回は、日付の入力チェックを行う関数を作成します。 入力チェックは以下の通りです...</summary>
    <author>
        <name>naka</name>
        
    </author>
    
        <category term="Tabulator tips" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="https://www.soum.co.jp/misc/">
        <![CDATA[<p>今回は、日付の入力チェックを行う関数を作成します。</p>

<p>入力チェックは以下の通りです。</p>

<ul>
<li>開始日、終了日は必須とします。</li>
<li>開始日が終了日より古い場合はエラーとします。</li>
<li>エラーがあった時、メッセージのセルにエラー内容を表示します。</li>
<li>入力が正常の時、メッセージのセルにOKを表示します。</li>
</ul>

<div id="table"></div>

<p>以下は開始日のチェック関数です。</p>

<pre><code>/* 開始日 - 検証関数 */
var validate_start=function(cell,value){
    clear_message(cell);
    if(!value){
        update_message(cell,'開始日は必須です。');
        return false;
    }
    var data = cell.getData();
    if(!data.end) {
        update_message(cell,'終了日は必須です。');
        return false;
    }
    var start = moment(value, "YYYY/MM/DD");
    var end   = moment(data.end, "YYYY/MM/DD");
    if(start.isAfter(end)){
      update_message(cell,'開始日が終了日より遅い日付です。');
      return false;
    }
    return true;
}
</code></pre>

<p>日付入力用のエディターは前回作成した関数dateEdit を流用しています。
違いは、入力チェックが正常の時、
メッセージのセルにOKを表示する処理を追加した部分です。
Tabulator のバージョンが、4.4.3 以降でないと success() が返り値を返さないので 4.4.3 以降のバージョンを使用してください。</p>

<pre><code>var successFunc = function() {
    ...
    if(success(val)){ // 値が正常ならOK表示
        update_message(cell,'OK');
    }
}
</code></pre>

<p>moment.js は以下のCDN を使用します。</p>

<pre><code>&lt;script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.10.6/moment.js"&gt;&lt;/script&gt;
</code></pre>

<h2>カラム定義</h2>

<pre><code>{title:"開始日",field:"start",editor:dateEdit,validator:{type:validate_start},width:150},
{title:"終了日",field:"end",editor:dateEdit,validator:{type:validate_end},width:150},
{title:"メッセージ",field:"msg", width:300},
</code></pre>

<h2>データ定義</h2>

<pre><code>{start:"2019/5/1",end:"2019/5/2", msg:""},
</code></pre>

<h2>サンプルコード</h2>

<pre><code>&lt;!doctype html&gt;
&lt;html lang="ja"&gt;
&lt;head&gt;
&lt;meta charset="utf-8"&gt;
&lt;link href="https://unpkg.com/tabulator-tables@4.4.3/dist/css/tabulator.min.css" rel="stylesheet"&gt;
&lt;script type="text/javascript" src="https://unpkg.com/tabulator-tables@4.4.3/dist/js/tabulator.min.js"&gt;&lt;/script&gt;
&lt;script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.10.6/moment.js"&gt;&lt;/script&gt;
&lt;/head&gt;
&lt;body onload="show_table()"&gt;
&lt;h1 id=title&gt;入力チェック付日付入力用エディター&lt;/h1&gt;
&lt;div id="table"&gt;&lt;/div&gt;

&lt;script type="text/javascript"&gt;
// エラーメッセージ表示
var update_message = function(cell, msg){
    cell.getRow().update({"msg":msg});
}
// エラーメッセージクリア
var clear_message = function(cell){
    update_message(cell,"");
}
/* 開始日 - 検証関数 */
var validate_start=function(cell,value){
    clear_message(cell);
    if(!value){
        update_message(cell,'開始日は必須です。');
        return false;
    }
    var data = cell.getData();
    if(!data.end) {
        update_message(cell,'終了日は必須です。');
        return false;
    }
    var start = moment(value, "YYYY/MM/DD");
    var end   = moment(data.end, "YYYY/MM/DD");
    if(start.isAfter(end)){
      update_message(cell,'開始日が終了日より遅い日付です。');
      return false;
    }
    return true;
}
/* 終了日 - 検証関数 */
var validate_end=function(cell,value){
    clear_message(cell);
    if(!value){
        update_message(cell,'終了日は必須です。');
        return false;
    }
    var data = cell.getData();
    var start = moment(data.start, "YYYY/MM/DD");
    var end   = moment(value, "YYYY/MM/DD");
    if(start.isAfter(end)){
      update_message(cell,'終了日が開始日より早い日付です。');
      return false;
    }
    return true;
}
var dateEdit = function(cell, onRendered, success, cancel, editorParams){
    // cell-編集可能なセルのセルコンポーネント
    // onRendered-エディターがレンダリングされたときに呼び出す関数
    // success-正常に更新された値をTabulatorに渡すために呼び出す関数
    // cancel-編集を中止して通常のセルに戻るために呼び出す関数
    // editorParams-editorParams列定義プロパティに渡されるparamsオブジェクト

    // 日付入力用エディターを作成
    var editor = document.createElement("input");
    editor.setAttribute("type","date");

    // エディターの値をセルの現在の値に設定します
    editor.value = moment(cell.getValue(), "YYYY/MM/DD").format("YYYY-MM-DD");

    //エディターが選択されたときに選択ボックスにフォーカスを設定します
    // （タイムアウトによりエディターをDOMに追加できます）
    onRendered(function(){ editor.focus() });

    //値が設定されたら、更新するセルをトリガーします
    var successFunc = function() {
        var val = "";
        if(editor.value) // 空白チェック
          val=moment(editor.value,"YYYY-MM-DD").format("YYYY/MM/DD");
        if(success(val)){ // 値が正常ならOK表示
          update_message(cell,'OK');
        }
    }
    editor.addEventListener("change", successFunc);
    editor.addEventListener("blur", successFunc);

    return editor;
}
var show_table=function(){
    var tdata = [
        {start:"2019/5/1",end:"2019/5/2", msg:""},
    ];
    var columns= [
      {title:"開始日",field:"start",editor:dateEdit,validator:{type:validate_start},width:150},
      {title:"終了日",field:"end",editor:dateEdit,validator:{type:validate_end},width:150},
      {title:"メッセージ",field:"msg", width:300},
    ];
    new Tabulator("#table", {
        data:tdata,
        columns: columns
    });
}
&lt;/script&gt;
</code></pre>

<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<link href="https://unpkg.com/tabulator-tables@4.4.3/dist/css/tabulator.min.css" rel="stylesheet">

<script type="text/javascript" src="https://unpkg.com/tabulator-tables@4.4.3/dist/js/tabulator.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.10.6/moment.js"></script>

<script type="text/javascript">
// エラーメッセージ表示
var update_message = function(cell, msg){
    cell.getRow().update({"msg":msg});
}
// エラーメッセージクリア
var clear_message = function(cell){
    update_message(cell,"");
}
// defined_function
/* 開始日 - 検証関数 */
var validate_start=function(cell,value){
    clear_message(cell);
    if(!value){
        update_message(cell,'開始日は必須です。');
        return false;
    }
    var data = cell.getData();
    if(!data.end) {
        update_message(cell,'終了日は必須です。');
        return false;
    }
    var start = moment(value, "YYYY/MM/DD");
    var end   = moment(data.end, "YYYY/MM/DD");
    if(start.isAfter(end)){
      update_message(cell,'開始日が終了日より遅い日付です。');
      return false;
    }
    return true;
}
// defined_function
/* 終了日 - 検証関数 */
var validate_end=function(cell,value){
    clear_message(cell);
    if(!value){
        update_message(cell,'終了日は必須です。');
        return false;
    }
    var data = cell.getData();
    var start = moment(data.start, "YYYY/MM/DD");
    var end   = moment(value, "YYYY/MM/DD");
    if(start.isAfter(end)){
      update_message(cell,'終了日が開始日より早い日付です。');
      return false;
    }
    return true;
}
var dateEdit = function(cell, onRendered, success, cancel, editorParams){
    // cell-編集可能なセルのセルコンポーネント
    // onRendered-エディターがレンダリングされたときに呼び出す関数
    // success-正常に更新された値をTabulatorに渡すために呼び出す関数
    // cancel-編集を中止して通常のセルに戻るために呼び出す関数
    // editorParams-editorParams列定義プロパティに渡されるparamsオブジェクト

    // 日付入力用エディターを作成
    var editor = document.createElement("input");
    editor.setAttribute("type","date");

    // エディターの値をセルの現在の値に設定します
    editor.value = moment(cell.getValue(), "YYYY/MM/DD").format("YYYY-MM-DD");

    //エディターが選択されたときに選択ボックスにフォーカスを設定します
    // （タイムアウトによりエディターをDOMに追加できます）
    onRendered(function(){ editor.focus() });

    //値が設定されたら、更新するセルをトリガーします
    var successFunc = function() {
        var val = "";
        if(editor.value) // 空白チェック
          val=moment(editor.value,"YYYY-MM-DD").format("YYYY/MM/DD");
        if(success(val)){ // 値が正常ならOK表示
          update_message(cell,'OK');
        }
    }
    editor.addEventListener("change", successFunc);
    editor.addEventListener("blur", successFunc);

    return editor;
}
var show_table=function(){
    var tdata = [
// defined_data
        {start:"2019/5/1",end:"2019/5/2", msg:""},
// defined_data
    ];
    var columns= [
// defined_columns
      {title:"開始日",field:"start",editor:dateEdit,validator:{type:validate_start},width:150},
      {title:"終了日",field:"end",editor:dateEdit,validator:{type:validate_end},width:150},
      {title:"メッセージ",field:"msg", width:300},
// defined_columns
    ];
    new Tabulator("#table", {
        data:tdata,
        columns: columns
    });
}

</script>

<script>show_table()</script>
]]>
        
    </content>
</entry>

<entry>
    <title>日付入力用エディター</title>
    <link rel="alternate" type="text/html" href="https://www.soum.co.jp/misc/tabulator-tips/23/" />
    <id>tag:sh173.soum.co.jp,2020:/misc//22.2185</id>

    <published>2020-04-28T00:40:00Z</published>
    <updated>2020-04-28T00:40:20Z</updated>

    <summary>今回は日付入力用エディターを作成します。   TabulatorドキュメントCu...</summary>
    <author>
        <name>naka</name>
        
    </author>
    
        <category term="Tabulator tips" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="https://www.soum.co.jp/misc/">
        <![CDATA[<p>今回は日付入力用エディターを作成します。</p>

<hr />

<blockquote>
  <p>Tabulatorドキュメント<a href="http://tabulator.info/docs/4.4/edit#edit-custom">Custom Editors</a>より抜粋</p>

<p>別のタイプのエディターが必要な場合は、カスタムエディター機能をeditor オプションに渡すことができます。
 この関数は5つの引数を取ります。</p>

<ol start='1'>
<li>編集中のセルの CellComponent。</li>
<li>セルがレンダリングされたときに呼び出す関数(要素が表示された後にフォーカスを設定したり、ディスプレイを整頓するために使用できる)。</li>
<li>ユーザーがセルに新しいデータを正常に入力したときに新しい値を返すために呼び出す関数。</li>
<li>ユーザーが編集を中止した場合に呼び出す関数。</li>
<li>editorParams 列定義プロパティから渡されるパラメータ。</li>
</ol>

<p>カスタムエディター関数は、セルに挿入されるエディターのDOMノードを返す必要があります。また、編集を中止する場合はfalseの値を返す必要があります。</p>
</blockquote>

<hr />

<p>入力用エディターのカスタム関数は 
Tabulatorドキュメント<a href="http://tabulator.info/docs/4.4/edit#edit-custom">Custom Editors</a> 
にあるサンプルプログラムを使用します。
サンプルプログラムに行ったの修正は以下の通りです。</p>

<ul>
<li>セルの日付表示を YYYY/MM/DD に変更。</li>
<li>successFunc に空白チェックを追加。
(moment が Invalid date を返すためエラーチェック)</li>
<li>style の指定を削除。</li>
<li>コメントを日本語にした。</li>
</ul>

<p>セルを２度クリックすると入力カレンダーが表示されます。
動作しないときは画面のセル以外の部分をクリックしてから、セルをクリックし直すと動作するようになると思います。</p>

<div id="table"></div>

<p>日付入力用のカスタム関数は以下のようになります。</p>

<pre><code>var dateEdit = function(cell, onRendered, success, cancel, editorParams){
    // cell-編集可能なセルのセルコンポーネント
    // onRendered-エディターがレンダリングされたときに呼び出す関数
    // success-正常に更新された値をTabulatorに渡すために呼び出す関数
    // cancel-編集を中止して通常のセルに戻るために呼び出す関数
    // editorParams-editorParams列定義プロパティに渡されるparamsオブジェクト

    // 日付入力用エディターを作成
    var editor = document.createElement("input");
    editor.setAttribute("type","date");

    // エディターの値をセルの現在の値に設定します
    editor.value = moment(cell.getValue(), "YYYY/MM/DD").format("YYYY-MM-DD");

    //エディターが選択されたときに選択ボックスにフォーカスを設定します
    // （タイムアウトによりエディターをDOMに追加できます）
    onRendered(function(){editor.focus()});

    //値が設定されたら、更新するセルをトリガーします
    var successFunc = function() {
        var val = "";
        if(editor.value) // 空白チェック
            val=moment(editor.value,"YYYY-MM-DD").format("YYYY/MM/DD");
        success(val);
    }
    editor.addEventListener("change", successFunc);
    editor.addEventListener("blur", successFunc);

    //return the editor element
    return editor;
};
</code></pre>

<p>moment.js  を使用するので以下のCDN を読み込みます。</p>

<pre><code>&lt;script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.10.6/moment.js"&gt;&lt;/script&gt;
</code></pre>

<h2>カラム定義</h2>

<pre><code>{ title:"日付", field:"date", editor:dateEdit, width:150 },
</code></pre>

<h2>データ定義</h2>

<pre><code>{ date: "2019/5/1"},
</code></pre>

<h2>サンプルコード</h2>

<pre><code>&lt;!doctype html&gt;
&lt;html lang="ja"&gt;
&lt;head&gt;
&lt;meta charset="utf-8"&gt;
&lt;link href="https://unpkg.com/tabulator-tables@4.4.3/dist/css/tabulator.min.css" rel="stylesheet"&gt;
&lt;script type="text/javascript" src="https://unpkg.com/tabulator-tables@4.4.3/dist/js/tabulator.min.js"&gt;&lt;/script&gt;
&lt;script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.10.6/moment.js"&gt;&lt;/script&gt;
&lt;/head&gt;
&lt;body onload="show_table()"&gt;
&lt;h1 id=title&gt;日付入力用エディター&lt;/h1&gt;
&lt;div id="table"&gt;&lt;/div&gt;

&lt;script type="text/javascript"&gt;
var dateEdit = function(cell, onRendered, success, cancel, editorParams){
    // cell-編集可能なセルのセルコンポーネント
    // onRendered-エディターがレンダリングされたときに呼び出す関数
    // success-正常に更新された値をTabulatorに渡すために呼び出す関数
    // cancel-編集を中止して通常のセルに戻るために呼び出す関数
    // editorParams-editorParams列定義プロパティに渡されるparamsオブジェクト

    // 日付入力用エディターを作成
    var editor = document.createElement("input");
    editor.setAttribute("type","date");

    // エディターの値をセルの現在の値に設定します
    editor.value = moment(cell.getValue(), "YYYY/MM/DD").format("YYYY-MM-DD");

    //エディターが選択されたときに選択ボックスにフォーカスを設定します
    // （タイムアウトによりエディターをDOMに追加できます）
    onRendered(function(){editor.focus()});

    //値が設定されたら、更新するセルをトリガーします
    var successFunc = function() {
        var val = "";
        if(editor.value) // 空白チェック
            val=moment(editor.value,"YYYY-MM-DD").format("YYYY/MM/DD");
        success(val);
    }
    editor.addEventListener("change", successFunc);
    editor.addEventListener("blur", successFunc);

    //return the editor element
    return editor;
};
var show_table=function(){
    var tdata = [
        { date: "2019/5/1"},
    ];
    var columns= [
        { title:"日付", field:"date", editor:dateEdit, width:150 },
    ];
    new Tabulator("#table", {
        data:tdata,
        columns: columns
    });
}
&lt;/script&gt;
</code></pre>

<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<link href="https://unpkg.com/tabulator-tables@4.4.3/dist/css/tabulator.min.css" rel="stylesheet">

<script type="text/javascript" src="https://unpkg.com/tabulator-tables@4.4.3/dist/js/tabulator.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.10.6/moment.js"></script>

<script type="text/javascript">
// defined_function
var dateEdit = function(cell, onRendered, success, cancel, editorParams){
    // cell-編集可能なセルのセルコンポーネント
    // onRendered-エディターがレンダリングされたときに呼び出す関数
    // success-正常に更新された値をTabulatorに渡すために呼び出す関数
    // cancel-編集を中止して通常のセルに戻るために呼び出す関数
    // editorParams-editorParams列定義プロパティに渡されるparamsオブジェクト

    // 日付入力用エディターを作成
    var editor = document.createElement("input");
    editor.setAttribute("type","date");

    // エディターの値をセルの現在の値に設定します
    editor.value = moment(cell.getValue(), "YYYY/MM/DD").format("YYYY-MM-DD");

    //エディターが選択されたときに選択ボックスにフォーカスを設定します
    // （タイムアウトによりエディターをDOMに追加できます）
    onRendered(function(){editor.focus()});

    //値が設定されたら、更新するセルをトリガーします
    var successFunc = function() {
        var val = "";
        if(editor.value) // 空白チェック
            val=moment(editor.value,"YYYY-MM-DD").format("YYYY/MM/DD");
        success(val);
    }
    editor.addEventListener("change", successFunc);
    editor.addEventListener("blur", successFunc);

    //return the editor element
    return editor;
};
// defined_function
var show_table=function(){
    var tdata = [
// defined_data
        { date: "2019/5/1"},
// defined_data
    ];
    var columns= [
// defined_columns
        { title:"日付", field:"date", editor:dateEdit, width:150 },
// defined_columns
    ];
    new Tabulator("#table", {
        data:tdata,
        columns: columns
    });
}

</script>

<script>show_table()</script>
]]>
        
    </content>
</entry>

</feed>