LoginSignup
0
0

More than 3 years have passed since last update.

Lightning Web ComponentのDatatableの罫線が正常に表示されないバグへの対処方法

Last updated at Posted at 2020-02-14

Lightning Web Component(LWC)で正常に罫線が表示されないバグ

バグなのか自分の実装方法が悪いのか、lightning web component標準のlightning-datatableを使うと正常に罫線が表示されてくれない。
筆者が現状確認できているバグ(?)とソリューションを考えた。
もしこの状況がバグでなく公式なソリューションを知っている方は教えて欲しい。

バグの概要

  1. lightning-datatableで実装してx軸スクロールすると一部の罫線が途切れる。下の画像のsample4とsample5の間で罫線が切れていることがわかる。
    スクリーンショット 2020-02-13 19.34.08.png

  2. lightning-datatableでslds-table_col-borderedを実装しようとすると一列目だけ罫線が表示されない
    スクリーンショット 2020-02-13 19.43.17.png

lightning web component標準のdatatableを実装したソースコード

1のソース

<template>
    <div class="slds-table_col-bordered">
        <lightning-datatable data={sorted_data} columns={columns} key-field="id" sorted-by={sorted_by}
            onsort={handle_sort_data} sorted-direction={sorted_direction}>
        </lightning-datatable>
    </div>
</template>
import { LightningElement, track } from 'lwc';

const columns = [
    { label: 'sample1', fieldName: 'sample1', type: 'text', sortable: true, fixedWidth: 200 },
    { label: 'sample2', fieldName: 'sample2', type: 'date', sortable: true, fixedWidth: 200 },
    { label: 'sample3', fieldName: 'sample3', type: 'percent', sortable: true, fixedWidth: 200 },
    { label: 'sample4', fieldName: 'sample4', type: 'currency', sortable: true, fixedWidth: 200 },
];

const data = [
    { sample1: 'sample3', sample2: '2020-01-10', sample3: 0.784, sample4: 321456 },
    { sample1: 'sample1', sample2: '2020-01-15', sample3: 0.3248, sample4: 3214 },
    { sample1: 'sample5', sample2: '2020-01-20', sample3: 0.321149, sample4: 356 },
    { sample1: 'sample3', sample2: '2020-01-2', sample3: 0.149, sample4: 35644444 },
]

export default class Qiita_sample_code_2 extends LightningElement {
    @track sorted_data = data;
    @track columns = columns;
    @track sorted_by;
    @track sorted_direction;

    handle_sort_data(event) {
        this.sorted_by = event.detail.fieldName;
        this.sorted_direction = event.detail.sortDirection;
        this.sort_data(event.detail.fieldName, event.detail.sortDirection);
    }

    sort_data(fieldname, direction) {
        let sorting_data = JSON.parse(JSON.stringify(this.sorted_data));
        let keyValue = (a) => {
            return a[fieldname];
        };
        let isReverse = direction === 'asc' ? 1 : -1;
        sorting_data.sort((x, y) => {
            x = keyValue(x) ? keyValue(x) : '';
            y = keyValue(y) ? keyValue(y) : '';
            return isReverse * ((x > y) - (y > x));
        });
        this.sorted_data = sorting_data;
    }
}

2のソース

<template>
    <lightning-datatable data={sorted_data} columns={columns} key-field="id" sorted-by={sorted_by}
        onsort={handle_sort_data} sorted-direction={sorted_direction}>
    </lightning-datatable>
</template>
import { LightningElement, track } from 'lwc';

