Sort content on page Angular - javascript

I have a component and table.
I get an object from the server and display it in the table. I want to add sort buttons that change the information displayed in the table by type.
This is my table-components:
<app-home-modal-button></app-home-modal-button>
<app-home-button></app-home-button>
<div class="searchBox">
<input type="text" class="searchBoarder"/>
<i class="fas fa-search"></i>
</div>
<div class="table-container">
<table class="table">
<thead>
<tr class="table-nav">
<th scope="col">שנה</th>
<th scope="col">סוג הדוח</th>
<th scope="col">ח.פ</th>
<th scope="col">שם החברה</th>
</tr>
</thead>
<tbody>
<ng-container *ngFor="let tax of currentPage">
<tr>
<td>{{tax.year}}</td>
<td>{{tax.type}}</td>
<td>{{tax.cid}}</td>
<td>{{tax.company}}</td>
</tr>
</ng-container>
</tbody>
</table>
<div class="table-footer">
<pagination class="pagination" nextText=">" previousText="<" [totalItems]="totalItems" (pageChanged)="pageChanged($event)"> </pagination>
</div>
</div>
components ts:
import { Component, OnInit } from '#angular/core';
import { CompanyService } from '../../../../core/services/company.service';
import { Tax } from 'src/app/entity/tax.entity'
#Component({
selector: 'app-taxreports',
templateUrl: './taxreports.component.html',
styleUrls: ['./taxreports.component.sass']
})
export class TaxreportsComponent implements OnInit {
constructor(private service: CompanyService) {
}
taxList: Tax[];
totalItems: Number;
currentPage: Tax[];
page: Number = 1;
ngOnInit() {
this.service.getTaxList().subscribe(data => {
this.taxList = data;
this.totalItems = data.length;
this.currentPage = data.slice(0, 10)
}, error => {
console.log(error);
})
}
pageChanged(event) {
const startItem = (event.page - 1) * event.itemsPerPage;
const endItem = event.page * event.itemsPerPage;
this.currentPage = this.taxList.slice(startItem, endItem);
}
}
The problem is that i dont want to sort All the length of the object.
I want the sorting done only on the information shown in the table, because the information is divided into several pages using pagination.

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

ERROR DOMException: Failed to execute 'setAttribute' on 'Element': '{{' is not a valid attribute name

Before the question, code is not completed yet so some methods are empty and *ngIf directives might be wrong (logic-wise, not syntax-wise). But even without them I got the same error so I didn't bother to remove them for now.
I'm following a angular course and expecting a screen like this when I click any of the edit buttons or create button:
Course-version
But after loading page without any errors, if I click any of the buttons (create or edit), I'm getting this error on the console and can't find why after a long try:
my-version
Similar problems I found on Stackoverflow mostly caused of simple syntax errors but I couldn't find any syntax issues with my code so far. Maybe someone will see the issue and correct me.
You can find all the codes below.
Here is my edit-task.component.html
<div *ngIf="task">
<h2 {{ task.taskName }}></h2>
<div>
Task ID:
<input [(ngModel)]="task.taskId" placeholder="Task ID"/>
</div>
<div>
Name:
<input [(ngModel)]="task.taskName" placeholder="Name"/>
</div>
<div>
Responsible ID:
<input [(ngModel)]="task.responsibleId" placeholder="Responsible ID"/>
</div>
<button (click)="updateTask(task)" *ngIf="task.taskId != null">Save</button>
<button (click)="deleteTask(task)" *ngIf="task.taskId != null">Delete</button>
<button (click)="createTask(task)" *ngIf="task.taskId == null">Create</button>
</div>
Here is app.component.html
<button (click)="initNewTask()">Create new task</button>
<table>
<thead>
<th>Task ID: </th>
<th>Task Name: </th>
<th>Resp ID: </th>
<th></th>
</thead>
<tbody>
<tr *ngFor="let task of tasks" >
<td>{{ task.taskId }}</td>
<td>{{ task.taskName }}</td>
<td>{{ task.responsibleId }}</td>
<td><button (click)="editTask(task)">Edit</button></td>
</tr>
</tbody>
</table>
<app-edit-task [task]="taskToEdit"></app-edit-task>
Here is edit-task.component.ts
import { Component, Input, OnInit } from '#angular/core';
import { Task } from 'src/app/models/task';
#Component({
selector: 'app-edit-task',
templateUrl: './edit-task.component.html',
styleUrls: ['./edit-task.component.css']
})
export class EditTaskComponent implements OnInit {
#Input() task?: Task;
constructor() { }
ngOnInit(): void {
}
updateTask(task:Task){
}
deleteTask(task:Task){
}
createTask(task:Task){
}
}
And here is app.component.ts
import { TaskService } from './services/task.service';
import { Task } from './models/task';
import { Component } from '#angular/core';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
tasks: Task[] = [];
taskToEdit?: Task;
constructor(private taskService: TaskService){}
ngOnInit() : void {
this.taskService
.getTasks()
.subscribe((result: Task[]) => (this.tasks = result));
}
initNewTask(){
this.taskToEdit = new Task();
}
editTask(task: Task){
this.taskToEdit = task;
}
}
Comes from
<h2 {{ task.taskName }}>
In edit-task.component.html
I don't know exactly what you tried to do but that can't work

