scrollable and rtl doesn't work in primeNG table - scrollbar

I want to have a table with horizontal and vertical scrollbar .
showcase in primeNg work properly when we don't use rtl direction for our table !
when we use horizontal scroll and rtl direction scroll doesn't scroll on table header ! table header is fixed when we use in rtl dir
mycode:
<div dir="rtl">
<p-table dir="rtl" #dt
[columns]="cols"
[value]="cars"
[paginator]="true"
[rows]="10"
[scrollable]="true"
scrollHeight="200px"
[style]="{width:'1000px'}">
<!-- below for fixining columns withs-->
<ng-template pTemplate="colgroup" let-columns>
<colgroup>
<col *ngFor="let col of columns" style="width:150px;">
</colgroup>
</ng-template>
<ng-template pTemplate="header" let-columns>
<tr dir="rtl" class="ui-rtl">
<th *ngFor="let col of columns">
{{col.header}}
</th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-rowData let-columns="columns">
<tr [pSelectableRow]="rowData">
<td *ngFor="let col of columns">
{{rowData[col.field]}}
</td>
</tr>
</ng-template>
</p-table>
</div>

PrimeNG doesn't support RTL for table component.
So workaround would be to listen for scroll event on the body and assign the same exact shift to the header:
scrollableTableBodyScroll: () => void;
constructor(
private el: ElementRef,
private zone: NgZone,
) { }
ngAfterViewInit(): void {
const scrollableTableHeader: HTMLElement = this.el.nativeElement.querySelector('.ui-table-scrollable-header');
const scrollableTableBody: HTMLElement = this.el.nativeElement.querySelector('.ui-table-scrollable-body');
this.zone.runOutsideAngular(() => {
this.scrollableTableBodyScroll = this.renderer.listen(scrollableTableBody, 'scroll', () => {
scrollableTableHeader.scrollLeft = scrollableTableBody.scrollLeft;
});
});
}
ngOnDestroy(): void {
this.scrollableTableBodyScroll();
}
Reasons behind use of NgZone

Related

how to I add a scrollbar for the table

