React
AdminLTE
grid-layout

AdminLTEにreact-grid-layout機能を追加する(Visual Studio版)

I will apply react-grid-layout to Admin LTE built in last time.
AdminLTE をVisual Studio でビルドする - Qiita

react-grid-layoutを使ってドロップ可能なグリッドシステムをAdminLTEに適用します。

grid.gif

react-grid-layoutとは

React-Grid-Layout はPackery や Gridster に影響を受けて作成された派生プロジェクト。

react-grid-layout機能を追加

前回作ったAdminLTEに機能を追加していきます

package.jsonの編集

package.jsonに以下を追記します。バージョン番号はその時の最新とします。

    "@types/react-grid-layout": "0.16.4",
    "react-grid-layout": "0.16.5"

CSS参照の追加

ClientApp/css/site.cssに以下を追加。

react-grid-layout.css
.react-grid-item:not(.react-grid-placeholder) {
    background: #ccc;
    border: 1px solid black;
}

boot.tsxに追加
function renderApp()の上に以下を追加します。

boot.tsx
import 'admin-lte';

// Font Awesome
import '../node_modules/font-awesome/css/font-awesome.min.css';
//// Ionicons
import '../node_modules/ionicons/dist/css/ionicons.css';
 //Morris chart
import '../node_modules/morris.js/morris.css';
// jvectormap
import '../node_modules/jvectormap/jquery-jvectormap.css';
// Date Picker
import '../node_modules/bootstrap-datepicker/dist/css/bootstrap-datepicker.min.css';
// Daterange picker
import '../node_modules/bootstrap-daterangepicker/daterangepicker.css';

//react-grid-layout
import '../node_modules/react-grid-layout/css/styles.css';
import '../node_modules/react-resizable/css/styles.css';

コンポーネント作成

コンポーネント作成

ReactGridLayoutComponentコンポーネントを作成

ClientApp/components/Counter.tsxを複製してReactGridLayoutComponent.tsxに名前を変更します。(名前は別の名前でもOK。)
もしくは、ClientApp/components/ にReactGridLayoutComponent.tsxを作成します。

インターフェース

レイアウトを管理するインターフェースを作成します。
ファイル末尾でもいいし、import文の下でもOK。

ReactGridLayoutComponent.tsx
interface ReactGridLayoutItem {
    i: string;
    x: number;
    y: number;
    w: number;
    h: number;
    minW?: number;
    maxW?: number;
    static?: boolean;
}

interface ReactGridLayoutState {
    layout: Array<ReactGridLayoutItem>;
    loading: boolean;
}

クラス名

クラス名をReactGridLayoutComponentに変更します。
Component引数を以下のように変更します。

RouteComponentProps<{}>, Array<ReactGridLayoutItem>

変更後は以下になります。

