Table details with angular and multiple components - javascript

I've got a table. Once I click on a row, I load some more details about that row. Also, on-click the table disappears and instead a new div appears with the details. I made it correctly using one component but now I want to separate everything in more components. One for the table and one for the details. I don't want to call the service again on click, so i can just pass the params i need from a component to another on click. This is what I tried so far:
The table:
<table *ngIf="loading == false && openDetail == false">
<thead>
<th>
Name
</th>
<th>
Birth Year
</th>
<th>
Actions
</th>
</thead>
<tbody>
<tr *ngFor="let item of list let i = index" [attr.data-index]="i" (openHeroDetailFromAbout) = "openDetailsFunction($event)">
<!-- <tr *ngFor="let item of list let i = index" [attr.data-index]="i" (click) = "openHeroDetail(item)"> -->
<td>
<mat-form-field class="example-full-width" *ngIf="item.edit == true">
<input matInput placeholder="Name" [(ngModel)]="item.name">
</mat-form-field>
<span *ngIf="item.edit == false || item.edit == undefined">
{{item.name}}
</span>
</td>
<td>
<mat-form-field class="example-full-width" *ngIf="item.edit == true">
<input matInput placeholder="Year" [(ngModel)]="item.birth_year">
</mat-form-field>
<span *ngIf="item.edit == false || item.edit == undefined">
{{item.birth_year}}
</span>
</td>
<td style="width: 160px">
<div class="row">
<div class="col-md-6">
<button type="button" class="mdc-icon-button material-icons" click-stop-propagation (click) = "confirmHero(item, $event)" *ngIf="item.edit == true">
<mat-icon>check</mat-icon>
</button>
<button type="button" class="mdc-icon-button material-icons" click-stop-propagation (click) = "editHero(item, $event)" *ngIf="item.edit == false || item.edit == undefined">
<mat-icon>edit</mat-icon>
</button>
</div>
<div class="col-md-6">
<button type="button" class="mdc-icon-button material-icons" click-stop-propagation (click) = "deleteHero(i, item, $event)">
<mat-icon>delete</mat-icon>
</button>
</div>
</div>
</td>
</tr>
</tbody>
</table>
and then below the table
<div *ngIf="openDetail == true">
<app-hero-detail></app-hero-detail>
</div>
The first component with openHeroDetailFromAbout is called TableComponent and in there i have this:
openHeroDetailFromAbout(item: any): void {
item.openDetail = true;
console.log(item);
}
the second component is called HeroDetailComponent :
import { Component, OnInit, EventEmitter, Input, Output } from '#angular/core';
#Component({
selector: 'app-hero-detail',
templateUrl: './hero-detail.component.html',
styleUrls: ['./hero-detail.component.scss']
})
export class HeroDetailComponent implements OnInit {
#Input() heroName: string; // hero's name
#Output() openDetails = new EventEmitter<any>();
constructor() { }
ngOnInit() {
}
openDetailsFunction(item: any): void {
this.openDetails.emit(item);
this.heroName = item.name;
console.log(item);
}
}
But nothing fires on click on the row. I just pass item object from component to the other and in the detail component show that information. Also the console.log() not work

Related

angular MatTableDataSource filterPredicate does not update the table after filter updates

