conditional css (dynamic) bason on json - javascript

The table <div class="cellSubText secondary-text {{cssSubCell}}" >{{cellData[subId]}}</div> from my table-multi-sort-cell-default.component.html using the cssClass from the tableOptions which is the cssSubCell: 'c-black fs-14px'
How we construct a conditional css based on my tableOptions cssSubCell
for example cssSubCell: 'c-black fs-14px' should only work if subId !== 'test'
I tried below, but the condition does not work or recognized , is my CSS condition structure and implementation correct?
cssSubCell: 'c-black fs-14px : subId !== "test"
#this CSS works but I want it to be condition
cssSubCell: 'c-black fs-14px'
#component A tableOptions
this.tableOptions = {
columns:[
{id:'name',name:'Deal Letter',subId:'dealType', subtitle:'Deal Type'},
{id:'annualRentCurrent',name:'Annual Rent (Current)', subId: 'annualRentProposed', subtitle:'Annual Rent (Proposed)'},
{id:'firmTermRemainingCurrent',name:'Firm Term Remaining (Current)', subId: 'proposedTerm', subtitle:'Firm Term Remaining(Proposed)'},
{id:'maxAvailableTerm',name:'Max Available Term (Current)' , subId:'proposedMaxAvailableTerm', subtitle: 'Max Available Term (Proposed)'},
{id:'cashContribution',name:'Cash Contribution'},
{id:'cashFlow',name:'Store Cash Flow'},
{id:'action', name: 'Actions', actions:[
{icon:'file_copy', name:'Copy', class:'primary-color' , },
{icon:'delete', name: 'Delete', class:'mat-error ml-7px'},
{icon:'forward', name: 'For Approval', class:'primary-color'}
]}
],
cssClass: {
cssCell:'',
cssSubCell: 'c-black fs-14px'
}
}
#table screenshot
enter image description here
#table-multi-sort-cell-default.component.html
<div class="{{cssCell}}">{{cellData[id]}}</div>
<div class="cellSubText secondary-text {{cssSubCell}}" >{{cellData[subId]}}</div>
#table-multi-sort.component.html
<ng-container *ngFor="let column of table.columns" [matColumnDef]="column.id">
<mat-header-cell class="table-multi-sort-header" *matHeaderCellDef [mat-multi-sort-header]="column.id">
<div>{{column.name}}</div>
<div class="sub-text">{{getColumnSubtitle(column.id)}}</div>
</mat-header-cell>
<mat-cell *matCellDef="let row" (click)="editRow(row)">
<ng-container *ngIf="column.id !== 'action'; then col; else actionCol"></ng-container>
<ng-template #col>
<app-table-multi-sort-cell-default [cellData]="row" [id]="column.id" [subId]="getColumnSubId(column.id)" [cssCell]="cssClass.cssCell" [cssSubCell]="cssClass.cssSubCell" ></app-table-multi-sort-cell-default>
</ng-template>
<ng-template #actionCol>
<app-table-multi-sort-cell-action [rowData]="row" [actions]="getActions(column.id)" (actionClickEvent)="clickTableAction($event,row)"></app-table-multi-sort-cell-action>
</ng-template>
</mat-cell>
</ng-container>

You need to use ngClass
<div class="cellSubText secondary-text" [ngClass]="{'c-black fs-14px' : subId !=='dealType'}">
{{cellData[subId]}}
</div>

Related

Data binding issue in MatTableDataSource with Array of Objects in Angular

