primefaces / primeng

The Most Complete Angular UI Component Library
https://primeng.org
Other
10.59k stars 4.62k forks source link

Scrollable Datatable with headerColumnGroup won't start #2978

Closed giovstef75 closed 7 years ago

giovstef75 commented 7 years ago

[x ] bug report => Search github for a similar issue or PR before submitting [ ] feature request => Please check if request is not on the roadmap already https://github.com/primefaces/primeng/wiki/Roadmap [ ] support request => Please do not submit support request here, instead see http://forum.primefaces.org/viewforum.php?f=35



**Current behavior**
Exception returned if datatable is using headerColumnGroup

ComponentiDettaglioComponent.html:206 ERROR TypeError: Cannot read property 'style' of undefined
    at DataTable.fixColumnWidths (datatable.js:1288)
    at DataTable.initResizableColumns (datatable.js:1198)
    at DataTable.ngAfterViewChecked (datatable.js:462)
    at callProviderLifecycles (core.es5.js:11164)
    at callElementProvidersLifecycles (core.es5.js:11136)
    at callLifecycleHooksChildrenFirst (core.es5.js:11120)
    at checkAndUpdateView (core.es5.js:12152)
    at callViewAction (core.es5.js:12507)
    at execEmbeddedViewsAction (core.es5.js:12465)
    at checkAndUpdateView (core.es5.js:12145)

**Expected behavior**
Datatable to show up

**Minimal reproduction of the problem with instructions**
This is my datatable code:

    <p-dataTable #dtComponentiDestinatari [value]="componente.componentiDestinatariNotifiche" [scrollable]="true" selectionMode="single" 
        [(selection)]="currentSelection" [scrollHeight]="scHeight()" emptyMessage="Nessun Destinatario inserito" resizableColumns="true" *ngIf="visible">
        <p-headerColumnGroup>
            <p-row>
                <p-column [style]="{width:'8%'}" header="Tipo" rowspan="2"></p-column>
                <p-column [style]="{width:'18%'}" header="Nome" rowspan="2"></p-column>
                <p-column [style]="{width:'34%'}" header="Email" rowspan="2"></p-column>
                <p-column [style]="{width:'36%'}" header="Notifiche Attivate" colspan="3"></p-column>
                <p-column [style]="{width:'4%'}" header="" rowspan="2"></p-column>
            </p-row>
            <p-row>
                <p-column [style]="{width:'12%'}" header="Data Lim.">
                    <ng-template pTemplate="header">
                        <span  pTooltip="Data Limite" tooltipPosition="top">Data Lim.</span>
                    </ng-template>     
                </p-column>
                <p-column [style]="{width:'12%'}" header="Ins. Data Lim.">
                    <ng-template pTemplate="header">
                        <span  pTooltip="Inserimento Data Limite" tooltipPosition="top">Ins. Data Lim.</span>
                    </ng-template>     
                </p-column>
                <p-column [style]="{width:'12%'}" header="Ins. Data Ok">
                    <ng-template pTemplate="header">
                        <span  pTooltip="Inserimento Data Ok" tooltipPosition="top">Ins. Data Ok</span>
                    </ng-template>     
                </p-column>
            </p-row>
        </p-headerColumnGroup>
        <p-column [style]="{width:'8%'}" field="tipo" [sortable]="true"></p-column>
        <p-column [style]="{width:'18%'}" field="nome" [sortable]="true"></p-column>
        <p-column [style]="{width:'34%'}" field="email" [sortable]="true"></p-column>
        <p-column [style]="{width:'12%'}" styleClass="col-check" field="dtlNotificaAutomatica" [sortable]="false">
            <ng-template let-item="rowData" let-index="rowIndex" pTemplate="body">
                <input type="checkbox" [(ngModel)]="item.dtlNotificaAutomatica" [name]="'dtlNotificaAutomatica'+index">
            </ng-template>             
        </p-column>        
        <p-column [style]="{width:'12%'}" styleClass="col-check" field="dtlNotifica" [sortable]="false">
            <ng-template let-item="rowData" let-index="rowIndex" pTemplate="body">
                <input type="checkbox" [(ngModel)]="item.dtlNotifica" [name]="'dtlNotifica'+index">
            </ng-template>            
        </p-column>    
        <p-column [style]="{width:'12%'}" styleClass="col-check" field="dtoNotifica" [sortable]="false">
            <ng-template let-item="rowData" let-index="rowIndex" pTemplate="body">
                <input type="checkbox" [(ngModel)]="item.dtoNotifica" [name]="'dtoNotifica'+index">
            </ng-template>            
        </p-column>    
        <p-column [style]="{width:'4%'}" styleClass="col-icon">
            <ng-template let-item="rowData" pTemplate="body">
                <div class="btn-link" (click)="rimuoviDestinatario(item)">
                    <i class="fa fa-trash-o" aria-hidden="true"></i>
                </div>
            </ng-template>
        </p-column>                                    
    </p-dataTable>    

**Please tell us about your environment:**
<Windows 10, VS Code, IIS Express>

* **Angular version:** 4.1.3

* **PrimeNG version:** 4.0.3

* **Browser:** Chromee

* **Language:** Typscript 2.3.3

* **Node (for AoT issues):** `node --version` =   
kotojo commented 7 years ago

I was having the same issue and found this code in DataTable.js.

        if (this.scrollable) {
            var colGroup = this.domHandler.findSingle(this.el.nativeElement, 'colgroup.ui-datatable-scrollable-colgroup');
            bodyCols = colGroup.children;
            if (bodyCols) {
                for (var i = 0; i < columns.length; i++) {
                    bodyCols[i].style.width = columns[i].offsetWidth + 'px';
                }
            }
        } 

I currently have multiple levels of headers. Generic top level date header, with children that are tied to actual keys (effective date, expiration date, etc). It seems the colGroup.children length was equal to the number of actual headers tied to a field, where columns.length was the total number of header columns I had. So the loop is going out of range of the array it's iterating on.

giovstef75 commented 7 years ago

Did you fix the code in the datatable.js?

kotojo commented 7 years ago

I have not. Been trying to get other features at my work done, and haven't had enough time to see if it's as easy as switching what it iterates over, or if that has other unknown effects yet. Hopefully get a chance later today to figure that out.

giovstef75 commented 7 years ago

Got it. I asked because you wrote "I was having" so I thought you fixed that. Anyway I think fixing the code is a bit tricky, if you want to stay up to date with the primeng releases (they are far to be stable usually).

kotojo commented 7 years ago

Yeah, currently I just removed the scrollable functionality from the datatable and will try to fix it later, or just have a scrollable container around the table if it's more complicated than I hope it to be.

giovstef75 commented 7 years ago

Ok, tks.

cagataycivici commented 7 years ago

Unable to replicate with 4.1.RC, please provide a test case based on plunkr below and we'll review again.

http://plnkr.co/edit/Wj39h1?p=preview

screen shot 2017-06-28 at 17 08 11
geetuBalwani commented 7 years ago

Title or subject of this issue is bit confusing. For me this issue occurs when scrollable table is used along with resizableColumns="true". With fixed width column this issue does not occur. Check ngAfterViewChecked function in datatable.js it calls initResizableColumns method for resizableColumns which in turn invokes the code written in the comments above. Vertical and horizontal scroll bars appear correctly with fixed width defined for every column.

riturajratan commented 7 years ago

have any one find any solution i am facing same issue