capturing form inputs with Angular 8 reactive forms

I want to get my forms to work how I have them set up. I needed multiple forms to have a update and delete option on every product item. The problem that I am having is that as soon as I add the [formGroup]="profileForm" directive in my form the form Controls stop working. I had trouble getting the reactive form to work because each of my forms are in a table row.
I unfortunately have the data on a local server so the code won't look like the picture displayed but here is the stack-blitz if you want a closer look at my code: https://stackblitz.com/github/RashellSmith/Dashboard-FrontEnd
update product ts
import { Component, OnInit } from '#angular/core';
import { Product } from '../model/Product';
import { Category } from '../model/Availability';
import { Supplier } from '../model/Supplier';
import { Home } from '../model/Home';
import { HomeService } from '../service/Home.service';
import { SupplierService } from '../service/Supplier.service';
import { CategoryService } from '../service/Category.service';
import { FormGroup, FormControl } from '#angular/forms'
#Component({
selector: 'app-update-product',
templateUrl: './update-product.component.html',
styleUrls: ['./update-product.component.scss']
})
export class UpdateProductComponent implements OnInit {
availability:boolean;
category:number;
orderBy: String;
Ascdesc: String;
page = 0;
home: Home[];
categories: Category[];
supplier: Supplier[];
selectedCategory: Category;
edit: boolean = false;
public currentProduct: number;
toogleEditMode() {
this.edit = this.edit ? false : true;
}
selectCategory (category) {
this.category = category.category;
}
available(boolean){
this.availability = boolean;
}
update($event){
this.homeService.getByParm(this.availability,this.category).subscribe(data => {
this.home = data;
});
}
profileForm = new FormGroup({
id: new FormControl(''),
name: new FormControl(''),
category: new FormControl(''),
fullPrice: new FormControl(''),
salePrice: new FormControl(''),
availability: new FormControl(''),
supplier: new FormControl(''),
discount: new FormControl(''),
});
// model = {id: null, productName: '', category: {category: null, categoryName: null}, fullPrice: '', salePrice:'', availability: false, supplier: {supplier:null,supplierName:""},discount:null};
// json = JSON.stringify(this.model);
constructor(private homeService: HomeService,private supplierService: SupplierService,private categoryService: CategoryService) { }
name = new FormControl('');
SortPrice($event:any){
let icon = document.getElementById("asc-desc1");
if(icon.className === "fas fa-angle-down"){
icon.className ="fas fa-angle-up";
this.homeService.getByPriceAsc().subscribe(data => {
this.home = data;
});
}else{
icon.className ="fas fa-angle-down"
this.homeService.getByPriceDesc().subscribe(data => {
this.home = data;
});
};
}
// model = new Newproduct(null,new Category( this.value,"name"),null,null,false,new Supplier(null,null),null);
onSubmit() {
// TODO: Use EventEmitter with form value
// console.warn(this.profileForm.value);
}
SortSale($event:any){
let icon = document.getElementById("asc-desc2");
if(icon.className === "fas fa-angle-down"){
icon.className ="fas fa-angle-up";
this.homeService.getBySaleAsc().subscribe(data => {
this.home = data;
});
}else{
icon.className ="fas fa-angle-down"
this.homeService.getBySaleDesc().subscribe(data => {
this.home = data;
});
};
}
SortDiscount($event:any){
let icon = document.getElementById("asc-desc3");
if(icon.className === "fas fa-angle-down"){
icon.className ="fas fa-angle-up";
this.homeService.getByDiscountAsc().subscribe(data => {
this.home = data;
});
}else{
icon.className ="fas fa-angle-down"
this.homeService.getByDiscountDesc().subscribe(data => {
this.home = data;
});
};
}
ngOnInit() {
this.supplierService.getAll().subscribe(data => {
this.supplier = data;
});
this.homeService.getAll().subscribe(data => {
this.home = data;
});
this.categoryService.getAll().subscribe(data => {
this.categories = data;
});
}
}
update product html
<!-- Table -->
<form [formGroup]="profileForm" (ngSubmit)="onSubmit()">
<p>
Form Status: {{profileForm.value |json}}
</p>
<div class="table-responsive">
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>Id</th>
<th>Product</th>
<th>Category</th>
<th>FullPrice <i id ="asc-desc1"class="fas fa-angle-down" (click)="SortPrice($event)"></i></th>
<th>Saleprice <i id ="asc-desc2"class="fas fa-angle-down" (click)="SortSale($event)"></i> </th>
<th>Availablity</th>
<th>Supplier</th>
<th>Discount<i id ="asc-desc3"class="fas fa-angle-down" (click)="SortDiscount($event)"></i></th>
<th>Edit</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let home of home | paginate:{itemsPerPage:20,currentPage: p} ; index as i">
<ng-container *ngIf="editMode !== i">
<td [attr.data-index]="i">{{home.id}}</td>
<td>{{home.productName}}</td>
<td>{{home.category.categoryName}}</td>
<td>{{home.fullPrice}}</td>
<td>{{home.salePrice}}</td>
<td>{{home.availability}}</td>
<td>{{home.supplier.supplierName}}</td>
<td>{{home.discount }}</td>
</ng-container>
<ng-container *ngIf="editMode === i">
<td><input class="form-control" id="id" formControlName="id" placeholder={{home.id}}></td>
<td><input class="form-control" id="name" formControlName="productName" placeholder={{home.productName}}> Value: {{ profileForm.productName.value }}</td>
<td><input class="form-control" id="categoryname" [formControl]="category" placeholder={{home.category.categoryName}}></td>
<td><input class="form-control" id="fullprice" [formControl]="fullPrice" placeholder={{home.fullPrice}}></td>
<td><input class="form-control" id="saleprice" [formControl]="salePrice" placeholder={{home.salePrice}}></td>
<td><input class="form-control" id="availability" [formControl]="availability" placeholder={{home.availability}}></td>
<td>
<select class="form-control">
<option *ngFor="let supplier of suppliers">{{supplier.supplierName}}</option>
</select>
</td>
<td><input class="form-control" id="discount" placeholder={{home.discount}}></td>
</ng-container>
<!-- if assigned index to editMode matches -->
<td class="text-right" id="tableDataBtns">
<div class="btn-group" role="group">
<button (click)="editMode === i ? editMode = null : editMode = i" data-toggle="modal" data-target="#updateProduct" type="button" class="btn btn-secondary">
<ng-container *ngIf="editMode === i"><i class="far fa-save"></i></ng-container>
<ng-container *ngIf="editMode !== i"><i class="far fa-edit"></i></ng-container>
</button>
<button type="button" data-toggle="modal" data-target="#deleteProduct" class="btn btn-danger"><i class="far fa-trash-alt"></i></button>
</div>
</td>
</tr>
<div>
<select >
<option *ngFor="let supplier of suppliers" [ngValue]="supplier">{{supplier.supplierName}}</option>
</select>
</div>
</tbody>
</table>
<pagination-controls class="myPagination" (pageChange)="p= $event"></pagination-controls>
</div>
</form>
You have in your HTML a mixup with formControlName and [formControl].
In your case, you have defined the [formGroup] in your code.
So keep using formControlName instead of [formControl]
Hi You are working with reactiveForms and you just need to change [formControl] to formControlName for every input field like below
<form [formGroup] >
Your input fields are here.
<input class="form-control" id="fullprice" formControlName="fullPrice" placeholder={{home.fullPrice}}></td>
</form>

