Динамическое отображение столбца с использованием div с фиксированным первым столбцом, а всего остального с горизонтальной полосой прокрутки

#javascript #css #angular5

#javascript #css #angular5

Вопрос:

Мне нужна ваша помощь.

Я создаю N-уровневую вложенную таблицу с динамическими столбцами

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

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

Я не хочу использовать какие-либо внешние библиотеки. Я создал пользовательскую таблицу на основе div вместе с сеткой CSS

Ниже приведены скриншоты того, что я делал до сих пор

введите описание изображения здесь

Вот код для справки:

HTML:

 <ng-container *ngFor="let rData of reportData; let i = index; last as isLast" >
  <div class="myTr report-row">
    <div class="myTd">
        <button 
           class="btn report-btn-sm" 
           *ngIf="checkIfHaveMoreSplits(this.splitOpt[0].id) !== 0 amp;amp; rData.isCollapsed == true"
           (click)="splitData(rowWiseFilterObj(rData,this.splitOpt[0].id),this.splitOpt[0].id,sFilters,splitOpt,i,rData,selectedDate)"
           row="rData"> </button>
        <button 
           class="btn report-btn-sm" 
           *ngIf="checkIfHaveMoreSplits(this.splitOpt[0].id) !== 0 amp;amp; rData.isCollapsed == false" 
           (click)="removeDynamicComponent(rData,i)"
           >-</button>
           <span *ngIf="this.splitOpt[0].id == 'campid'">{{rData['campaign_name']}}</span>

          <span *ngIf="this.splitOpt[0].id !== '__time' amp;amp; this.splitOpt[0].id !== 'campid'">{{rData[this.splitOpt[0].id]}}</span>
          <span *ngIf="this.splitOpt[0].id === '__time'">{{ rData[this.splitOpt[0].id]  | date:'dd-MM-yyyy HH:mm:ss Z'}}</span>


    </div>
    <div class="myTdGroupBox"><div class="myTdGroup">
      <div class="myTd">{{convertToDecimals(rData.impressions,2)}}</div>
      <div class="myTd">{{convertToDecimals(rData.conversions,2)}}</div>
      <div class="myTd">{{convertToDecimals(rData.bids,2)}}</div>
      <div class="myTd">{{convertToDecimals(rData.wins,2)}}</div>
      <div class="myTd">$ {{convertToDecimals(rData.spend,2)}}</div>
      <div class="myTd">
        <button class="btn btn-secondary m-btn m-btn--label-danger m-btn--label-danger m-btn--bolder m-btn--uppercase btn-sm" *ngIf="this.splitOpt[0].id=='campid'" (click)="excludeReport(rowWiseFilterObj(rData,this.splitOpt[0].id))"> <i class="la la-close"></i> </button>
        <button class="btn btn-secondary m-btn m-btn--label-danger m-btn--bolder m-btn--uppercase btn-sm" disabled="disabled" *ngIf="this.splitOpt[0].id!='campid'"> <i class="la la-ban"></i> </button>

      </div>
    </div></div>
  </div>

  <div *ngIf="isLast" class="text-right col-12">{{altrows("#ffffff","#f5f5f5")}}

            <a href="javascript:void(0)" class="m-link" (click)="loadmore()" style="    margin: 10px -30px 15px 10px;
    background: #5ccdde;
    color: #fff;
    padding: 2px 10px;
    font-size: 12px;" *ngIf="reportData.length > 19"> Load more </a>
        </div>
    <ng-template #dynamic ></ng-template>

    </ng-container>
  <div class="myTr" style="margin-top:20px;">
    <div class="myTd"></div>
    <div class="myTdGroupBox"><div class="myTdGroup">
      <div class="myTd"></div>
    </div></div>
  </div>
</div>
  

JS:

 getReport() {
        this.hidePopup();
        if(this.splitOpt.length === 0) {
            // this.updateGraph(this.currentGraphSelection);
            return false;
        } 


        var apiFilters: any = [{}];
        for (var i = 0; i < this.sFilters.length; i  ) {
            if (this.sFilters[i].values.length > 0) {
                var k;
                k = this.sFilters[i].id
                apiFilters[0][k] = this.sFilters[i].values
            }
        }

        var split = this.splitOpt[0].id;
        this.reportData=[];
        this.reportLoading = true;
        this._apis.getReportData(split, apiFilters[0],this.selectedDate,1,20).subscribe(response => {
            if (response.status == 1200) {
                this.reportData = response.data.split_by_data;
                this.reportData.map(function(obj) {
                  obj.isCollapsed = true;
                  return obj;
               });
            this.totalImpressions=response.data.totalCount[0].impressions;
            this.totalConversions=response.data.totalCount[0].conversions;
            this.totalBids=response.data.totalCount[0].bids;
            this.totalWins=response.data.totalCount[0].wins;
            this.totalSpend=response.data.totalCount[0].spend;
               this.reportLoading = false;
               var contentGroups = document.querySelectorAll('.myTr:not(:last-child) .myTdGroupBox');
var ctrlGroup = document.querySelector('.myTr:last-child .myTdGroupBox');
ctrlGroup.addEventListener('scroll', (ev)=> {
    contentGroups.forEach((g)=> g.scrollTo(ctrlGroup.scrollLeft, 0) );
});
               this.cd.detectChanges();

            }
        });
    }
  

