Quantcast
Channel: かずきのBlog@hatena
Viewing all articles
Browse latest Browse all 1387

ReactとTypeScriptでデータグリッド表示するのに使えるreact-datagrid

$
0
0

業務で使おうと思ったらそれなりのデータグリッド部品が必要になりますよね。そんなとき、ちょっと我慢すれば使えそうなreact-datagridを紹介したいと思います。

react-datagrid

npm install react-datagrid --save
tsd install react-datagrid

で導入が可能なデータグリッド部品です。公式サイトは以下のページになります。

A carefully crafted datagrid for React

サンプルを見ると、大体どんなことが出来るのかわかるようになっています。

A carefully crafted datagrid for React

ライセンスはMITになるので、ライセンス的にも使いやすいライブラリです。

React + TypeScriptで使う

npmとtsdコマンドを打ち込んで必要なファイルを準備したら、node_modules/react-datagrid/dist/index-no-normalize.min.cssをプロジェクトにコピーしてプロジェクトに含めます。そしてindex.htmlで参照するように設定します。今回はWebAPIの呼び出し結果をバインドしたいので、whatwg-fetchもインストールして参照しておきました。index.htmlは以下のような雰囲気になります。

<!DOCTYPE html><html><head><metahttp-equiv="Content-Type"content="text/html; charset=utf-8" /><metacharset="utf-8" /><title>Hello world</title><linkhref="index-no-normalize.min.css"rel="stylesheet" /></head><body><divid="content"></div><scriptsrc="scripts/fetch.js"></script><scriptsrc="bundle.js"></script></body></html>

WebAPI

こんな感じのASP.NET WebAPIを準備しておきます。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading;
using System.Web.Http;

namespace ReactApplication3.Controllers
{
    publicclass PeopleController : ApiController
    {
        public IHttpActionResult Get()
        {
            Thread.Sleep(5000);
            var source = Enumerable.Range(1, 1000)
                .Select(x => new Person
                {
                    Id = x,
                    Name = $"おかずき{x}",
                    Age = x % 30 + 30,
                });
            return Ok(source);
        }
    }

    publicclass Person
    {
        publicint Id { get; set; }
        publicstring Name { get; set; }
        publicint Age { get; set; }
    }
}

react-datagridを使う

idPropertyとdataSoruceとcolumnsは必須っぽいです。TypeScriptだと割とインテリセンスがきくので簡単に書けます。色気を出してフィルタリングも実装してみました。onFilterに何かしら追加するとフィルタリングが有効になるみたいです。

/// <reference path="../typings/whatwg-fetch/whatwg-fetch.d.ts" />import * as React from 'react';
import * as ReactDOM from 'react-dom';
import ReactDataGrid = require('react-datagrid');

class Person {
    constructor(public id: number, public name: string, public age: number) {}}interface DataGridComposerState {
    data: Person[];
    loading: boolean;
}class DataGridComposer extends React.Component<{}, DataGridComposerState> {private originalData: Person[];
    constructor(props: {}) {super(props);
        this.state = { data: [], loading: true};
    }private dataSource() {return fetch('api/People', {
            headers: {'Accept-Type': 'application/json'}})
            .then(x => x.json());
    }private handleFilter(column, value, allFilterValues) {var data = this.originalData;
        Object.keys(allFilterValues).forEach(name => {var f = allFilterValues[name] as string;
            if (f === '') {return;
            }

            data = data.filter(x => {return x[name].toString().indexOf(f) === 0;
            });
        });

        this.setState({ data: data } as DataGridComposerState);
    }

    componentDidMount() {this.dataSource().then(x => {this.originalData = x as Person[];
            this.setState({
                data: x as Person[],
                loading: false} as DataGridComposerState);
        });
    }

    render() {return (
            <ReactDataGrid
                idProperty='id'
                dataSource={this.state.data} 
                columns={[{ name: 'name', title: '名前', width: 200 },
                    { name: 'age', title: '年齢', width: 200 }]}
                pagination={false} 
                style={{ height: 300 }}
                loading={this.state.loading}
                liveFilter={true}
                onFilter={this.handleFilter.bind(this)}/>
        );
    }}class App extends React.Component<{}, {}> {
    render() {return (
            <div>
                <h1>OK Google.</h1>
                <DataGridComposer />
            </div>);
    }}

ReactDOM.render(
    <App />,
    document.getElementById('content'));

実行してみる

こんな感じでローディング中の表示がされます。

f:id:okazuki:20160102200504p:plain

そしてデータが表示されます。

f:id:okazuki:20160102200538p:plain

フィルタリングもばっちり。

f:id:okazuki:20160102200622p:plain

いまいちなところと注意点

style属性のheightでデータグリッドの高さを決めれるのですが、ここはnumber型じゃないとダメです。'500px'とかって書くと効きません。あと、ローカライズが弱いです。一部表示が英語のままでもいいかなというのが許容できない場合は使えないと思います。


Viewing all articles
Browse latest Browse all 1387

Trending Articles