i am mapping values on the table, i want the table to have scrollbar when it reaches some max-height,
adding overflow: scrollbar, width max-height: 600px did not work, the table just keeps extending downwards
return (
<div className='journaltable-div'>
<table className='table table-journal'>
<thead className='table-head'>
<tr className='table-head-row'>
<th>Task</th>
<th>Date-created</th>
<th>Action</th>
</tr>
</thead>
<tbody className='table-body'>
{ journalList.map((entry) => {
const { key, journal, time } = entry
return (
<tr key={key} className="table-body-row">
<td>{journal}</td>
<td>{time}</td>
<td><button
className='button button-complete'
onClick={(e) => {
e.stopPropagation
addToLog(key, "completed")
removeJournal(key)
}}>completed</button><button
className='button button-delete'
onClick={(e) => {
e.stopPropagation
addToLog(key, "deleted")
removeJournal(key)
}}>delete</button></td>
</tr>
)
}) }
</tbody>
</table>
<div className='redirect-div'>
<button className='redirect-logs' style={{cursor: 'pointer'}} onClick={() => {handleLogs()}}> Check Logs</button>
</div>
</div>
.table-journal {
overflow: scroll;
max-height: 600px;
}
also tried placing on tbody did not work either
put all of your return values from the map function in a div with scrollit style class and add these codes to your CSS:
.scrollit {
overflow:scroll;
height:100px;
}
your code have look like this:
return (
<div className='journaltable-div'>
<table className='table table-journal'>
<thead className='table-head'>
<tr className='table-head-row'>
<th>Task</th>
<th>Date-created</th>
<th>Action</th>
</tr>
</thead>
<tbody className='table-body'>
<div className="scrollit">
{ journalList.map((entry) => {
const { key, journal, time } = entry
return (
<tr key={key} className="table-body-row">
<td>{journal}</td>
<td>{time}</td>
<td><button
className='button button-complete'
onClick={(e) => {
e.stopPropagation
addToLog(key, "completed")
removeJournal(key)
}}>completed</button><button
className='button button-delete'
onClick={(e) => {
e.stopPropagation
addToLog(key, "deleted")
removeJournal(key)
}}>delete</button></td>
</tr>
)
}) }
</div>
</tbody>
</table>
<div className='redirect-div'>
<button className='redirect-logs' style={{cursor: 'pointer'}} onClick={() => {handleLogs()}}> Check Logs</button>
</div>
</div>

Nebular Tree Grid table body scrollable

Is it possible to make just the table body without the table header of a table (tree Grid) in nebular theme vertically scrollable?
The basic tree grid looks like this:
<table [nbTreeGrid]="dataSource">
<tr nbTreeGridHeaderRow *nbTreeGridHeaderRowDef="allColumns"></tr>
<tr nbTreeGridRow *nbTreeGridRowDef="let row; columns: allColumns" (click)="doSth(row.data)"></tr>
<ng-container nbTreeGridColumnDef="name">
<th nbTreeGridHeaderCell *nbTreeGridHeaderCellDef >Name</th>
<td nbTreeGridCell *nbTreeGridCellDef="let row">
{{ row.data.name }}
</td>
</ng-container>
<ng-container nbTreeGridColumnDef="age">
<th nbTreeGridHeaderCell *nbTreeGridHeaderCellDef >Age</th>
<td nbTreeGridCell *nbTreeGridCellDef="let row">
{{ row.data.age }}
</td>
</ng-container>
<!-- and so on ... -->
</table>
I achieved to wrap it into a nb-list so that makes it scrollable but the table header will not stay in place.
<nb-list style="max-height: 250px;">
<nb-list-item>
<table [nbTreeGrid]="dataSource">
<tr nbTreeGridHeaderRow *nbTreeGridHeaderRowDef="allColumns"></tr>
<tr nbTreeGridRow *nbTreeGridRowDef="let row; columns: allColumns" (click)="doSth(row.data)"></tr>
<ng-container nbTreeGridColumnDef="name">
<th nbTreeGridHeaderCell *nbTreeGridHeaderCellDef >Name</th>
<td nbTreeGridCell *nbTreeGridCellDef="let row">
{{ row.data.name }}
</td>
</ng-container>
<ng-container nbTreeGridColumnDef="age">
<th nbTreeGridHeaderCell *nbTreeGridHeaderCellDef >Age</th>
<td nbTreeGridCell *nbTreeGridCellDef="let row">
{{ row.data.age }}
</td>
</ng-container>
<!-- and so on ... -->
</table>
</nb-list-item>
</nb-list>
When i examine the HTML structure in browser i see that the HTML element i want to be scrollable is <tbody> element. So i also tried to add some css but also without effect
tbody {
max-height: 100px !important;
overflow-y: scroll !important;
}
I just cant access the tbody element and give it a class that i can handle with css or something so i just dont know what to do anymore...

How to avoid elements transitioning from top of page with transition

My elements seems to transition or "fly" in from the top of my page. This is not what I want as I want them to transition from the row to which they belong. How can I achieve this behaviour?
Vue template looks like this.
<li class="accordion-parent" v-for="(parent, pIndex) in list" :key="pIndex">
<div class="accordion-entry">
<div
#click="() => toggleExpand(pIndex)"
:class="[{ expanded: expanded === pIndex }, outerDiv]"
>
<table class="accordion-expanded">
<transition-group name="fade" tag="v-layout" class="manual-v-layout">
<tbody
v-for="index in 10"
:key="index"
class="cycle"
v-show="expanded === pIndex"
>
<tr class="view-more-row" v-show="expanded === pIndex">
<td />
<td class="view-more-cell">
<span> View more cycles </span>
</td>
</tr>
</tbody>
<tbody key="id">
<transition name="fade">
<tr class="view-more-row" v-show="expanded === pIndex">
<td />
<td class="view-more-cell">
<span> View more cycles </span>
</td>
</tr>
</transition>
</tbody>
</transition-group>
</table>
</div>
</li>
Vue script
<script>
export default {
name: "AnalyticsAccordion",
data() { return { list: [1,2,3,4] }
},};
</script>
Css
<style>
tbody {
transition: 0.5s;
width: 100%;
}
.manual-v-layout {
display: flex;
flex-wrap: wrap;
flex-direction: row;
}
</style>

How to align p-table and p-chart elements side by side

I have a very little experience developing UI but I wanted to accomplish a task quickly where I have to put a p-table and p-chart elements side by side. I tried to use flex layout as well as float left and right as below but not getting the expected result. How can this be fixed?
<div fxLayout="row" fxLayoutAlign="start center">
<div fxFlex="50%" class="floatLeft">
<p-table [value]="summaryList" [scrollable]="true" scrollHeight="200px"
[resizableColumns]="true" [style]="{width:'500px'}">
<ng-template pTemplate="caption">
XXX Summary
</ng-template>
<ng-template pTemplate="header">
<tr>
<th *ngFor="let col of summaryColumns" [pSortableColumn]="col.field">
{{col.header}}
<p-sortIcon [field]="col.field"></p-sortIcon>
</th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-summaryList>
<tr>
<td *ngFor="let col of summaryColumns">
{{summaryList[col.field]}}
</td>
</tr>
</ng-template>
</p-table>
</div>
<div class="col-md-4 content-section implementation" fxFlex="50%" class="floatRight">
<p-chart type="line" [data]="dailyData" title="XXX Chart" extender="overrideXAxis"></p-chart>
</div>
</div>
You can try doing this.
<div class="container">
<p-table [value]="summaryList" height="200" [scrollable]="true" scrollHeight="100px" [resizableColumns]="true" [style]="{width:'50%', float:'left'} ">
<ng-template pTemplate="caption">
My Awesome Summary
</ng-template>
<ng-template pTemplate="header">
<tr>
<th *ngFor="let col of summaryColumns" [pSortableColumn]="col.field">
{{col.header}}
<p-sortIcon [field]="col.field"></p-sortIcon>
</th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-summaryList>
<tr>
<td *ngFor="let col of summaryColumns">
{{summaryList[col.field]}}
</td>
</tr>
</ng-template>
</p-table>
<p-chart height="250" [responsive]="false" type="bar" [data]="data" [options]="options" [style]="{width:'48%', float:'right'}"></p-chart>
</div>
then add style to your component.css
.container{
display: flex;
justify-content: center;
align-items: center;
}

Why am I getting 'TypeError: Cannot read property 'slice' of undefined'?

I am working on a small project. It is an ASP.NET MVC/Angular5 project. I am simply trying to populate a tableView (PrimeNG) with data that is selected from a Modal or PrimeNG Dialog.
Here is a snipit of the relevent ts file:
displayIndexDialog: boolean;
index: Index = {};
selectedIndex: Index;
newIndex: boolean;
indexes: Index[];
//METHODS
getIndexes() {
this._indexesService.getIndexes().subscribe(indexes => this.indexList = indexes);
}
showIndexAdd() {
this.newIndex = true;
this.selectedIndex = {};
this.displayIndexDialog = true;
this.getIndexes();
}
closeIndexDialog() {
this.displayIndexDialog = false;
}
saveIndex() {
let index = [...this.indexes];
if (this.newIndex) {
index.push(this.index);
}else
index[this.indexes.indexOf(this.selectedIndex)] = this.index;
this.indexes = index;
this.indexes = null;
this.displayIndexDialog = false;
};
//INTERFACE
interface Index {
defaultIndex?;
pK_Index ?;
description ?;
}
Here is the relevent HTML:
<!--INDEX TABLE-->
<p-table [columns]="cols3" [value]="indexes">
<ng-template pTemplate="header" let-columns>
<tr>
<th *ngFor="let col of columns">
{{col.header}}
</th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-rowData let-columns="columns">
<tr [pSelectableRow]="rowData">
<td *ngFor="let col of columns">
{{rowData[col.field]}}
</td>
</tr>
</ng-template>
<ng-template pTemplate="summary" let-rowData>
<div style="text-align:left">
<button class="btn-cblt" type="button" pButton icon="fa-plus" (click)="showIndexAdd()" label="Add"></button>
</div>
</ng-template>
</p-table><br />
<h4>Differentials</h4>
<p-table [columns]="cols2" [value]="diffs1">
<ng-template pTemplate="header" let-columns>
<tr>
<th *ngFor="let col of columns">
{{col.header}}
</th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-rowData let-columns="columns">
<tr [pSelectableRow]="rowData">
<td *ngFor="let col of columns">
{{rowData[col.field]}}
</td>
</tr>
</ng-template>
<ng-template pTemplate="summary" let-rowData>
<div style="text-align:left">
<button class="btn-cblt" type="button" pButton icon="fa-plus" (click)="showDifferentialAdd()" label="Add"></button>
</div>
</ng-template>
</p-table>
<!--ADD INDEX DIALOG-->
<p-dialog class="sha" header="Add Index" [(visible)]="displayIndexDialog" [responsive]="true" showEffect="fade" [modal]="true" [width]="600" [height]="300">
<div class="ui-g ui-fluid" *ngIf="selectedIndex">
<div class="ui-g-12">
<div class="ui-g-4">
<label for="Index">Index</label>
</div>
<div class="ui-g-8">
<p-dropdown id="index" placeholder="Select an Index" [options]="indexList" [(ngModel)]="selectedIndex.description" [ngModelOptions]="{standalone: true}" optionLabel="description" [showClear]="true"> </p-dropdown>
</div>
</div>
<div class="ui-g-12">
<div class="ui-g-4">
<label for="isDefault">Default Index?</label>
</div>
<div class="ui-g-8">
<p-checkbox name="defaultIndex" id="isDefault" [(ngModel)]="selectedIndex.defaultIndex"></p-checkbox>
</div>
</div>
<div id="indexName">{{index.pK_Index ? index.pK_Index: ' ' }}</div>
</div>
<div class="ui-dialog-buttonpane ui-helper-clearfix">
<button class="btn-cblt" type="button" pButton icon="fa-check" (click)="saveIndex()" label="Save"></button>
<button class="btn-cblt-danger" type="button" pButton icon="fa-close" (click)="closeIndexDialog()" label="Cancel"></button>
</div>
</p-dialog>
Every time I click the 'save' button on the dialog, in the console I get:

I have been staring at this for 3 days now and Have no idea why this isn't working. Please help!
The Resolution to this was #ConnorsFan 's suggestion. The indexes were not initialized. Setting indexes: Index[] = [] fixed the issue. Thank you #ConnorsFan.

Resources