Комментарии:

1. У вас не может быть только части переполнения таблицы. Вам нужно будет аккуратно нарисовать две таблицы рядом друг с другом внутри div. Один div имеет фиксированную ширину, другой рядом с ним может затем переполниться.

2. Я предполагаю, что возможно, я видел это в библиотеке таблиц данных, я знаю о решениях, которые вы предлагаете! Также существует так много вложенных таблиц, которые вставляются с использованием динамических компонентов. В моем случае это решение не сильно поможет

3. Макет здесь довольно сложный, но спасибо за предложение

Ответ №1:

Вы можете переделать таблицу, используя <div> s с гибкой компоновкой.

Я пишу полный пример ниже. У вас нет всей гибкости таблицы, однако она довольно мощная. Вы также можете прикрепить скроллер столбцов к странице и сделать его видимым, даже если таблица больше высоты страницы. И многое другое…

Вы увидите, что я делаю прокручиваемые столбцы одинаковой ширины. Вы можете установить разную ширину. Я бы сделал это, используя классы для столбцов.

Я считаю, что код прост для понимания. Если вам нужна помощь или вы хотите использовать больше возможностей гибкой компоновки, вы можете увидеть эту страницу: https://css-tricks.com/snippets/css/a-guide-to-flexbox /

Javascript, чтобы заставить все двигаться вместе, — это самая простая вещь здесь. Идея состоит в том, чтобы получить событие прокрутки и применить ту же прокрутку, что и к строкам overflow: hidden .