import { Component, OnInit, AfterViewInit } from '#angular/core';
import { Coach } from "../../shared/models/User";
import { ManagementService } from "../../shared/services/management.service";
import { Router } from '#angular/router';
import { UtilsService } from 'src/app/shared/services/utils.service';
import * as moment from 'moment';
import swal from 'sweetalert2';
import { FormControl } from '#angular/forms';
import { MatTableDataSource } from '#angular/material/table';
#Component({
selector: 'app-coaches',
templateUrl: './coaches.component.html',
styleUrls: ['./coaches.component.css']
})
export class CoachesComponent implements OnInit, AfterViewInit {
dataSource;
columnsToDisplay = ['username', 'email', 'actions'];
coachList: Array<Coach> = [];
username
usernameFilter = new FormControl('');
constructor(
private managementService: ManagementService,
private router: Router,
private utils: UtilsService
) {
this.dataSource = new MatTableDataSource();
this.dataSource.filterPredicate = this.createFilter();
}
async ngAfterViewInit() {
// await this.initializePage();
}
ngOnInit() {
this.initializePage();
this.usernameFilter.valueChanges
.subscribe(
username => {
this.username = username;
this.dataSource.filter = this.username;
console.log(this.dataSource.filter)
}
)
}
createFilter(): (data: Coach, filter: string) => boolean {
let filterFunction = function (data, filter): boolean {
return data.username.toLowerCase().indexOf(filter.toLowerCase()) !== -1
}
return filterFunction;
}
async initializePage() {
let coaches: Array<Coach> = await this.managementService.getCoaches();
this.coachList = coaches.sort(
(prev, next) => {
return moment(prev.createdAt).isBefore(moment(next.createdAt)) ? 1 : -1;
}
);
this.dataSource = this.coachList
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>
<div class="main-content zero_margin">
<div class="container-fluid">
<div class="row">
<div class="col-md-12">
<div class="card">
<div class="card-header card-header-primary card-header-icon">
<div class="card-icon">
<i class="material-icons">account_circle</i>
</div>
<h4 class="card-title">Coaches</h4>
</div>
<div class="card-body">
<div class="toolbar">
<button mat-raised-button class="btn btn-primary" (click)="registerCoach()">Register</button>
<div class="col-lg-3 col-md-6 col-sm-4 add-select" style="float: right;">
<mat-form-field appearance="standard">
<mat-label>Filter</mat-label>
<input matInput [formControl]="usernameFilter" placeholder="username" #input>
</mat-form-field>
</div>
</div>
<div style="text-align: center" *ngIf="coachList.length === 0">
<br>
<div style="font-style: italic; color: gray">.:: No Registered Coaches ::.</div>
</div>
<table mat-table [dataSource]="dataSource" class="table table-striped table-no-bordered table-hover"
cellspacing="0" width="100%" style="width:100%">
<ng-container matColumnDef="username">
<th mat-header-cell *matHeaderCellDef> Username </th>
<td mat-cell *matCellDef="let row"> {{row.username}} </td>
</ng-container>
<ng-container matColumnDef="email">
<th mat-header-cell *matHeaderCellDef> Email </th>
<td mat-cell *matCellDef="let row"> {{row.email}} </td>
</ng-container>
<ng-container matColumnDef="actions">
<th mat-header-cell *matHeaderCellDef> Actions </th>
<td mat-cell *matCellDef="let row">
<app-button-delete (onClick)="deleteCoach(coach.id)"></app-button-delete>
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="columnsToDisplay"></tr>
<tr mat-row *matRowDef="let row; columns: columnsToDisplay;"></tr>
</table>
<mat-paginator showFirstLastButtons [pageSizeOptions]="[10, 25, 50, 100]"></mat-paginator>
</div>
</div>
</div>
</div>
</div>
</div>
I am very new to Angular and I am working on a project previously owned by other people.
The question goes as the title, I have done a lot of search around but none of the answers from stackoverflow works for me so far.
Below are the code, let me know if you need other information.
in a word, for some reason the filter function does not update the table content, which is confusing because it seems that the filter function works from another component, with essentially the same code.
This really confused me. Thank you in advance for any help and suggestion!!!
You need to assign coachList as data of the dataSource.
// replace this line
this.dataSource = this.coachList
// with this
this.dataSource.data = this.coachList
when you create the dataSourse as an instance of MatTableDataSource the data array that is displayed is stored in the data property of the data source object, you can read more about MatTableDataSource here

Angular Making Inputs HyperLinks

In my code, I have an input field where the user can enter some stuff. When the user enters his input and presses done, I want that input to be a hyperlink. Here is my code. What should I add to make that input a link?
HTML:
<ng-container matColumnDef="FilePath" #filePath>
<th mat-header-cell *matHeaderCellDef> Dosya Yolu </th>
<td mat-cell *matCellDef="let row; let i = index">
<span *ngIf="EditIndex != i">{{row.LabAnalysisFiles.FilePath}}</span>
<mat-form-field floatLabel="never" *ngIf="EditIndex == i" class="w-100-p">
<input matInput name="FilePath" [(ngModel)]="row.LabAnalysisFiles.FilePath" type="text">
</mat-form-field>
</td>
</ng-container>
<ng-container matColumnDef="Actions">
<th mat-header-cell *matHeaderCellDef></th>
<td mat-cell *matCellDef="let row; let i = index">
<div *ngIf="!isClosed">
<button mat-icon-button *ngIf="EditIndex != i" (click)="editRow(row, i)">
<mat-icon>edit</mat-icon>
</button>
<button mat-icon-button *ngIf="EditIndex == i"
(click)="editRow(row, undefined)">
<mat-icon>done</mat-icon>
</button>
</div>
</td>
</ng-container>
TS:
testList: ILabConditionResult[] = [];
filePath: ILabAnalysisFile;
editRow(row: ILabConditionResult, index: number) {
if (index == undefined) {
if (
!row.LabAnalysisFiles.FilePath
) {
return;
}
this.testList = [];
} else {
this.testList = [];
}
this.EditIndex = index;
}
For a text to appear like a hyperlink, you have to use the a tag with a href attribute.
Hence, in your code, you have to change
<span *ngIf="EditIndex != i">{{row.LabAnalysisFiles.FilePath}}</span>
to
<a href *ngIf="EditIndex != i">{{row.LabAnalysisFiles.FilePath}}</a>
Keep in mind that if you click the link it will navigate, so if this behavior is not desired you should add:
(click)="$event.preventDefault()"

How can I create a custom pipe for table row?

I want to create a custom pipe to render the rows in a table which contains a particular data.
If you follow the image -
By clicking starting point I button it will only show the row with starting point value - 'one' same for starting point II & III.
Can anyone please help me to write the custom pipe?
Table image
src\app\book-ride\book-ride.component.html
<div style="position: relative">
<div class="btn-group mr-2" role="group" aria-label="First group">
<button type="button" class="btn btn-secondary" (click)="onClick()">Show all rides</button>
</div>
<div *ngIf = "showButton"class="btn-group mr-2" role="group" aria-label="Third group">
<button type="button" class="btn btn-secondary">Start Point I</button>
</div>
<div *ngIf = "showButton" class="btn-group mr-2" role="group" aria-label="Fourth group">
<button type="button" class="btn btn-secondary">Start Point II</button>
</div>
<div *ngIf = "showButton" class="btn-group mr-2" role="group" aria-label="Fifth group">
<button type="button" class="btn btn-secondary">Start Point III</button>
</div>
<div style="position: relative" *ngIf="clicked">
<table mat-table [dataSource]="data" class="mat-elevation-z8">
<ng-container matColumnDef="Start_Point">
<th mat-header-cell *matHeaderCellDef> Start point </th>
<td mat-cell *matCellDef="let data"> {{data}} </td>
</ng-container>
<ng-container matColumnDef="End_Point" appMouseHover>
<th mat-header-cell *matHeaderCellDef>End point</th>
<td mat-cell *matCellDef="let index = index"> {{index}} </td>
</ng-container>
<ng-container matColumnDef="Seats_available" appMouseHover>
<th mat-header-cell *matHeaderCellDef> Seats available</th>
<td mat-cell *matCellDef="let count = count"> {{count}} </td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr appMouseHover mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>
</div>
<div class="btn-group mr-2" role="group" aria-label="Second group">
<button type="button" class="btn btn-secondary">Offer a ride</button>
</div>
</div>
src\app\book-ride\book-ride.component.ts
import { Component, OnInit } from '#angular/core';
#Component({
selector: 'app-book-ride',
templateUrl: './book-ride.component.html',
styleUrls: ['./book-ride.component.css']
})
export class BookRideComponent implements OnInit {
clicked: Boolean = false;
showButton: Boolean = false;
constructor() { }
displayedColumns: string[] = ['Start_Point', 'End_Point', 'Seats_available'];
data: string[] = ['one', 'two', 'three'];
ngOnInit(): void {
}
onClick(){
this.clicked = ! this.clicked;
this.showButton = ! this.showButton
}
}
I tried creating this pipe but was not working
src\app\start-pipe.pipe.ts
import { Pipe, PipeTransform } from '#angular/core';
import { BookRideComponent } from './book-ride/book-ride.component';
import { Users } from './login/users';
#Pipe({
name: 'startPipe'
})
export class StartPipePipe implements PipeTransform {
bookRideComponent: BookRideComponent = new BookRideComponent;
user: Users = new Users;
transform(value: unknown, arg : String): unknown {
console.log("inside pipe: "+arg);
if (arg == "one"){
this.user.click2 = false;
this.user.click3 = false;
}
else if(arg == "two"){
this.user.click1 = false;
this.user.click3 = false;
}
else if(arg == "three"){
this.user.click1 = false;
this.user.click2 = false;
}
else
this.user.click1 = true;
this.user.click2 = true;
this.user.click3 = true;
return null;
}
}

