Создать прокручиваемую таблицу с фиксированным столбцом - PullRequest
0 голосов
/ 18 сентября 2018

Мне нужно добиться чего-то подобного

enter image description here

Прокрутка вправо является динамической (количество столбцов является переменной), и первыйстолбец слева исправлен.Прокрутка должна осуществляться с помощью стрелок вверху изображения, но я могу договориться об этом, чтобы отказаться от этого.

Моя первая мысль состояла в том, чтобы использовать flexbox, как это (это пример для насмешки, я буду использовать угловой сng-repeat для динамического создания структуры)

.reporting-table-container {
    display: flex;
    padding-left: 25px;
    padding-right: 10px;
    margin-bottom: 15px;
}

.reporting-table-container .columns-container {
    display: flex;
    overflow-x: scroll;
    margin-right: 15px;
}

.reporting-table-container .columns-container .single-column-container {
    display: flex;
    flex-direction: column;
    justify-content: space-evenly;
}

.reporting-table-container .columns-container .single-column-container:nth-child(even), .reporting-table-container .labels-container {
    background-color: #e9e9e9;
}

.reporting-table-container .labels-container {
    display: flex;
    flex-direction: column;
    justify-content: space-evenly;
}

.reporting-table-container .labels-container > div {
    width: 100px;
    font-weight: 800px;
}
<div class="reporting-table-container">
    <div class="labels-container">
        <div>ID</div>
        <div>Product Title</div>
        <div>Strategy Name</div>
        <div>Score</div>
        <div>Message</div>
        <div>Feedback</div>
        <div>Clicks</div>
        <div>Conversion Rate</div>
        <div>Revenue</div>
    </div>
    <div class="columns-container">
        <div class="single-column-container">
            <div>2249</div>
            <div>25.5 cu. ft. French Door Refrigerator in Stainless Steel</div>
            <div>Online co-purchase 2wks</div>
            <div>230</div>
            <div>Customer also bough this other item</div>
            <div>43</div>
            <div>0.50%</div>
            <div>$282.830</div>
        </div>
         <div class="single-column-container">
            <div>2249</div>
            <div>25.5 cu. ft. French Door Refrigerator in Stainless Steel</div>
            <div>Online co-purchase 2wks</div>
            <div>230</div>
            <div>Customer also bough this other item</div>
            <div>43</div>
            <div>0.50%</div>
            <div>$282.830</div>
        </div>
         <div class="single-column-container">
            <div>2249</div>
            <div>25.5 cu. ft. French Door Refrigerator in Stainless Steel</div>
            <div>Online co-purchase 2wks</div>
            <div>230</div>
            <div>Customer also bough this other item</div>
            <div>43</div>
            <div>0.50%</div>
            <div>$282.830</div>
        </div>
<div class="single-column-container">
            <div>2249</div>
            <div>25.5 cu. ft. French Door Refrigerator in Stainless Steel</div>
            <div>Online co-purchase 2wks</div>
            <div>230</div>
            <div>Customer also bough this other item</div>
            <div>43</div>
            <div>0.50%</div>
            <div>$282.830</div>
        </div>
<div class="single-column-container">
            <div>2249</div>
            <div>25.5 cu. ft. French Door Refrigerator in Stainless Steel</div>
            <div>Online co-purchase 2wks</div>
            <div>230</div>
            <div>Customer also bough this other item</div>
            <div>43</div>
            <div>0.50%</div>
            <div>$282.830</div>
        </div>
<div class="single-column-container">
            <div>2249</div>
            <div>25.5 cu. ft. French Door Refrigerator in Stainless Steel</div>
            <div>Online co-purchase 2wks</div>
            <div>230</div>
            <div>Customer also bough this other item</div>
            <div>43</div>
            <div>0.50%</div>
            <div>$282.830</div>
        </div>
<div class="single-column-container">
            <div>2249</div>
            <div>25.5 cu. ft. French Door Refrigerator in Stainless Steel</div>
            <div>Online co-purchase 2wks</div>
            <div>230</div>
            <div>Customer also bough this other item</div>
            <div>43</div>
            <div>0.50%</div>
            <div>$282.830</div>
        </div>