Создавать новые столбцы так же просто, как создавать их на a <table> , просто <div> разбивайте s на .myTdGroup элементы.

 <style>
  .myTable {
    font-family: sans-serif;
    font-size: 15px;
    width: 450px;
    border: 2px solid #BBB;
    position: relative;
  }
  .myTr {
    display: flex;
    align-items: center;
  }
  .myTr:nth-child(odd) { background: #DDD }
  .myTdGroupBox {
    overflow: hidden;
  }
  .myTdGroup {
    display: flex;
    align-items: center;
    width: 500px;
  }
  .myTr:last-child { background: #777 }
  .myTr:last-child .myTdGroupBox { overflow-x: scroll }
  .myTr:last-child .myTd { padding: .1px 0 0 0 }
  .myTd {
    margin: 0 1em;
    padding: .5em 0;
    flex-grow: 1;
    flex-basis: 50px;
    overflow-x: auto;
    white-space: nowrap;
  }
  .myTr > .myTd { flex-basis: 150px; }
</style>

<div class="myTable">
  <div class="myTr">
    <div class="myTd">Line A</div>
    <div class="myTdGroupBox"><div class="myTdGroup">
      <div class="myTd">A1</div>
      <div class="myTd">A222</div>
      <div class="myTd">A333</div>
      <div class="myTd">A444</div>
      <div class="myTd">A555</div>
      <div class="myTd">A666</div>
    </div></div>
  </div>
  <div class="myTr">
    <div class="myTd">Line BBBBB</div>
    <div class="myTdGroupBox"><div class="myTdGroup">
      <div class="myTd">B111</div>
      <div class="myTd">B2</div>
      <div class="myTd">B333</div>
      <div class="myTd">BX<br>444</div>
      <div class="myTd">B555</div>
      <div class="myTd">B666</div>
    </div></div>
  </div>
  <div class="myTr">
    <div class="myTd">Line<br>CCC<br>CCC</div>
    <div class="myTdGroupBox"><div class="myTdGroup">
      <div class="myTd">C111</div>
      <div class="myTd">C222</div>
      <div class="myTd">C3</div>
      <div class="myTd">C 444 444 444 end</div>
      <div class="myTd">C555</div>
      <div class="myTd">C666</div>
    </div></div>
  </div>
  <div class="myTr">
    <div class="myTd">Line DDD</div>
    <div class="myTdGroupBox"><div class="myTdGroup">
      <div class="myTd">D111</div>
      <div class="myTd">D222</div>
      <div class="myTd">D333</div>
      <div class="myTd">D444</div>
      <div class="myTd">D555</div>
      <div class="myTd">D666</div>
    </div></div>
  </div>
  <div class="myTr">
    <div class="myTd"></div>
    <div class="myTdGroupBox"><div class="myTdGroup">
      <div class="myTd"></div>
    </div></div>
  </div>
</div>

<script>
var contentGroups = document.querySelectorAll('.myTr:not(:last-child) .myTdGroupBox');
var ctrlGroup = document.querySelector('.myTr:last-child .myTdGroupBox');
ctrlGroup.addEventListener('scroll', (ev)=> {
    contentGroups.forEach((g)=> g.scrollTo(ctrlGroup.scrollLeft, 0) );
});
</script>
  

Комментарии:

1. Привет, да, я попробовал ваше решение, я сохранил этот javascript в ngAfterViewInit, но он не работает с динамическими строками

2. я также пытался сохранить код js после того, как мой запрос ajax все еще не работал! может быть, что-то нужно сделать с angular 5?

3. Я добавил код к вопросу, посмотрите на него прямо сейчас, решение работает, но прокручивается только первая статическая строка, а не результаты, полученные из серверной части

4. Я также попытался реализовать с помощью статического массива его работу stackblitz.com/edit/angular-a7z3pa Проверьте здесь, не знаю, что не так с ajax-запросами

5. Я также пытался выполнять функцию всякий раз, когда отображается последняя строка, но все еще не работает

Ответ №2:

Джанак Праджапати, ранее я делал что-то похожее на фиксированную таблицу.

https://jsfiddle.net/Sampath_Madhuranga/2o4h6u3f/10/

   

.tg {
     border-collapse:collapse;
     border-spacing:0;
     border-color:#ccc;
}
 .tg td{
     font-family:Arial, sans-serif;
     font-size:14px;
     padding:9px 20px;
     border-style:solid;
     border-width:1px;
     overflow:hidden;
     word-break:normal;
     border-color:#ccc;
     color:#333;
     background-color:#fff;
}
 .tg th{
     font-family:Arial, sans-serif;
     font-size:14px;
     font-weight:normal;
     padding:9px 20px;
     border-style:solid;
     border-width:1px;
     overflow:hidden;
     word-break:normal;
     border-color:#ccc;
     color:#333;
     background-color:#f0f0f0;
}
 .tg .tg-29qf{
     font-weight:bold;
     background-color:#f0f0f0;
     border-color:inherit;
     text-align:left
}
 .tg .tg-xldj{
     border-color:inherit;
     text-align:left
}
 .tg .sticky-col-1{
     left: 0;
     position: absolute;
     top: auto;
     width: 120px;
}
 .tg .sticky-col-2{
     left: 160px;
     position: absolute;
     top: auto;
     width: 70px;
}
 .zui-scroller {
     margin-left: 295px;
     overflow-x: scroll;
     overflow-y: visible;
     padding-bottom: 5px;
     width: 900px;
}
 .tg .tg-kiyi{
     font-weight:bold;
     border-color:inherit;
     text-align:left;
     min-width:100px;
}
 .tg .cover-head-cell{
     min-width:300px;
     text-align:center;
}
 .tg .tg-29qf{
     font-weight:bold;
     background-color:#f0f0f0;
     border-color:inherit;
     text-align:left;
     min-width:100px;
}
 .tg .tg-xldj{
     border-color:inherit;
     text-align:left;
     min-width:100px;
}
 .tg .tg-dvid{
     font-weight:bold;
     background-color:#efefef;
     border-color:inherit;
     text-align:left;
     vertical-align:top;
     min-width:100px;
}
 @media screen and (max-width: 767px) {
    .tg {
        width: auto !important;
    }
    .tg col {
        width: auto !important;
    }
    .tg-wrap {
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
    }
}  
    

 <div class="tg-wrap">
       <div class="zui-scroller">
          <table class="tg">
             <thead>
                <tr>
                   <th class="tg-kiyi sticky-col-1" rowspan="2">Title 1</th>
                   <th class="tg-kiyi sticky-col-2" rowspan="2">Title 2</th>
                   <th class="tg-kiyi cover-head-cell" colspan="3">Title 3</th>
                   <th class="tg-kiyi" rowspan="2">Title 4</th>
                   <th class="tg-kiyi cover-head-cell" colspan="3">Title 5</th>
                   <th class="tg-kiyi" rowspan="2">Title 6</th>
                   <th class="tg-kiyi cover-head-cell" colspan="3">Title 7</th>
                   <th class="tg-kiyi" rowspan="2">Title 8</th>
                </tr>
                <tr>
                   <th class="tg-kiyi sticky-col-1" rowspan="2">Subtitle 1</th>
                   <th class="tg-kiyi sticky-col-2" rowspan="2">Subtitle 2</th>
                   <th class="tg-29qf">Subtitle 3</th>
                   <th class="tg-29qf">Subtitle 4</th>
                   <th class="tg-29qf">Subtitle 5</th>
                   <th class="tg-29qf">Subtitle 6</th>
                   <th class="tg-29qf">Subtitle 7</th>
                   <th class="tg-29qf">Subtitle 8</th>
                   <th class="tg-29qf">Subtitle 9</th>
                   <th class="tg-29qf">Subtitle 10</th>
                   <th class="tg-29qf">Subtitle 11</th>
                </tr>
             </thead>
             <tr>
                <td class="tg-xldj sticky-col-1">sdz</td>
                <td class="tg-xldj sticky-col-2">saz</td>
                <td class="tg-xldj">as</td>
                <td class="tg-xldj">as</td>
                <td class="tg-xldj">as</td>
                <td class="tg-xldj">as</td>
                <td class="tg-xldj">as</td>
                <td class="tg-xldj">as</td>
                <td class="tg-xldj">as</td>
                <td class="tg-xldj">as</td>
                <td class="tg-xldj">as</td>
                <td class="tg-xldj">sa</td>
                <td class="tg-xldj">as</td>
                <td class="tg-xldj">as</td>
             </tr>
             <tr>
                <td class="tg-xldj sticky-col-1">as</td>
                <td class="tg-xldj sticky-col-2">sa</td>
                <td class="tg-xldj">as</td>
                <td class="tg-xldj">as</td>
                <td class="tg-xldj">as</td>
                <td class="tg-xldj">as</td>
                <td class="tg-xldj">as</td>
                <td class="tg-xldj">as</td>
                <td class="tg-xldj">sa</td>
                <td class="tg-xldj">as</td>
                <td class="tg-xldj">as</td>
                <td class="tg-xldj">as</td>
                <td class="tg-xldj">as</td>
                <td class="tg-xldj">sa</td>
             </tr>
             <tr>
                <td class="tg-dvid sticky-col-1">Total</td>
                <td class="tg-dvid sticky-col-2">23</td>
                <td class="tg-dvid">sd</td>
                <td class="tg-dvid">ds</td>
                <td class="tg-dvid">sd</td>
                <td class="tg-dvid">sd</td>
                <td class="tg-dvid">ds</td>
                <td class="tg-dvid">dd</td>
                <td class="tg-dvid">sd</td>
                <td class="tg-dvid">ds</td>
                <td class="tg-dvid">sd</td>
                <td class="tg-dvid">ds</td>
                <td class="tg-dvid">dd</td>
                <td class="tg-dvid">sd</td>
             </tr>
          </table>
       </div>
    </div>   

Пожалуйста, попробуйте это и дайте мне знать вашу идею. Спасибо.

Комментарии:

1. выглядит хорошо для меня! я бы не хотел использовать здесь теги таблиц, я хочу создать таблицу, полностью основанную на div. поскольку у меня n уровней вложенных таблиц, и вставка одной таблицы в другую мне не нравится

2. Да, это сработало! но если у меня так много записей, мне нужно перейти к концу страницы, чтобы прокручивать ее по горизонтали. Возможно ли также включить вертикальную полосу прокрутки. Я преобразовал весь макет на основе таблиц в div на основе использования свойств отображения css css. Я также обновлю его в ответ, если вы сможете помочь мне с вертикальной полосой прокрутки, это будет большое спасибо за вашу помощь

3. @JanakPrajapati, я обновил свою ссылку на JSFIDDLE. Не могли бы вы проверить и сообщить мне, этого ли вы ожидаете от меня? jsfiddle.net/Sampath_Madhuranga/2o4h6u3f/25

4. да, но опять же фиксированная позиция всегда будет отображаться при прокрутке страницы? не так ли? Я пробовал это раньше, но у меня есть график над таблицей, когда я прокручиваю страницу, эта таблица останется там, поскольку позиция фиксирована.

5. @JanakPrajapati, не могли бы вы прислать мне рабочую скрипку или что-нибудь еще?