ReactGridLayoutComponent.tsx
export class ReactGridLayoutComponent extends React.Component<RouteComponentProps<{}>, ReactGridLayoutState> {

インポート

importは以下になるようにします。

ReactGridLayoutComponent.tsx
import * as React from 'react';
import { RouteComponentProps } from 'react-router';
import * as ReactGridLayout from 'react-grid-layout';

コンストラクタの追加

コンストラクタを追加し、画面ロード時にReactGridLayoutに3×1のグリッドを作成するためのlayout変数を作成します。

ReactGridLayoutComponent.tsx
    constructor() {
        super();

        var layout: ReactGridLayoutItem[] = [
            { i: 'a', x: 0, y: 0, w: 1, h: 2 },
            { i: 'b', x: 1, y: 0, w: 3, h: 2, minW: 2, maxW: 4 },
            { i: 'c', x: 4, y: 0, w: 1, h: 2 },
            { i: 'd', x: 4, y: 4, w: 1, h: 2 },
            { i: 'e', x: 4, y: 6, w: 1, h: 2 },
            { i: 'f', x: 4, y: 8, w: 1, h: 2 },
        ];


        this.state = { layout: layout, loading: true };
    }

レンダー

renderにはコンポーネントを表示するコードを記入します。

ReactGridLayoutComponent.tsx
    public render() {
        return <div>
            <ReactGridLayout className="layout" layout={this.state.layout} cols={12} rowHeight={30} width={1200}>
                <div key="a">a</div>
                <div key="b">b</div>
                <div key="c">c</div>
                <div key="d">d</div>
                <div key="e">e</div>
                <div key="f">f</div>
            </ReactGridLayout>
        </div>;
    }

最終的には以下になります。

ReactGridLayoutComponent.tsx
import * as React from 'react';
import { RouteComponentProps } from 'react-router';
import * as ReactGridLayout from 'react-grid-layout';


interface CounterState {
    currentCount: number;
}

export class ReactGridLayoutComponent extends React.Component<RouteComponentProps<{}>, ReactGridLayoutState> {
    constructor() {
        super();

        var layout: ReactGridLayoutItem[] = [
            { i: 'a', x: 0, y: 0, w: 1, h: 2 },
            { i: 'b', x: 1, y: 0, w: 3, h: 2, minW: 2, maxW: 4 },
            { i: 'c', x: 4, y: 0, w: 1, h: 2 },
            { i: 'd', x: 4, y: 4, w: 1, h: 2 },
            { i: 'e', x: 4, y: 6, w: 1, h: 2 },
            { i: 'f', x: 4, y: 8, w: 1, h: 2 },
        ];

        this.state = { layout: layout, loading: true };
    }

    public render() {
        return <div>
            <ReactGridLayout className="layout" layout={this.state.layout} cols={12} rowHeight={30} width={1200}>
                <div key="a">a</div>
                <div key="b">b</div>
                <div key="c">c</div>
                <div key="d">d</div>
                <div key="e">e</div>
                <div key="f">f</div>
            </ReactGridLayout>
        </div>;
    }

}


interface ReactGridLayoutItem {
    i: string;
    x: number;
    y: number;
    w: number;
    h: number;
    minW?: number;
    maxW?: number;
    static?: boolean;
}

interface ReactGridLayoutState {
    layout: Array<ReactGridLayoutItem>;
    loading: boolean;
}


ルート情報の追加

ルート情報の追加

/ClientApp/routes.tsxに以下の2行を追加します。

import { ReactGridLayoutComponent } from './components/ReactGridLayoutComponent';`
<Route path='/reactgridlayout' component={ReactGridLayoutComponent } />

最終的には以下になります。

routes.tsx
import * as React from 'react';
import { Route } from 'react-router-dom';
import { Layout } from './components/Layout';
import { Home } from './components/Home';
import { FetchData } from './components/FetchData';
import { Counter } from './components/Counter';
import { ReactGridLayoutComponent } from './components/ReactGridLayoutComponent';

export const routes = <Layout>
    <Route exact path='/' component={ Home } />
    <Route path='/counter' component={ Counter } />
    <Route path='/fetchdata' component={ FetchData } />
    <Route path='/reactgridlayout' component={ReactGridLayoutComponent } />
</Layout>;

画面メニューに参照の追加

ReactGridLayout画面を表示するリンクを追加します。
/ClientApp/components/MainSidebar.tsxに以下を追加します。

<ul className="treeview-menu">
    <li className="active">
        <NavLink to={'/reactgridlayout'} activeClassName='active'>
            <span className='glyphicon glyphicon-th-list'></span> react-grid-layout
        </NavLink>
    </li>
</ul>


実行

この状態で実行してみる。エラーなく表示されればOKです。

grid.gif

うまく動かない場合

NPM系

NPMアイコンが以下のような場合はライブラリがインストールされていない場合があるので、
pacage.jsonを見直してみてください。

image

NPMを開けば何がインストールされていないかを知ることができます。

image

VS系の原因

ただたんにVSが表示不具合を起こしている場合もあります。
再起動したら治る時があります。

npm-shrinkwrap.jsonの再作成

コマンドプロンプトにて以下を実行する事で、npm-shrinkwrap.jsonを再作成する事ができます。

npm shrinkwrap

ソース

今回のソースは以下に置いてます。

Admin-LTE-VS/2 admin-lte-react-grid-layout at master · sugasaki/Admin-LTE-VS