Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<ngx-table
[data]="[
{ name: 'World', firstName: 'Hello', active: true },
{ name: 'Tools', firstName: 'NGX', active: false },
]"
[columns]="['name', 'firstName']"
[contextRowKeys]="['active']"
>
<ng-template #contextRowTmpl let-row>
{{ row | json }}
</ng-template>
</ngx-table>
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { CommonModule } from '@angular/common';
import { Component } from '@angular/core';
import { NgxTable } from '@ngx/table';

@Component({
imports: [CommonModule, NgxTable],
selector: 'context-row-one-demo',
templateUrl: './context-row-one.demo.component.html',
})
export class ContextRowOneDemoComponent {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<ngx-table
[data]="[
{ name: 'World', firstName: 'Hello', favorite: true, favoriteSince: '2023-01-01' },
{ name: 'Tools', firstName: 'NGX', favorite: false },
{ name: 'Angular', firstName: 'Framework', favorite: true, favoriteSince: '2022-05-15' },
]"
[columns]="['name', 'firstName']"
[contextRowKeys]="['favorite']"
>
<ng-template #contextRowTmpl let-row> Favorite since {{ row.favoriteSince }} </ng-template>
<ng-template #detailRowTmpl let-row> {{ row | json }} </ng-template>
</ngx-table>
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
$fav-border: 1px solid gold;