<div class="single-column-container">
            <div>2249</div>
            <div>25.5 cu. ft. French Door Refrigerator in Stainless Steel</div>
            <div>Online co-purchase 2wks</div>
            <div>230</div>
            <div>Customer also bough this other item</div>
            <div>43</div>
            <div>0.50%</div>
            <div>$282.830</div>
        </div>
<div class="single-column-container">
            <div>2249</div>
            <div>25.5 cu. ft. French Door Refrigerator in Stainless Steel</div>
            <div>Online co-purchase 2wks</div>
            <div>230</div>
            <div>Customer also bough this other item</div>
            <div>43</div>
            <div>0.50%</div>
            <div>$282.830</div>
        </div>
<div class="single-column-container">
            <div>2249</div>
            <div>25.5 cu. ft. French Door Refrigerator in Stainless Steel</div>
            <div>Online co-purchase 2wks</div>
            <div>230</div>
            <div>Customer also bough this other item</div>
            <div>43</div>
            <div>0.50%</div>
            <div>$282.830</div>
        </div>
<div class="single-column-container">
            <div>2249</div>
            <div>25.5 cu. ft. French Door Refrigerator in Stainless Steel</div>
            <div>Online co-purchase 2wks</div>
            <div>230</div>
            <div>Customer also bough this other item</div>
            <div>43</div>
            <div>0.50%</div>
            <div>$282.830</div>
        </div>
    </div>
</div>

но быстро стало очевидно, что границы между столбцами меток и столбцами данных не будут.Кроме того, у меня нет возможности (по крайней мере без javascript) сопоставить высоты для одной и той же строки (я должен увеличить высоту строки, учитывая самые большие данные для этой строки)

Затем я перешел в CSS Grid Layouts, но я не совсем уверен, как это должно выглядеть - в отличие от моего текущего примера, все «ячейки» будут находиться в одном блоке, поэтому я не уверен, как исправить первый столбец или как установить динамику CSS, в зависимости отколичество элементов для визуализации.

Как мне этого добиться?

Обратите внимание : хотя мой код будет использовать angularjs для динамического генерирования структуры, я считаю, что проблема заключается в чистом CSS / HTML (я хотел быхотел бы избежать использования JavaScript для генерации этого).

Заранее спасибо

1 Ответ

0 голосов
/ 20 сентября 2018

Мне наконец-то удалось это исправить с помощью CSS-сеток.

Ниже приведен пример насмешки с основным, но, конечно, я буду использовать реальные данные (а также изображение, которое загружается правильно).

Ключ был в использовании grid-template-columns и ng-style для динамического присвоения количества столбцов

Мне все еще не хватает пользовательской полосы прокрутки рядом с изображениями, но я считаю, что это другая история