const columns = [
    { label: 'sample1', fieldName: 'sample1', type: 'text', sortable: true, fixedWidth: 200 },
    { label: 'sample2', fieldName: 'sample2', type: 'date', sortable: true, fixedWidth: 200 },
    { label: 'sample3', fieldName: 'sample3', type: 'percent', sortable: true, fixedWidth: 200 },
    { label: 'sample4', fieldName: 'sample4', type: 'currency', sortable: true, fixedWidth: 200 },
    { label: 'sample5', fieldName: 'sample5', type: 'text', fixedWidth: 200 },
    { label: 'sample6', fieldName: 'sample6', type: 'date', fixedWidth: 200 },
    { label: 'sample7', fieldName: 'sample7', type: 'percent', fixedWidth: 200 },
    { label: 'sample8', fieldName: 'sample8', type: 'currency', fixedWidth: 200 },
    { label: 'sample9', fieldName: 'sample9', type: 'text', fixedWidth: 200 },
    { label: 'sample10', fieldName: 'sample10', type: 'date', fixedWidth: 200 },
    { label: 'sample11', fieldName: 'sample11', type: 'percent', fixedWidth: 200 },
    { label: 'sample12', fieldName: 'sample12', type: 'currency', fixedWidth: 200 },
    { label: 'sample13', fieldName: 'sample13', type: 'text', fixedWidth: 200 },
    { label: 'sample14', fieldName: 'sample14', type: 'date', fixedWidth: 200 },
    { label: 'sample15', fieldName: 'sample15', type: 'percent', fixedWidth: 200 },
    { label: 'sample16', fieldName: 'sample16', type: 'currency', fixedWidth: 200 },
];

const data = [
    { sample1: 'sample3', sample2: '2020-01-10', sample3: 0.784, sample4: 321456, sample5: 'sample', sample6: '2020-01-10', sample7: 50, sample8: 321456, sample9: 'sample', sample10: '2020-01-10', sample11: 50, sample12: 321456, sample13: 'sample', sample14: '2020-01-10', sample15: 50, sample16: 321456 },
    { sample1: 'sample1', sample2: '2020-01-15', sample3: 0.3248, sample4: 3214, sample5: 'sample', sample6: '2020-01-10', sample7: 50, sample8: 321456, sample9: 'sample', sample10: '2020-01-10', sample11: 50, sample12: 321456, sample13: 'sample', sample14: '2020-01-10', sample15: 50, sample16: 321456 },
    { sample1: 'sample5', sample2: '2020-01-20', sample3: 0.321149, sample4: 356, sample5: 'sample', sample6: '2020-01-10', sample7: 50, sample8: 321456, sample9: 'sample', sample10: '2020-01-10', sample11: 50, sample12: 321456, sample13: 'sample', sample14: '2020-01-10', sample15: 50, sample16: 321456 },
]

export default class Qiita_sample_code_2 extends LightningElement {
    @track sorted_data = data;
    @track columns = columns;
    @track sorted_by;
    @track sorted_direction;

    handle_sort_data(event) {
        this.sorted_by = event.detail.fieldName;
        this.sorted_direction = event.detail.sortDirection;
        this.sort_data(event.detail.fieldName, event.detail.sortDirection);
    }

    sort_data(fieldname, direction) {
        let sorting_data = JSON.parse(JSON.stringify(this.sorted_data));
        let keyValue = (a) => {
            return a[fieldname];
        };
        let isReverse = direction === 'asc' ? 1 : -1;
        sorting_data.sort((x, y) => {
            x = keyValue(x) ? keyValue(x) : '';
            y = keyValue(y) ? keyValue(y) : '';
            return isReverse * ((x > y) - (y > x));
        });
        this.sorted_data = sorting_data;
    }
}

ソリューション

  1. この場合の問題点は、x軸方向にスクロールした場合にのみ発生するので、そもそもスクロールしないようなdatatableであればLightning Web Component標準のdatatableを使用して良い
    例としては、以下のような場合である。
    スクリーンショット 2020-02-13 19.52.19.png
    だが、以下のようにカラムが増えすぎてスクロールしないと見れないような場合は他の手段を考えなければならない。
    スクリーンショット 2020-02-14 13.19.08.png

  2. Lightning Design System(slds)のdatatableを使う
    その方法を以下に記す。

lightning design systemのdatatableを使う方法

実演とソースコードを記す。

実演

以下のようにx軸スクロールも、罫線の途切れもなく実装できていることがわかる。

bt469-kae9m.gif

lightning design systemのdatatableを実装したソースコード

