capturing form inputs with Angular 8 reactive forms - javascript

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>

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

JSON-RPC service post request with response with Angular

I have a probleme. I will call JSON-RPC request. My Http post request on service.ts
service.ts
#Injectable({
providedIn: 'root'
})
export class Service {
public encoder: HttpParameterCodec;
public defaultHeaders = new HttpHeaders();
constructor(protected httpClient: HttpClient) {}
public createBriefing(
briefingData: Briefing //: Observable<any>
) {
const url = "";
let headers = new HttpHeaders();
headers.append("Content-Type", "application/json");
let body= new JsonRpcBody();
body.id = briefingData.id;
body.method = "query";
body.params = briefingData.params;
this.httpClient.post(url, JSON.stringify(body), { headers: headers })
.subscribe(response => console.log(response));
}
}
export class JsonRpcBody {
id:string;
method: string;
params: BriefingParameters[]
}
export class BriefingParameters {
id: string;
name: string[]
city: string[]
state: string[]
}
component.ts
Brifing: any = {
id: 'query01',
method: 'query',
"params": [
{
"id": "briefing01",
"name": ["FIRST", "LAST"],
"city":["LONDON", "ARSENAL"],
"state": ["ENGLAND"]
},
],
};
postBriefing(){
this.service.createBriefing(this.Brifing)
};
component.html
<form [formGroup]="guestForm" >
<table class="form-group" >
<tr>
<th> Query: </th>
<td ><input type="checkbox" formControlName="name" [(ngModel)]="Brifing.name" class="form-control" id="" formControlName="" > FIRST
<input type="checkbox" formControlName="name" [(ngModel)]="Brifing.name" class="form-control" id="" formControlName="" > LAST
</td>
</tr>
<tr>
<th> City</th>
<td ><input type="textarea" formControlName="city" [(ngModel)]="Brifing.city" class="form-control" id="" formControlName=""></td>
</tr>
<tr>
<th> State</th>
<td ><input type="textarea" formControlName="state" [(ngModel)]="Brifing.state" class="form-control" id="" formControlName=""></td></tr>
</table>
<button type="button" class="btn btn-primary" (click)="postBriefing()">Create Briefing</button>
<pre></pre>
</form>
<table>
<tr>
<th> </th>
<td> 3 rows </td>
</tr>
</table>
I want to sleep the data as
type, location, name in table.
The data is already displayed on the console, but if I write the name, adress,city in the table, the data does not appear.
what am I doing wrong?

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;
}
}

JavaScript plain CRUD edit function - update/ edit the input fields in the table

I need help by the implementation for a edit/update function. My goal is to edit/update the input fields from the customer. Thanks in advance! I tried to code the implementation into the function editFields(). Whenever the customer clicked the button "edit", he can edit/update the text fields from the table (please see picture).
HTML:
<!--CONTENT-->
<div class="content">
<!--CONTENT-PAGE-->
<div class="content__page">
<!--CAR-FORM-->
<div class="content__page__carForm">
<form id="car-form">
<label for="producer">Producer</label>
<input type="text" id="producer" class="form-controll">
<label for="model">Model</label>
<input type="text" id="model" class="form-controll">
<label for="color">Color</label>
<input type="text" id="color" class="form-controll">
<label for="price">Price</label>
<input type="text" id="price" class="form-controll">
<input type="submit" id="submit--button" value="Add Car" class="btn btn-primary btn-block">
</form>
<!--CAR-TABLE-->
<table class="table table-striped" id="car-table">
<thead>
<tr>
<th>Producer</th>
<th>Model</th>
<th>Color</th>
<th>Price</th>
</tr>
</thead>
</table>
</div>
</div>
</div>
JS:
class Car {
constructor(producer, model, color, price) {
this.producer = producer;
this.model = model;
this.color = color;
this.price = price;
}
}
class CarList {
static addCarToList(car) {
const list = document.getElementById('car-table');
const row = document.createElement('tr');
row.innerHTML = `
<td>${car.producer}</td>
<td>${car.model}</td>
<td>${car.color}</td>
<td>${car.price}</td>
<td>X</td>
<td>Edit</td>
`;
list.appendChild(row);
CarBase.addCar();
CarBase.removeCar();
}
static deleteCar(el) {
if (el.classList.contains('delete')) {
el.parentElement.parentElement.remove();
}
}
static clearFields() {
document.getElementById('producer').value = '';
document.getElementById('model').value = '';
document.getElementById('color').value = '';
document.getElementById('price').value = '';
}
static showAlert() {
}
static editFields() {
}
}
lass CarBase {
static addCar() {
document.getElementById('car-form').addEventListener('submit', (e) => {
e.preventDefault();
const producer = document.getElementById('producer').value;
const model = document.getElementById('model').value;
const color = document.getElementById('color').value;
const price = document.getElementById('price').value;
if (producer === '' || model === '' || color === '' || price === '') {
alert('Please fill out all fields');
} else {
const car = new Car(producer, model, color, price);
CarList.addCarToList(car);
CarList.clearFields();
}
});
}
static removeCar() {
document.getElementById('car-table').addEventListener('click', (e) => {
CarList.deleteCar(e.target);
CarList.showAlert();
});
}
}
const car1 = new Car('BMW', 'E63', 'Green', 15, 000);
CarList.addCarToList(car1);

Sort content on page Angular

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.

Categories

Resources