How to show/hide instead toggle icon?

I need to show/hide icon instead to right now toggle icon.
Code:
<td *ngIf="isActive !== i" (click)="clickerTrue(set, i)">
<img src="https://img.icons8.com/office/30/000000/plus.png"/>
</td>
<td *ngIf="isActive === i">
<input type="text" [(ngModel)]="set.note" name="value" class="form-control" />
</td>
i is index from ngFor
clickerTrue(set, index) {
this.isActive = this.isActive === index ? null : index;
}
isActive variable first value is false.
If you are using ngFor, why you pass the object?
<button *ngFor="let item of items" (click)="toggleActive(item)">click me</button>
toggleActive(item) {
item.active = !item.active;
}
it is work in *ngFor
<td *ngIf="isActive != set" (click)="clickerTrue(set, i)">
<img src="https://img.icons8.com/office/30/000000/plus.png"/>
</td>
<td *ngIf="isActive == set">
<input type="text" [(ngModel)]="set.note" name="value" class="form-control" />
</td>
public isActive: any;
clickerTrue (set: any, index: number) {
this.isActive = set;
}

How to delete a particular row from table by clicking button Angular 2

I am trying to delete a particular row by clicking button from that row which is in for loop,but its deleting all the rows of that table.
Here is my Html code:
<table id="mytable" class="table table-bordred table-striped">
<tbody id="del">
<tr *ngFor="let cart of modalData">
<td>
<div style="display:inline-flex;">
<div style="margin-left:10px;">
<p class="font_weight" style="font-size:13px;">{{cart.ExamName}}</p>
<p>{{cart.Categoryname}}|{{cart.CompanyName}}</p>
</div>
</div>
</td>
<td>
<div style="margin-top: 32px;">
<p class="font_weight" style="font-size:13px;"></p> <span class="font_weight" style="font-size: 13px;"> {{cart.Amount| currency :'USD':'true'}} </span> </div>
</td>
<td>
<div style="margin-top: 19px;">
<button class="button_transparent" (click)="Delete(cart)"> delete </button>
</div>
</td>
</tr>
<tr> </tr>
</tbody>
</table>
Here is my Component:
public loadData() {
let transaction = new TransactionalInformation();
this.myCartService.GetExamOrderForCart()
.subscribe(response => this.getDataOnSuccess(response),
response => this.getDataOnError(response));
}
getDataOnSuccess(response) {
this.modalData = response.Items;
}
This is my delete method:
public Delete(response) {
this.myCartService.updateExamOrder(response)
.subscribe(response => this.getDataOnSuccessForDelete(response),
response => this.getDataOnErrorForDelete(response));
}
Please help me to do, How to delete only one row from table?
You can add index in *ngFor :
<tr *ngFor="let cart of modalData;let i = index">
Then, pass the index in the method:
<button class="button_transparent" (click)="delete(i)"> delete </button>
And finally:
delete(i){
this.modalData.splice(i,1);
}
you can do this:
<button class="button_transparent" (click)="delete(cart)"> delete </button>
then
delete(item){
this. modalData = this. modalData.filter(item => item.id !== id);
this.modalData.push();}
here you are creating a new list without the element that you want to delete.

Categories

Resources