<template>
    <div
        class="slds-table slds-table_cell-buffer slds-table_bordered slds-is-relative slds-table_col-bordered slds-scrollable --x">
        <table>
            <thead>
                <tr>
                    <th>
                        <div>sample2
                            <lightning-icon if:true={arrow_direction} icon-name="utility:arrowup" size="x-small"
                                name="sample1" onclick={handleSort}>
                            </lightning-icon>
                            <lightning-icon if:false={arrow_direction} icon-name="utility:arrowdown" size="x-small"
                                name="sample1" onclick={handleSort}>
                            </lightning-icon>
                        </div>
                    </th>
                    <th>
                        <div>sample1
                            <lightning-icon if:true={arrow_direction} icon-name="utility:arrowup" size="x-small"
                                name="sample2" onclick={handleSort}>
                            </lightning-icon>
                            <lightning-icon if:false={arrow_direction} icon-name="utility:arrowdown" size="x-small"
                                name="sample2" onclick={handleSort}>
                            </lightning-icon>
                        </div>
                    </th>
                    <th>
                        <div>sample3
                            <lightning-icon if:true={arrow_direction} icon-name="utility:arrowup" size="x-small"
                                name="sample3" onclick={handleSort}>
                            </lightning-icon>
                            <lightning-icon if:false={arrow_direction} icon-name="utility:arrowdown" size="x-small"
                                name="sample3" onclick={handleSort}>
                            </lightning-icon>
                        </div>
                    </th>
                    <th>
                        <div>sample1
                            <lightning-icon if:true={arrow_direction} icon-name="utility:arrowup" size="x-small"
                                name="sample1" onclick={handleSort}>
                            </lightning-icon>
                            <lightning-icon if:false={arrow_direction} icon-name="utility:arrowdown" size="x-small"
                                name="sample1" onclick={handleSort}>
                            </lightning-icon>
                        </div>
                    </th>
                    <th>
                        <div>sample1
                            <lightning-icon if:true={arrow_direction} icon-name="utility:arrowup" size="x-small"
                                name="sample1" onclick={handleSort}>
                            </lightning-icon>
                            <lightning-icon if:false={arrow_direction} icon-name="utility:arrowdown" size="x-small"
                                name="sample1" onclick={handleSort}>
                            </lightning-icon>
                        </div>
                    </th>
                    <th>
                        <div>sample1
                            <lightning-icon if:true={arrow_direction} icon-name="utility:arrowup" size="x-small"
                                name="sample1" onclick={handleSort}>
                            </lightning-icon>
                            <lightning-icon if:false={arrow_direction} icon-name="utility:arrowdown" size="x-small"
                                name="sample1" onclick={handleSort}>
                            </lightning-icon>
                        </div>
                    </th>
                    <th>
                        <div>sample1
                            <lightning-icon if:true={arrow_direction} icon-name="utility:arrowup" size="x-small"
                                name="sample1" onclick={handleSort}>
                            </lightning-icon>
                            <lightning-icon if:false={arrow_direction} icon-name="utility:arrowdown" size="x-small"
                                name="sample1" onclick={handleSort}>
                            </lightning-icon>
                        </div>
                    </th>
                    <th>
                        <div>sample1
                            <lightning-icon if:true={arrow_direction} icon-name="utility:arrowup" size="x-small"
                                name="sample1" onclick={handleSort}>
                            </lightning-icon>
                            <lightning-icon if:false={arrow_direction} icon-name="utility:arrowdown" size="x-small"
                                name="sample1" onclick={handleSort}>
                            </lightning-icon>
                        </div>
                    </th>
                    <th>
                        <div>sample1
                            <lightning-icon if:true={arrow_direction} icon-name="utility:arrowup" size="x-small"
                                name="sample1" onclick={handleSort}>
                            </lightning-icon>
                            <lightning-icon if:false={arrow_direction} icon-name="utility:arrowdown" size="x-small"
                                name="sample1" onclick={handleSort}>
                            </lightning-icon>
                        </div>
                    </th>
                    <th>
                        <div>sample1
                            <lightning-icon if:true={arrow_direction} icon-name="utility:arrowup" size="x-small"
                                name="sample1" onclick={handleSort}>
                            </lightning-icon>
                            <lightning-icon if:false={arrow_direction} icon-name="utility:arrowdown" size="x-small"
                                name="sample1" onclick={handleSort}>
                            </lightning-icon>
                        </div>
                    </th>
                    <th>
                        <div>sample1
                            <lightning-icon if:true={arrow_direction} icon-name="utility:arrowup" size="x-small"
                                name="sample1" onclick={handleSort}>
                            </lightning-icon>
                            <lightning-icon if:false={arrow_direction} icon-name="utility:arrowdown" size="x-small"
                                name="sample1" onclick={handleSort}>
                            </lightning-icon>
                        </div>
                    </th>
                    <th>
                        <div>sample1
                            <lightning-icon if:true={arrow_direction} icon-name="utility:arrowup" size="x-small"
                                name="sample1" onclick={handleSort}>
                            </lightning-icon>
                            <lightning-icon if:false={arrow_direction} icon-name="utility:arrowdown" size="x-small"
                                name="sample1" onclick={handleSort}>
                            </lightning-icon>
                        </div>
                    </th>
                </tr>
            </thead>
            <tbody>
                <template for:each={sorted_data} for:item="element">
                    <tr key={element.id} class="slds-hint-parent">
                        <td>
                            <div class="slds-truncate">
                                {element.sample1}
                            </div>
                        </td>
                        <td>
                            <div class="slds-truncate">
                                {element.sample2}
                            </div>
                        </td>
                        <td>
                            <div>
                                {element.sample3}
                            </div>
                        </td>
                        <td>
                            <div>
                                {element.sample3}
                            </div>
                        </td>
                        <td>
                            <div>
                                {element.sample3}
                            </div>
                        </td>
                        <td>
                            <div>
                                {element.sample3}
                            </div>
                        </td>
                        <td>
                            <div>
                                {element.sample3}
                            </div>
                        </td>
                        <td>
                            <div>
                                {element.sample3}
                            </div>
                        </td>
                        <td>
                            <div>
                                {element.sample3}
                            </div>
                        </td>
                        <td>
                            <div>
                                {element.sample3}
                            </div>
                        </td>
                        <td>
                            <div>
                                {element.sample3}
                            </div>
                        </td>
                        <td>
                            <div>
                                {element.sample3}
                            </div>
                        </td>
                    </tr>
                </template>
            </tbody>
        </table>
    </div>
