はじめに
HTML+JavaScript でアプリ開発するにあたって、UI ライブラリ Webix を使ってみました。
Webix を使ってみた #JavaScript - Qiita
Webix のコンポーネントは多くの種類が用意されていますが特に、データを一覧表示する datatable
コンポーネントは便利です。
Webix の datatable を使ってみる
datatable
は、テーブルにデータを表示するコンポーネントで、スクロールおよびソートを始め、データを表示したり編集するための機能が充実しています。
DataTable - DataTable UI widget documentation: configuration, data export, etc. - Webix Docs
Webix の datatable を使ってみる①
datatable コンポーネントを記述する
まず、datatable
コンポーネントを画面に表示します。
weibx.ready(function(){
webix.ui({
rows:[
{
view:'datatable',
id:"list",
columns:[
{ id:'rank', header:"", width:30 },
{ id:'title', header:"Title", width:300 },
{ id:'year', header:"Released", width:80 },
{ id:'votes', header:"Votes", width:100 }
],
},
]
});
});
この datatable
コンポーネントにデータをセットして表示します。
datatable にデータをセットする①
まず、data
プロパティを使って設計時点でデータを指定します。
{
view:'datatable',
id:"list",
(中略)
data:[
{ id:1, title:"The Shawshank Redemption", year:1994, votes:678790, rating:9.2, :1 },
{ id:2, title:"The Godfather", year:1972, votes:511495, rating:9.2, rank:2 }
]
},
参考 https://snippet.webix.com/04e56172
datatable にデータをセットする②
data
プロパティを使って設計時点でデータをセットする代わりに、parse
メソッドを使って実行時点でデータをセットします。
{
view:'datatable',
id:"list",
(中略)
}
(中略)
$$("list").parse([
{ id:1, title:"The Shawshank Redemption", year:1994, votes:678790, rating:9.2, rank:1 },
{ id:2, title:"The Godfather", year:1972, votes:511495, rating:9.2, rank:2 }
]);
参考 https://snippet.webix.com/598f77de
データを返すサーバアプリを用意する
サーバからデータを取得して表示したいので、GET リクエストを受けて JSON データを返すウェブサーバを用意します。
以降のサンプルは、Webix 公式が用意してくれている URL を使っています。
datatable にデータをセットする③
data
プロパティに JavaScript の配列オブジェクトをセットする代わりに、url
プロパティにウェブサーバを指定します。
{
view:'datatable',
id:"list",
(中略)
url:"https://docs.webix.com/samples/15_datatable/01_loading/data/data.json"
},
参考 https://snippet.webix.com/045e83f8
datatable にデータをセットする④
url
プロパティを使って設計時点でデータをセットする代わりに、load
メソッドを使って実行時点でデータをセットします。
{
view:'datatable',
id:"list",
(中略)
}
(中略)
$$('list').load("https://docs.webix.com/samples/15_datatable/01_loading/data/data.json");
参考 https://docs.webix.com/api__link__ui.datatable_load.html
Webix の datatable を使ってみる②
datatable を編集可能にする
editable
プロパティを指定すると、セル単位でインライン編集できるようになります。
{
view:'datatable',
id:"list",
(中略)
columns:[
{ id:'rank', header:"", width:30 },
{ id:'title', header:"Title", width:300, editor:'text' },
{ id:'year', header:"Released", width:80, editor:'text' },
{ id:'votes', header:"Votes", width:100, editor:'text' }
],
editable:true,
},
参考 https://snippet.webix.com/f1edcadc
さらに、データの追加と削除できるように入力フォームを用意しましょう。
datatable にデータを追加する
add
メソッドを使って datatable
に行を追加できます。
まず、入力フォームを追加します。ここに「追加」ボタンを用意しています。
{
view:'datatable',
id:"list",
(中略)
},
{
view:'form',
id:"input",
elements:[
{ view:'text', name:"title", value:"New Movie",inputWidth:200 },
{ view:'text', name:"year", value:"2025", inputWidth:200 },
{ cols:[
{ view:'button', width:100, value:"Add", click:addData },
] }
]
}
「追加」ボタンをクリックすると関数 addData
を実行するようにしています。ここで datatable
に行を追加します。
function addData(){
var values = $$('input').getValues();
$$('list').add({
title: values['title'],
year: values['year']
});
}
参考 https://snippet.webix.com/247a9541
datatable にデータを削除する
remove
メソッドを使って datatable
から行を削除できます。
まず、入力フォームに「削除」ボタンを追加します。
{
view:'datatable',
id:"list",
(中略)
select:'row',
},
{
view:'form',
(中略)
{ view:"button", width:160, value:"Remove selected", click:removeData },
] }
]
}
「削除」ボタンをクリックすると関数 removeData
を実行するようにしています。ここで datatable
から行を削除します。
function removeData(){
var id = $$('list').getSelectedId()
if (!id) {
return;
}
$$('list').remove(id);
}
選択した行を削除するので、datatable
に select:'row'
を指定して行単位で選択できるようにしておきます。↓
{
view:'datatable',
id:"list",
(中略)
select:`row`,
},
参考 https://snippet.webix.com/247a9541
Webix の datatable を使ってみる③
データを受けるサーバアプリを用意する
サーバにデータを送って記録したいので、POST リクエストを受けてデータを記録するウェブサーバを用意します。
以降のサンプルは、ウェブアプリのクライアントプログラムをテストできるサイトを利用しています。httpbin.org
datatable で編集したデータを記録する①
datatable
の save
プロパティにウェブサーバを指定します。
{
view:'datatable',
id:"list",
(中略)
url:"https://docs.webix.com/samples/15_datatable/01_loading/data/data.json"
save:"https://https://httpbin.org/post",
},
参考 https://docs.webix.com/api__link__ui.datatable_save_config.html
Webix の datatable
コンポーネントから以下の POST リクエストが送られるようです。
追加時
{
queryString=, postData=FileUpload, contentLength=50.0, contextPath=
parameters={
webix_operation=[Ljava.lang.Object;@7b411371, year=[Ljava.lang.Object;@405f2985, title=[Ljava.lang.Object;@37c83540
},
parameter={
webix_operation=insert,
title=New Movie, year=2025
},
}
更新時
{
queryString=, postData=FileUpload, contentLength=80.0, contextPath=,
parameters={
webix_operation=[Ljava.lang.Object;@494b62ca, id=[Ljava.lang.Object;@79b1cbee, title=[Ljava.lang.Object;@510feef6, year=[Ljava.lang.Object;@3b7609aa, votes=[Ljava.lang.Object;@3e522055,
},
parameter={
webix_operation=update,
id=1736151956759, title=New Movie, year=2025, votes=999999,
}
}
削除時
{
queryString=, postData=FileUpload, contentLength=80.0, contextPath=,
parameters={
webix_operation=[Ljava.lang.Object;@6628475f, id=[Ljava.lang.Object;@55a35e5b, title=[Ljava.lang.Object;@25cae84d, year=[Ljava.lang.Object;@77f08f85
},
parameter={
webix_operation=delete,
id=1735646393786, title=New Movie, year=2025, votes=999999
}
}
webix_operation
属性がセットされているので、これで判別して処理できそうです。
datatable で編集したデータを記録する②
save
プロパティでウェブサーバを指定する代わりに、データが変更されたイベントを受けて webix.ajax().post
メソッドを使ってウェブサーバにデータを送ることにします。
datatable
に行が追加されるタイミングで onBeforeAdd
イベント、表示の内容が変更されると onDataUpdate
イベント、行が削除されるタイミングで onBeforeDelete
イベントが発生します。
$$('list').attachEvent('onBeforeAdd', function(id, data, index){
webix.ajax().post("https://httpbin.org/post", data)
});
$$('list').attachEvent('onDataUpdate', function(id, data, old){
webix.ajax().post("https://httpbin.org/post", data)
});
$$('list').attachEvent('onBeforeDelete', function(id){
var data = $$('list').getItem(id);
webix.ajax().post("https://httpbin.org/post", data)
});
webix.ajax()
コンポーネントから以下の POST リクエストが送られます。
追加時
{
queryString=, postData=FileUpload, contentLength=44.0, contextPath=,
parameters={
id=[Ljava.lang.Object;@1259bd3, title=[Ljava.lang.Object;@3dfdc651, year=[Ljava.lang.Object;@64f7624b
},
parameter={
id=1736152703287, title=New Movie, year=2025
}
}
更新時
{
queryString=, postData=FileUpload, contentLength=57.0, contextPath=,
parameters={
id=[Ljava.lang.Object;@7684661a, title=[Ljava.lang.Object;@a7dd8bb, year=[Ljava.lang.Object;@3ebad4fb, votes=[Ljava.lang.Object;@111c2aee
},
parameter={
id=1736152703287, title=New Movie, year=2025, votes=999999
}
}
削除時
{
queryString=, postData=FileUpload, contentLength=57.0, contextPath=,
parameters={
id=[Ljava.lang.Object;@5b8a2409, title=[Ljava.lang.Object;@334f35ba, year=[Ljava.lang.Object;@41831fb3, votes=[Ljava.lang.Object;@1a4be87a,
},
parameter={
id=1736152703287, title=New Movie, year=2025, votes=999999
}
}
post()
する時点で、送信する data
オブジェクトに追加か更新か削除か判別するための属性を追加する必要あります。あるいは、操作ごとに送信先の URL を別々にしてもいいでしょう。
Webix の datatable を使ってみる④
datatable に新規追加の空行を追加する
一覧表示の最終に空行を表示してデータを入力して追加できると便利ですね。
onBeforeRender
イベントで空行を追加します。
{
view:'datatable',
id:"list",
columns:[
{ id:'no', header:"", width:30 },
{ id:'title', header:"Title", width:300, editor:'text' },
{ id:'year', header:"Released", width:80, editor:'text' },
{ id:'votes', header:"Votes", width:100, editor:'text' }
],
editable:true,
},
(中略)
$$('list').attachEvent('onBeforeRender', function(){
var dt = this;
if (dt.count() == 0){
dt.add({});
}
if (canAdd(dt.getLastId())) {
dt.add({});
}
dt.data.each(function(obj, i){
obj['no'] = i + 1;
});
});
先頭の列を「no」にして、連番を表示するようにしています。↑
行を追加していいか判定する
上記のコードで canAdd
関数を用意して使っています。指定された行の、全てのセルが空でないか確認して、空がなければ行の追加を可能と判断します。↓
function canAdd(id) {
return $$('list').getColumns(true).every(function(obj){
return ($$('list').getItem(id)[obj.id])
});
}
datatable で編集したデータを記録する③
onBeforeAdd
イベントが発生する空行を追加した時点では全ての項目は空なので、ここで記録する処理しても意味ありません。
onDataUpdate
イベントでも全ての項目がセットされていないと、処理してはだめでしょう。canAdd
を使って判定します。
$$('list').attachEvent('onBeforeAdd', function(id, data){
// 何もしない
});
$$('list').attachEvent('onDataUpdate', function(id, data){
if (!canAdd(id)) {
return;
}
webix.ajax().post("https://httpbin.org/post", data);
});
webix.ajax()
コンポーネントから以下の POST リクエストが送られます。post()
する時点で追加か更新か判別して処理できていません。
追加・更新時
{
queryString=, postData=FileUpload, contentLength=62.0, contextPath=,
parameters={
id=[Ljava.lang.Object;@725ff6bf, title=[Ljava.lang.Object;@e3169fd, year=[Ljava.lang.Object;@cf80f2, votes=[Ljava.lang.Object;@6dfc719f, no=[Ljava.lang.Object;@b5e3d70,
},
parameter={
id=1736153323221, title=New Movie, year=2025, votes=999999, no=3,
},
}
id
を使ってサーバ側で登録済か確認して、未登録なら追加、そうでなければ更新の処理するのがいいでしょう。