As i am trying to bind the array of objects data to a MatTableDataSource but the table shows with empty results. I guess its a minor issue with data binding. I have written the code as below.
endPointsDataSource;
endPointsLength;
endPointsPage = 0;
endPointsPageSize = 50;
allProjectsEndpointsList = [];
populateCoverage(objList) {
let tObj = { resourceName: '', endpoints: [] }
let cont = 1;
let lastName = ''
try {
lastName = objList[0][4];
} catch (e) { }
tObj.resourceName = lastName;
let resourceDefinitionList = [];
objList.forEach(function (item) {
let obj = { "projectName": item[6], "method": item[1], "endpoint": item[0], "description": item[3], "summary": item[4], "isManual": item[5] };
if (lastName == item[4]) tObj.endpoints.push(obj);
else if (lastName != item[4]) {
resourceDefinitionList.push(tObj);
tObj = { resourceName: item[4], endpoints: [obj] }; lastName = item[4]
}
});
var arr: any = []
arr = tObj;
resourceDefinitionList.push(arr)
return resourceDefinitionList;
}
showAllProjectsEndpoints() {
this.resource.getAllProjectsEndpoints().subscribe((results) => {
this.handler.hideLoader();
if (this.handler.handle(results)) {
return;
}
this.allProjectsEndpointsList = this.populateCoverage(results['data']);
this.endPointsDataSource = new MatTableDataSource(this.allProjectsEndpointsList);
}, (error) => {
this.handler.hideLoader();
this.handler.error(error);
});
}
The html template code as follows:
<div class="mat-elevation-z8 ">
<mat-table [dataSource]="endPointsDataSource">
<!-- projectName Column -->
<ng-container matColumnDef="projectName">
<mat-header-cell *matHeaderCellDef>Name
<mat-cell *matCellDef="let element">
{{element.projectName}}</mat-cell>
</mat-header-cell>
</ng-container>
<!-- method Endpoint Column -->
<ng-container matColumnDef="method">
<mat-header-cell *matHeaderCellDef>Endpoint
<mat-cell *matCellDef="let element">{{element.method}}</mat-cell>
</mat-header-cell>
</ng-container>
<!-- endpoint Column -->
<ng-container matColumnDef="endpoint">
<mat-header-cell *matHeaderCellDef>Endpoint
<mat-cell *matCellDef="let element">{{element.endpoint}}</mat-cell>
</mat-header-cell>
</ng-container>
<!-- description Column -->
<ng-container matColumnDef="description">
<mat-header-cell *matHeaderCellDef>Description
<mat-cell *matCellDef="let element">{{element.description}}</mat-cell>
</mat-header-cell>
</ng-container>
<mat-header-row *matHeaderRowDef="endPointsColumns"></mat-header-row>
<mat-row *matRowDef="let row; columns: endPointsColumns;"></mat-row>
</mat-table>
<mat-paginator [hidden]="vulnerabilityLength == 0" matColumnDef="position"
[pageSizeOptions]="pageSizeOptions" [pageSize]="vulnerabilityPageSize"
[pageIndex]="vulnerabilityPage" (page)="changeVul($event)" [length]="vulnerabilityLength">
</mat-paginator>
</div>
Can anyone correct me what mistake i have made?
I am getting the empty table as below:
I am getting the data as below:
You need check your function populateCoverage. See that each element of your allProjectsEndpointsListarray are in the way
{resourceName:...,endpoints:[...]}
So you need write some
{{elements.endpoints[0].description}}
TIP: Sometimes is util write in a td
{{element|json}}
To see the way of the element -obviously, the table crash-

Validate the input text user-entry inside table in angular 5

html file
<mat-table #table [dataSource]="CMDataSource">
<ng-container matColumnDef="mQues">
<mat-header-cell *matHeaderCellDef> Ticket Volume </mat-header-cell>
<mat-cell *matCellDef="let element"> <label> {{element.mQues}} </label> </mat-cell>
</ng-container>
<ng-container matColumnDef="metricUnit">
<mat-header-cell *matHeaderCellDef></mat-header-cell>
<mat-cell *matCellDef="let element">
<mat-form-field>
<input type="number" matInput (change)="userMCState(element.mQuesId, $event.target.value)">
</mat-form-field>
</mat-cell>
</ng-container>
<mat-header-row *matHeaderRowDef="displayedColumnsHeaderName"></mat-header-row>
<mat-row *matRowDef="let row; columns: displayedColumnsHeaderName;">
</mat-row>
</mat-table>
<button mat-raised-button (click)='submitMA()'> SUBMIT </button>
component file
const CM_DATA: MetricsAssess[] = [
{ mQuesId: 1, mQues: 'English', metricUnit: 'hour' },
{ mQuesId: 2, mQues: 'French', metricUnit: 'hour' },
{ mQuesId: 3, mQues: 'Spanish', metricUnit: 'hour' },
{ mQuesId: 4, mQues: 'German', metricUnit: 'hour' }
];
CMDataSource = new MatTableDataSource(CM_DATA);
userMCState(questionNum, statusValue): void {
this.mArray.push({ "quesNum": questionNum, "userAns": statusValue});
}
submitMA(): void {
**//VALIDATE THE USER INPUT & if the ENTRY is BLANK, request the user to make entry**
let pMDataJSON = {
mAssessJSONArray: this.mArray
};
}
Here, is a set of questions displayed from table & also input text boxes.
Need to validate the User entry is NUMBER and also, if no entry is made then, request dialog box to make entry.
Kindly help me.
Please fallow thiese below steps.
remove change event because it triggers in every value changes.
try and use with ngModel
<input type="number" matInput [(ngModel)]= "element.statusValue">
do your validation in submitMA() by using loop, like below way
submitMA(): void {
let isError=false;
for(const obj of this.mArray)
{
if(!obj.statusValue || !Number.isInteger(obj.statusValue))
{
isError=true;
alert(some error occurred)
break;
}
if(isError)
{
return false
}
}
// .. possitive scenario codes
}
Note: your model class should have statusValue property.

Dots in bracket to access nested property