</template>
import { LightningElement, track } from 'lwc';

//単純にstringとしてソートしているためか日付の場合zero paddingが必須
const data = [
    { id: 1, sample1: '2020-10-01', sample2: 123132321, sample3: 'a' },
    { id: 2, sample1: '2020-10-02', sample2: 6544566, sample3: 'b' },
    { id: 3, sample1: '2020-10-03', sample2: 98744166, sample3: 'c' },
    { id: 4, sample1: '2020-10-04', sample2: 8716555, sample3: 'd' },
    { id: 5, sample1: '2020-10-05', sample2: 498743, sample3: 'e' },
    { id: 6, sample1: '2020-10-06', sample2: 41688446, sample3: 'c' },
    { id: 7, sample1: '2020-10-07', sample2: 4687, sample3: 'e' },
    { id: 8, sample1: '2020-10-08', sample2: 4687, sample3: 'd' },
    { id: 9, sample1: '2020-10-09', sample2: 7763734, sample3: 'b' },
    { id: 10, sample1: '2020-10-10', sample2: 468743, sample3: 'a' },
];


export default class activity_log extends LightningElement {
    @track sorted_data = [];
    sort_direction = 'asc';
    sort_column = 'sample1';

    get arrow_direction() {
        return this.sort_direction === 'asc' ? true : false;
    }

    connectedCallback() {
        this.sorted_data = data;
        this.sort_data(this.sort_column, this.sort_direction);
    }

    // カラムのクリックハンドラー
    handleSort(event) {
        this.sort_direction = (this.sort_direction === 'asc') ? 'desc' : 'asc';
        this.sort_column = event.target.name;
        this.sort_data(this.sort_column, this.sort_direction);
    }

    //実際にソートしてる関数
    sort_data(sort_column, direction) {
        // JSON化しないとリアクティブにdatatableに反映されない
        let sorting_data = JSON.parse(JSON.stringify(this.sorted_data));

        // ソートするカラムの値を参照
        let keyValue = (a) => {
            return a[sort_column];
        };

        let isReverse = direction === 'asc' ? 1 : -1;

        sorting_data.sort((x, y) => {
            x = keyValue(x) ? keyValue(x) : '';
            y = keyValue(y) ? keyValue(y) : '';
            return isReverse * ((x > y) - (y > x));
        });

        this.sorted_data = sorting_data;
    }
}

参考になるURL

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0