::ng-deep {
.ngx-table {
border: none !important;
}
.cdk-header-row * {
border: none !important;
text-align: left;
text-transform: capitalize;
}

.ngx-table-row-cell {
border: none !important;
}

.ngx-table-detail-cell {
background-color: rgb(250, 250, 250);
border: none !important;
}

.ngx-table-context-key--favorite {
background-color: rgb(255, 247, 199);

> * {
padding: 3px 10px !important;
border: $fav-border !important;
border-bottom: none !important;
font-style: italic;
font-size: 0.8em;

&::before {
content: '★';
color: darkgoldenrod;
margin-right: 5px;
}
}

+ .ngx-table-row {
.ngx-table-row-cell {
border-bottom: $fav-border !important;

&:first-child {
border-left: $fav-border !important;
}

&:last-child {
border-right: $fav-border !important;
}
}

&:has(+ .ngx-table-detail-row-open) {
.ngx-table-row-cell {
border-bottom: none !important;
}
}

+ .ngx-table-detail-row-open {
.ngx-table-detail-cell {
border-left: $fav-border !important;
border-right: $fav-border !important;
border-bottom: $fav-border !important;
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { CommonModule } from '@angular/common';
import { Component } from '@angular/core';
import { NgxTable } from '@ngx/table';

@Component({
imports: [CommonModule, NgxTable],
selector: 'context-row-three-demo',
templateUrl: './context-row-three.demo.component.html',
styleUrl: './context-row-three.demo.component.scss',
})
export class ContextRowThreeDemoComponent {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<ngx-table
[data]="[
{ name: 'World', firstName: 'Hello', active: true },
{ name: 'Tools', firstName: 'NGX', active: false },
]"
[columns]="['name', 'firstName']"
[contextRowKeys]="['name', 'active']"
>
<ng-template #contextRowTmpl let-row>
{{ row | json }}
</ng-template>
</ngx-table>
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { CommonModule } from '@angular/common';
import { Component } from '@angular/core';
import { NgxTable } from '@ngx/table';

@Component({
imports: [CommonModule, NgxTable],
selector: 'context-row-two-demo',
templateUrl: './context-row-two.demo.component.html',
})
export class ContextRowTwoDemoComponent {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export * from './context-row-one/context-row-one.demo.component';
export * from './context-row-two/context-row-two.demo.component';
export * from './context-row-three/context-row-three.demo.component';
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
---
keyword: ContextRowPage
---

`ngx-table` provides a built-in way to add context rows to your table rows. This can be done by providing the `#contextRowTmpl` template as a `ContentChild` of the `NgxTable`.

## Example use case

Since the use of this component is not easily described, below is an example of when a context row could be useful. Let's say you want to visualize if and when a certain data entry has been favorited, the context row can be useful.
_Continue reading below for the (property) explanation._

{{ NgDocActions.demo("ContextRowThreeDemoComponent") }}

## Explanation

> **Note:** It is very important to be aware that this row does as its name suggests: it allows for additional context. It should not be used to add or define data of the row itself. This context row always has the `role="none"` aria tag. This means any and all content defined in this row gets excluded from the accessibility tree. Elements that are defined within this row that have a tabindex greater than or equal to 0 (and are therefor focusable) _are_ included in the accessibility tree. This means that you may include buttons and links inside this row. For more information and what not to define in this context row, please visit the official ARIA docs: https://w3c.github.io/aria/#none.

Once a context row is provided, the row does not automatically become visible. We need to use an Input to handle the behavior of the table. By defining the `contextRowKeys` input to a non-empty array, the attributes of the `data` are checked for a possible match. If at least one key of the data the row consists of matches a value of the `contextRowKeys`, that row will get a context row. If no key matches, the row will still get a context row, but the class will be `ngx-context-row`. This is the same way that detail views are rendered when they are not expanded.

From the moment that the `#contextRowTmpl` has been defined, every main row will get a corresponding context row. It is set to `display: none` as long as it is empty, and it shall remain empty as long as the above condition is not met. Be cautious of applying styles to the `ngx-context-row` class.

{{ NgDocActions.demo("ContextRowOneDemoComponent") }}

Be cautious of applying styles to the `ngx-context-row` class, since hidden context rows also have this class. You can modify how all visible context rows look by applying styles to the `ngx-table-context-row-open` class. In the above example, only one key was provided to the table via the `contextRowKeys`. This resulted in the row with the `active: true` to also be assigned the `ngx-table-context-key--active` modifier class.

In the example below, the `name` key of the data also gets taken into account. This results in more than one modifier to be applied to the context row that also has the `active` property set to `true`. The order in which the classes are applied to the element, is the same order in which the array values are provided to the `contextRowKeys` input.

Note the classes in the example below using the DevTools. The first row should get the following classes (aside from the by-Angular-injected classes):

1. `cdk-row`
1. `ngx-table-context-row`
1. `ngx-table-context-row-open`
1. `ngx-table-row-first`
1. `ngx-table-context-key--name`
1. `ngx-table-context-key--active`

{{ NgDocActions.demo("ContextRowTwoDemoComponent") }}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { NgDocPage } from '@ng-doc/core';
import { TableImplementationCategory } from '../../../../../../categories/angular';
import {
ContextRowOneDemoComponent,
ContextRowTwoDemoComponent,
ContextRowThreeDemoComponent,
} from './demos';

const ContextRowPage: NgDocPage = {
title: `Context row`,
mdFile: './index.md',
category: TableImplementationCategory,
order: 1,
demos: { ContextRowOneDemoComponent, ContextRowTwoDemoComponent, ContextRowThreeDemoComponent },
};

export default ContextRowPage;
13 changes: 13 additions & 0 deletions apps/table-test/src/app/app.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
[selectable]="true"
[currentSorting]="currentSort"
[resetFormOnNewData]="false"
[contextRowKeys]="contextRowKeys"
(rowClicked)="rowEmitted($event)"
>
<ng-template #radioTmpl let-control let-row="row" let-index="index">
Expand All @@ -38,6 +39,16 @@
{{ index }}
</ng-template>
}
@if (showContext) {
<ng-template #contextRowTmpl let-row let-index="index">
The item below has
<code
>{{ row.active ? 'active' : ''
}}{{ row.someKey ? (row.active ? ' and someKey' : 'someKey') : '' }}</code
>
special class.
</ng-template>
}

<ngx-table-cell
column="firstName"
Expand Down Expand Up @@ -70,5 +81,7 @@
</app-wrapper>

<button (click)="setFormValue()">Set form value</button>
<button (click)="toggleContextView()">Toggle context row</button>
<button (click)="toggleDetailView()">Toggle detail row</button>
<button (click)="toggleDataSet()">Toggle dataset</button>
<button (click)="toggleContextKeysSet()">Toggle context set</button>
28 changes: 27 additions & 1 deletion apps/table-test/src/app/app.component.scss
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,26 @@
color: darkred;
}
}
code {
background-color: #f0f0f0;
padding: 2px 5px;
border-radius: 3px;
font-family: monospace;
}

::ng-deep {
.ngx-table-row-selected {
outline: 2px dashed red;
}

.ngx-table-context-row {
padding: 3px !important;
font-size: 0.9em;
font-style: italic;
}

.ngx-table-row-first {
background-color: lightblue;
color: rgb(60, 164, 58);

> :first-child {
border-top-left-radius: 10px;
Expand All @@ -35,4 +47,18 @@
border-bottom-right-radius: 10px;
}
}

.ngx-table-context-key {
&--active,
&--active + .ngx-table-row,
&--active + .ngx-table-row + .ngx-table-detail-row {
background-color: rgb(241, 241, 193);
}

&--someKey,
&--someKey + .ngx-table-row,
&--someKey + .ngx-table-row + .ngx-table-detail-row {
background-color: rgb(206, 250, 206);
}
}
}
16 changes: 16 additions & 0 deletions apps/table-test/src/app/app.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export class AppComponent {
hello: 'world',
amount: 37,
date: '12/02/2023',
someKey: true,
},
{
name: 'Hyperdrive',
Expand All @@ -40,6 +41,7 @@ export class AppComponent {
hello: 'world',
amount: 5000,
date: '12/02/2023',
someKey: false,
},
{
name: 'Hyperdrive',
Expand All @@ -49,6 +51,7 @@ export class AppComponent {
hello: 'world',
amount: 5000,
date: '12/02/2023',
someKey: true,
},
];

Expand All @@ -61,15 +64,20 @@ export class AppComponent {
hello: 'world',
amount: 0.5,
date: '12/02/2023',
someKey: false,
},
];

public data = new BehaviorSubject(this.dataSet1);

public readonly columns = ['firstName', 'name', 'date', 'button', 'amount', 'active'];

public contextRowKeys = undefined;

public showDetail = true;

public showContext = true;

public form = new FormControl();

public isWrapperShown = true;
Expand All @@ -84,6 +92,10 @@ export class AppComponent {
this.showDetail = !this.showDetail;
}

public toggleContextView() {
this.showContext = !this.showContext;
}

public toggleDataSet() {
this.loading = true;

Expand All @@ -101,4 +113,8 @@ export class AppComponent {
public sort(event: NgxTableSortEvent) {
this.currentSort = event;
}

public toggleContextKeysSet(): void {
this.contextRowKeys = this.contextRowKeys ? null : ['someKey', 'active'];
}
}
5 changes: 3 additions & 2 deletions apps/table-test/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,19 @@ import { importProvidersFrom } from '@angular/core';
import { ReactiveFormsModule } from '@angular/forms';
import { BrowserModule, bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app/app.component';
import { NgxTableConfigToken } from '@ngx/table';
import { NgxTableConfig, NgxTableConfigToken } from '@ngx/table';

bootstrapApplication(AppComponent, {
providers: [
importProvidersFrom(BrowserModule, ReactiveFormsModule),
{
provide: NgxTableConfigToken,
useValue: {
useValue: <NgxTableConfig>{
showDetailRow: 'on-single-item',
showOpenRowState: true,
emitValueOnSingleItem: true,
hideHeaderWhen: ['when-loading'],
contextRowKeys: ['active'],
},
},
],
Expand Down
Loading