(function(){

    function reportingTableController() {
      this.recommendations = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    }

    angular
        .module('app', [])
        .component('reportingTable', {
            template: `<div class="reporting-table-container" ng-style="{'grid-template-columns': '90px repeat({{$ctrl.recommendations.length + 1}}, 130px)'}">
    <div style="grid-row:1;" class="row-label-title"></div>
    <div style="grid-row:2;" class="row-label-title">ID</div>
    <div style="grid-row:3;" class="row-label-title">Product Title</div>
    <div style="grid-row:4;" ng-style="{'grid-column-end': $ctrl.recommendations.length + 2}" class="orange-delimiter"></div>
    <div style="grid-row:5;" class="row-label-title">Strategy Name</div>
    <div style="grid-row:6;" class="row-label-title">Score</div>
    <div style="grid-row:7;" class="row-label-title">Message</div>
    <div style="grid-row:8" ng-style="{'grid-column-end': $ctrl.recommendations.length + 2}" class="orange-delimiter">></div>
    <div style="grid-row:9;" class="row-label-title">Feedback</div>
    <div style="grid-row:10;" class="row-label-title">Clicks</div>
    <div style="grid-row:11;" class="row-label-title">Conversion Rate</div>
    <div style="grid-row:12;" class="row-label-title">Revenue</div>

    <div ng-class-even="'even-cell'" class="reporting-table-cell" ng-style="{'grid-row': 1, 'grid-column': $index + 2 }" ng-repeat="recommendation in $ctrl.recommendations">
        <img src="Angular/app/RecommendationsTab/mock.png" alt="recommendation image" />
    </div>

    <div ng-class-even="'even-cell'" class="reporting-table-cell" ng-style="{'grid-row': 2, 'grid-column': $index + 2 }" ng-repeat="recommendation in $ctrl.recommendations">
        2249
    </div>
    
    <div ng-class-even="'even-cell'" class="reporting-table-cell" ng-style="{'grid-row': 3, 'grid-column': $index + 2 }" ng-repeat="recommendation in $ctrl.recommendations">
        25.5 cu. ft. French Door Refrigerator in Stainless Steel
    </div>
    
    <div ng-class-even="'even-cell'" class="reporting-table-cell" ng-style="{'grid-row': 5, 'grid-column': $index + 2 }" ng-repeat="recommendation in $ctrl.recommendations">
        Online co-purchase 2wks
    </div>
    
    <div ng-class-even="'even-cell'" class="reporting-table-cell" ng-style="{'grid-row': 6, 'grid-column': $index + 2 }" ng-repeat="recommendation in $ctrl.recommendations">
        230
    </div>
    
    <div ng-class-even="'even-cell'" class="reporting-table-cell" ng-style="{'grid-row': 7, 'grid-column': $index + 2 }" ng-repeat="recommendation in $ctrl.recommendations">
        Customer also bough this other item
    </div>
    
    <div ng-class-even="'even-cell'" class="reporting-table-cell" ng-style="{'grid-row': 9, 'grid-column': $index + 2 }" ng-repeat="recommendation in $ctrl.recommendations">
        Mailbox
    </div>
    
    <div ng-class-even="'even-cell'" class="reporting-table-cell" ng-style="{'grid-row': 10, 'grid-column': $index + 2 }" ng-repeat="recommendation in $ctrl.recommendations">
        43
    </div>
    
    <div ng-class-even="'even-cell'" class="reporting-table-cell" ng-style="{'grid-row': 11, 'grid-column': $index + 2 }" ng-repeat="recommendation in $ctrl.recommendations">
        0.50%
    </div>
    
    <div ng-class-even="'even-cell'" class="reporting-table-cell" ng-style="{'grid-row': 12, 'grid-column': $index + 2 }" ng-repeat="recommendation in $ctrl.recommendations">
        $282.830
    </div>
</div>`,
            controller: reportingTableController,
        });
})();
.reporting-table-container {
    display:grid;
    padding-right: 10px;
    margin-bottom: 15px;
    margin-left: 25px;
    background-color: white;
    overflow-x: scroll;
}

.reporting-table-container .row-label-title {
    font-weight: 800;
    left: 0;
    position: sticky;
    grid-column: 1;
}

/* grid cells*/
.reporting-table-container > div {
    padding-left: 6px;
    padding-right: 6px;
    padding-top: 8px;
    padding-bottom: 10px;
}

.reporting-table-container .row-label-title, 
.reporting-table-container .reporting-table-cell.even-cell {
    background-color: #e9e9e9;
}

.reporting-table-container .reporting-table-cell, 
.reporting-table-container .row-label-title {
    border-bottom: #d1d1d1 1px solid;
}

.reporting-table-container .row-label-title:first-of-type {
    background-color: white;
    border-bottom: none;
}

.reporting-table-container .orange-delimiter {
    border: 1px solid #f96302;
    background-color: white;
    grid-column-start: 1;
    height: 1px;
    margin-bottom: 3px;
    margin-top: 3px;
    padding: 0;
}

.reporting-table-container .reporting-table-cell > img {
    max-width: calc(100% - 12px);/* 12 px of padding*/
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.2/angular.min.js"></script>
<body>
  <div ng-app="app">
   <reporting-table></reporting-table>
  </div>
</body>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...