Using ngx-pagination on reusable component

I am attempting to use ngx-pagination on a reusable datatable component, however the change in one table is effecting the change in other tables on the page. How can I assure pagination events are only occurring on one component at a time?
table.component.html
<table>
<thead>
<tr>
<th *ngFor="let col of cols">
<label>{{col.header}}</label>
</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let row of data | paginate: { itemsPerPage: 6,
currentPage: p }">`
<td *ngFor="let col of cols">
{{row[col.prop]}}
</td>
</tr>
</tbody>
</table>
<pagination-controls
class="my-pagination"
(pageChange)="p = $event">
</pagination-controls>
table.component.ts
#Component({
selector: 'app-data-table',
templateUrl: './data-table.component.html',
styleUrls: ['./data-table.component.css']
})
export class DataTableComponent {
#Input() data
#Input() cols
p: number = 1
}

i am coding ..todo task manger in Angular2.... having to update select option value ....in localStorage

Here is my problem regarding to-do task management.
I want to update an option value in select selector when the (change) event is triggered.
there are 2 Component
//app.component.ts
//array object
this.dataArr[this.counter] = {id: this.task_ID, name: this.t_name, msg: this.t_msg, date: this.task_date};
//console.log(this.counter);
console.log(this.dataArr[this.counter]);
//local storage
if (typeof(Storage) !== "undefined") {
localStorage.setItem("taskM", JSON.stringify(this.dataArr.reverse())); //put object array in reverse order to show latest object at top position
this.myObj = JSON.parse(localStorage.getItem("taskM"));
}
in this component I want to change and save select option value to localStorage
//task-form.component.ts.
import { Component, OnInit, Input, Output } from '#angular/core';
import { AppComponent } from './app.component';
#Component({
selector: 'task-data',
template: `<h3>List of Task</h3>
<div class="table-responsive">
<table class="table table-striped">
<thead>
<tr>
<th>Task Id</th>
<th>Task Title</th>
<th>Description</th>
<th>Date</th>
<th>Status</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let hero of taskMM">
<td> {{ hero.id }} </td>
<td> {{ hero.name }} </td>
<td> {{ hero.msg }} </td>
<td> {{ hero.date }} </td>
<td>
<select class="form-control">
<option *ngFor="let p of taskStatus"[value]="p"> {{p}}</option>
</select>
</td>
</tr>
</tbody>
</table>
</div>
`
})
export class TaskFormComponent {
taskStatus: string[];
taskMM: string[] = JSON.parse(localStorage.getItem("taskM"));
#Input('task-s') t_status: string;
#Input() data1: any= [];
onChange(deviceValue) {
console.log(deviceValue);
}
ngOnInit() {
console.log('this is ngOnInit ');
}
constructor() {
this.taskStatus = ['Started', 'Pending', 'Completed'];
}
}
<select (change)="onChange($event.target.value)" class="form-control">
<option *ngFor="let p of taskStatus"[value]="p"> {{p}}</option>
</select>
onChange($event) {
localStorage.setItem("taskM", $event);
}

Categories

Resources