Consider the object below:
var item = {
id: 'some-id',
price: 12,
customer: {
id: 'fake-id',
name: 'fake-name'
}
};
We can access the customer name using "dots" or "brackets" as below:
item.customer.name
item['customer'].name
item.customer['name']
item.['customer']['name']
Question
In Javascript or Typescript, is there a way to access customer name like the following?
item['customer.name'] or item[customer.name]
Notes
In angular I created a reusable table component based on the mat-table, which includes pagination, sort filter and bunch of other functions... I use the following for the column definitions:
mytable.component.ts:
export interface MyTableCol {
id: string;
title: string;
// some other settings...
}
mypage.component.ts:
cols: MyTableCol[] = [
{id: 'price', title: 'Total Price'},
{id: 'customer.name', title: 'Customer Name' }
];
mypage.component.html:
<my-table [columns]="cols"></my-table>
mytable.component.html:
<ng-container [matColumnDef]="col.id" *ngFor="let col of columns">
<th mat-header-cell *matHeaderCellDef mat-sort-header>
{{ col.title}}
</th>
<td mat-cell *matCellDef="let element">
{{ element[col.id] }}
</td>
</ng-container>
However, for the nested properties (customer.name) this won't work. I think the reason is the line: element[col.id] converts to element['customer.id'] in case of the customer name column.
How can I resolve this?
It won't work automatically to pass a string like that to access the properties, you need to create a getter function like lodash _get and use it to find the value you need. And then write something like:
{{ _getAtr(element, col.id) }}

How to dynamically bind angular material table with data from backend?

I am trying to bind mat-table with data from backend api based on this Angular Material Table Dynamic Columns without model. Here is the .ts file content
technologyList = [];
listTechnology = function () {
this.http.get("https://localhost:44370/api/admin").subscribe(
(result: any[]) => {
this.technologyList = result;
//creating table begins here
var displayedColumns = Object.keys(this.technologyList[0]);
var displayedRows = Object.entries(this.technologyList[0]);
this.dataSource = new MatTableDataSource(this.technologyList);
}
I am getting response from backend as technologyListwhich is
>
Array(2)
0: {id: 1, technologyName: "Python", description: "Python123", commission: "20", imageURL: "https://cutt.ly/gePgUvn", …}
1: {id: 2, technologyName: "Ruby", description: "Python123", commission: "30", imageURL: "https://cutt.ly/gePgUvn", …}
length: 2
I am trying to bind this with html using .html file as
>
<div>
<mat-table #table [dataSource]="dataSource" class="mat-elevation-z8">
<ng-container *ngFor="let disCol of displayedColumns; let colIndex = index" matColumnDef="{{disCol}}">
<mat-header-cell *matHeaderCellDef>{{disCol}}</mat-header-cell>
<mat-cell *matCellDef="let element "> {{element[disCol]}}
</mat-cell>
</ng-container>
<mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
<mat-row *matRowDef="let row; columns: displayedColumns;"></mat-row>
</mat-table>
</div>
The output is a blank white block. What am I doing wrong here? Any help would be much appreciated, thank you.
Response after the proposed change
output table
Try like this:
Working Demo
displayedColumns = [];
dataSource;
listTechnology = function () {
this.http.get("https://localhost:44370/api/admin").subscribe(
(result: any[]) => {
this.technologyList = result;
this.displayedColumns = Object.keys(this.technologyList[0]);
this.dataSource = new MatTableDataSource(this.technologyList);
})
}

Angular mat-sort not working on matColumnDef with dot notation

I am trying to sort a table by its columns.
The problem occurs when I have to filter a result that is inside another.
I tried to access the property by bracket notation and dot notation but none gave results.
Also placing the final node in matColumnDef but it fails because there are 2 columns with the same name.
<table mat-table [dataSource]="dataSource" matSort>
<!-- Element name Column -->
<ng-container matColumnDef="name">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Name </th>
<td mat-cell *matCellDef="let element"> {{element.name}} </td>
</ng-container>
<!-- Username Column -->
<ng-container matColumnDef="user.name">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Username </th>
<td mat-cell *matCellDef="let element"> {{element.user.name}} </td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>
displayedColumns definition:
displayedColumns = ['name', 'user.name'];
There is a dataSource example:
[
{
id: 2,
name: "Testing",
user: {
id: 1,
name: "User Testing",
username: "test#example.com"
}
},
{
id: 4,
name: "Testing_2",
user: {
id: 3,
name: "User Testing 2",
username: "test2#example.com"
}
}
]
It was hard to find documentation on this, but it is possible by customizing the sortingDataAccessor of MatTableDataSource and a switch statement.
For example:
#ViewChild(MatSort) sort: MatSort;
ngOnInit() {
this.dataSource = new MatTableDataSource(yourData);
this.dataSource.sortingDataAccessor = (item, property) => {
switch(property) {
case 'project.name': return item.project.name;
default: return item[property];
}
};
this.dataSource.sort = sort;
}
Found here: Angular Material 2 DataTable Sorting with nested objects

Categories

Resources