question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

column header misalignment with body in version 11.1.2 ( same code works in 11.0.4 )

See original GitHub issue

I’m submitting a … (check one with “x”)

[x] bug report => search github for a similar issue or PR before submitting
[ ] feature request
[ ] support request => Please do not submit support request here, post on Stackoverflow or Gitter

Current behavior With the same typescript code on my side, I have a different rendering depending on ngx-datatable version I use :

This is what I have with ngx-datatable version 11.0.4 list-11 0 4

and with version 11.1.2 list-11 1 2

Expected behavior Same rendering regardless of version

Reproduction of the problem

my-list component :

html

<ngx-datatable
    class="material fullscreen"                        
    [columnMode]="'force'"
    [rowClass]="getRowClass"
    [headerHeight]="50"
    [footerHeight]="50"
    [rowHeight]="50"
    [externalPaging]="true"
    [externalSorting]="true"
    [loadingIndicator]="loading"
    [limit]="pageSize"
    [offset]="pageOffset"
    [count]="totalCount"
    [rows]="items"
    [columns]="columns"
>

    <!-- Header template -->
    <ng-template #headerTemplate let-column="column">
        <span class="datatable-header-cell-wrapper"><span class="datatable-header-cell-label draggable text-truncate" (click)="sort()">{{ column.name | translate }}</span></span>
    </ng-template>

    <!-- Cell template -->
    <ng-template #cellTemplate let-column="column" let-value="value">
        <div [innerHTML]="getCellHtml(value, column) | safe: 'html'"></div>
    </ng-template>

    <!-- Actions template -->
    <ng-template #actionTemplate let-row="row" let-value="value">
        <!-- Buttons omitted -->
    </ng-template>
    
</ngx-datatable>

typescript

@Component({
  selector: 'my-list',
  [...]
})
export class MyListComponent implements OnInit, OnDestroy {
    @Input('searchFn') searchFn: (term: string) => Observable<any>;
    @Input('columnFn') columnFn: () => Observable<Columns[]>;
    @Input('getCellFn') getCellFn: (column: string, value: string) => string;
    [...]
    constructor(private el: ElementRef, private sanitizer: DomSanitizer) {}

    public ngOnInit() {
        // on init, get columns and then do search
        this._column().then(() => this._search(''));
    }

    private getCellHtml(value, column) : string
    {
        const type = typeof value;

        // Allow for column custom text
        if (this.getCellFn !== undefined) {
            var innerHtml = this.getCellFn(column.prop, value);
            if (innerHtml !== undefined)
                return innerHtml;
        }

        switch (type) {
            case 'string': {
                if (moment(value, moment.ISO_8601).isValid()) {
                    return moment(value).local().format('L');
                } else {
                    const sanitizedValue = this.sanitizer.sanitize(SecurityContext.HTML, value);
                    return `<span class="text-truncate">${sanitizedValue}</span>`;
                }
            }
            case 'boolean': {
                return value ? '<i class="material-icons">check</i>' : '';
            }
        }

        // Any other case, return value as is
        return value;
    }

    private _search(term: string) {
        this.searchFn(term).subscribe(result => this.items = [...result.items]);
    }

    private _column() {
        const promise = new Promise((resolve, reject) => { 

            this.columns = []

            this.columnFn()
                .flatMap(preferences => preferences) // yield array items
                .map(preference => {
                    return {
                        headerTemplate: this.headerTemplate,
                        cellTemplate: this.cellTemplate,
                        name: preference.description,
                        prop: preference.fieldName,
                        sortable: true,
                        draggable: true,
                        minWidth: undefined,
                        maxWidth: undefined,
                        _index: preference.fieldOrder
                    };
                })
                .toArray()
                .subscribe(
                    result => {
                        result.sort((a, b) => a._index - b._index)
                        result.push({
                            headerTemplate: this.headerTemplate,
                            cellTemplate: this.actionTemplate,
                            name: '',
                            prop: 'id',
                            sortable: false,
                            draggable: false,
                            minWidth: 100,
                            maxWidth: 100,
                            _index: result.length
                        });
                        this.columns = [...result];

                        // Resolve promise
                        resolve();
                    }
                );

        });
        return promise;
    }

}

Consuming my-list component :

html

<my-list #myList
    sortProp="'name'"
    [columnFn]="getColumnCallback"
    [getCellFn]="formatCellCallback">
</my-list>

typescript

    [...]

    /**
     * Return Observable of items from api service
     * Note: Notation 'public xxx = () => {}' is required in order to work correctly
     */
    public searchCallback = (term: string): Observable<any> => {
        return this.myHttpApiService.search(term);
    }


    /**
     * Return columns preferences Observable from api service
     * Note: Notation 'public xxx = () => {}' is required in order to work correctly
     */
    public getColumnCallback = () => {
        return this.myHttpApiService.getFormPreferences();
    }


    /**
     * Basic formatting is handled by MyListComponent. This handler is exclusively if you want to intercept columns
     * of 'string' type and format it as you need.
     * 
     * Note: Notation 'public xxx = () => {}' is required in order to work correctly ( This keeps 'this' valid )
     */
    public formatCellCallback = (column: string, value: string): string => {
        switch (column) {
            case 'gender': return this.getGenderIcon(value);
            case 'type': return this.getTypeLabel(value);
            default: return undefined;
        }
    }
    [...]

Please tell us about your environment:

windows 10 pro, vs code, npm, node

  • Table version: 0.8.x

11.0.4 vs 11.1.2

  • Angular version: 2.0.x

5.0.2

  • Browser: [all | Chrome XX | Firefox XX | IE XX | Safari XX | Mobile Chrome XX | Android X.X Web Browser | iOS XX Safari | iOS XX UIWebView | iOS XX WKWebView ]

Chrome

  • Language: [all | TypeScript X.X | ES6/7 | ES5] typescript 2.6.1

Issue Analytics

  • State:open
  • Created 6 years ago
  • Reactions:6
  • Comments:24 (3 by maintainers)

github_iconTop GitHub Comments

3reactions
stewxcommented, Mar 1, 2018

Is this the same issue, or different? If it’s different, I will log a new issue.

screencastgif

2reactions
enniobcommented, Mar 1, 2018

@stewx just uploaded the image, I had replies to the email and it didn’t attached it.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Why are these HTML column headers misaligned?
I believe it's faster for large tables to be rendered with dynamic column widths, header/column alignment is then guaranteed, plus the code ......
Read more >
Cognos Analytics 11.0 Fix Lists - IBM
A comprehensive list of defect corrections for major releases, refresh packs and fix packs of Cognos Analytics 11.0.x.0 Details of the APARs ...
Read more >
JavaScript Data Grid Release notes - Handsontable
Added a new feature that lets you copy the contents of column headers by using 3 new context menu options: "Copy with headers",...
Read more >
Changelog - ngx-datatable - GitBook
Fix: Fixed issue wi th misaligned body content #1326. Fix: Fixed Default Sort Behavior Of Table With Custom Templates #1308. Chore: Fixed link...
Read more >
Fleetsoft11_changes.txt
NET 4.5 -CHANGE: bold entity code in reminder emails -CHANGE: ... -FIX: version 11.0.4 mismatch error -FIX: column headings were not ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found